Skip to main content
Providers are dependency-injected singletons (or scoped singletons) that your apps, tools, adapters, and plugins can use — e.g., config, DB pools, Redis clients, KMS, HTTP clients. They’re declared with @Provider() and registered at server or app scope. Resolution is hierarchical: tool → app → server.
Provider metadata, records, and DI helpers remain available through @frontmcp/sdk as type-only exports, so your existing @frontmcp/di imports keep working while bundlers drop unused types. Enums such as ProviderScope and ProviderKind still expose their runtime values, so you can configure scopes the same way you always have.
Nx users: Scaffold with nx g @frontmcp/nx:provider my-provider --project my-app. See Provider Generator.

Define a provider

Scopes

  • GLOBAL (default): one instance per process/worker. Ideal for clients, pools, caches.
  • CONTEXT: one instance per request. Use for per-request state, tracing, or user-specific data.
Legacy scopes SESSION and REQUEST are deprecated and automatically normalized to CONTEXT.

Register providers

Server-level providers (available to all apps):
App-level providers (override or add on top of server-level):
You can register class, value, or factory providers. Factories are useful for async initialization or composing other providers.

File Layout (folder per provider)

Once a provider grows past a single class — adds a spec, a helper, internal types, or config-loading logic — promote it from src/providers/<slug>.provider.ts to a folder per provider:
Plus a top-level src/providers/index.ts barrel:
Cross-provider imports go through the subfolder barrel — never reach into another provider’s implementation file:
Trivial providers (a Map-based cache, a pure DTO with no helpers) can stay flat. As soon as the provider has a spec, a helper, or internal types, fold it into its own directory.

Using providers from tools/plugins

FrontMCP resolves providers for your executors and hooks. Keep your tool logic pure; read side-effects (DB, queues, secrets) via providers.
  • Prefer GLOBAL for shared clients.
  • Use CONTEXT for request-scoped state or user-bound data.
Provider injection/consumption follows your runtime’s DI rules. In general: register providers at the minimal scope and let the framework resolve them for tools and hooks at execution time.

FrontMcpContext

Every HTTP request creates a FrontMcpContext that flows through the entire execution chain via AsyncLocalStorage. Access it via the FRONTMCP_CONTEXT token or the context getter.

In Tools/Resources/Prompts

In CONTEXT-Scoped Providers

CONTEXT-scoped providers can access the current context via factory injection:

FrontMcpContext API

Context-Aware Fetch

Use ctx.fetch() to automatically inject headers into outgoing requests:

Transport Access (Elicit)

Access the transport for interactive prompts:
See Request Context for the complete guide including distributed tracing and migration from legacy APIs.

CONTEXT-Scoped Providers

CONTEXT-scoped providers are created fresh for each request. They’re ideal for per-request state, user-specific data, or request-scoped caching.

Accessing Session ID

The session ID is available directly from the context:

Example: Context-Scoped Redis Provider

Multi-Pod Deployment Considerations

CONTEXT-scoped providers are per-request - each request builds its own provider instances. They are NOT shared across requests or pods.
When running behind a load balancer:
  • Each request builds its own provider instances
  • Transport state (MCP protocol) is shared via Redis (if configured)
  • For cross-pod session data, use Redis or another distributed store

Session Metadata

Access additional session metadata (protocol, platform type) via the context: