Skip to main content
FrontMCP includes a built-in dependency injection system. Define services with @Provider, inject them into tools, resources, prompts, and agents with this.get().

Defining Providers

Create a provider with a token and scope:
import { Provider } from '@frontmcp/sdk';

export const CONFIG_TOKEN = Symbol('Config');

@Provider({
  token: CONFIG_TOKEN,
  scope: 'singleton',
})
export class ConfigProvider {
  readonly apiKey = process.env.API_KEY!;
  readonly baseUrl = process.env.BASE_URL!;

  static factory() {
    return new ConfigProvider();
  }
}

Provider Scopes

ScopeLifetimeUse Case
singletonOne instance per serverConfiguration, database connections
requestOne instance per MCP requestRequest-scoped caches, loggers
contextOne instance per execution contextPer-tool state

Injecting Providers

Use this.get() or this.tryGet() inside any context class:
@Tool({
  name: 'fetch-data',
  inputSchema: { url: z.string() },
})
class FetchDataTool extends ToolContext {
  async execute({ url }: { url: string }) {
    const config = this.get(CONFIG_TOKEN);    // Throws if not found
    const cache = this.tryGet(CACHE_TOKEN);   // Returns undefined if not found

    const response = await this.fetch(url, {
      headers: { Authorization: `Bearer ${config.apiKey}` },
    });

    return response.json();
  }
}

Registering Providers

Register providers at the server or app level:
// Server-level — available to all apps
@FrontMcp({
  info: { name: 'Server', version: '1.0.0' },
  apps: [MyApp],
  providers: [ConfigProvider, DatabaseProvider],
})
class Server {}

// App-level — available only within this app
@App({
  id: 'crm',
  name: 'CRM',
  tools: [CreateLeadTool],
  providers: [CrmServiceProvider],
})
class CrmApp {}
Server-level providers are shared across all apps. App-level providers are isolated to their app.

Learn More

Providers Guide

Full guide to defining, scoping, and composing providers

@Provider Reference

Complete decorator API reference