Skip to main content

Basic Usage

Signature

Configuration Options

Required Properties

info is the serverInfo of every initialize response, title, websiteUrl and icons included; without a title, serverInfo.title is the name. Up to 1.9.2, serverInfo.title was always the name. The instructions below reach every transport’s initialize, createFetchHandler() and connect() included; up to 1.9.2 those two sent none.

Server Metadata

Server Configuration

With serve: true (the default), the decorated server starts when its module is imported. To serve over stdio instead — with no HTTP port bound — set FRONTMCP_STDIO=1 before the module loads; the decorator then connects the stdio transport rather than starting HTTP. The built --stdio runner and --target cli binaries set this flag for you. Set serve: false to opt out of auto-starting entirely (use FrontMcpInstance.bootstrap/runStdio explicitly).
http.hostFactory replaces the default Express host with a FrontMcpServer of your own, or a function that builds one from the HTTP options.

Storage Configuration

redis (and pubsub) also take a connection URL — redis: { url: process.env.REDIS_URL } — which is read into host/port/password/db (rediss:// sets tls). Fields beside the url only fill in what it leaves out; one that contradicts it is a validation error. See Redis Setup.

Transport Configuration

Shared Components

Prompts, agents, jobs, workflows, and channels are declared at the @App level — not at the gateway level. See the @App reference for the full list.

Server-level tools and resources

Tools, resources and resource templates declared on @FrontMcp are listed, called and read next to every app’s own, through the same flows: hooks of server-level plugins, hooks declared on the entry class, authorities, rate limits, availableWhen, and the startup checks apply to them as they do to app entries. They resolve the server-level providers, not an app’s.
  • Every scope serves them. With splitByApp: true, and for a standalone app, each app’s scope builds its own instance of every server-level tool and resource, as it does for server-level plugins and adapters.
  • Name conflicts. A server-level tool keeps its name unless an app in the same scope has a tool of that name. Then both are prefixed with their owner: <app id>:<name> for the app’s tool and server:<name> for the server’s. Call each by the name tools/list returns. For that reason no app may have the id server while @FrontMcp declares tools or resources; startup fails with ReservedAppIdError.
  • Plugins. An app’s plugin hooks run for a server-level tool only when declared with appliesTo: 'uncovered-apps'; server-level plugin hooks always run.
  • Progressive authorization. A server-level tool belongs to no app, so incrementalAuth does not ask for an app grant before it runs.
@FrontMcp does not accept prompts; declare them on an @App, or serve them from a server-level adapter or plugin.

Feature Configuration

Full Example

Skill catalog injection

The optional skillsConfig.injectInstructions field controls how the server’s auto-built skill catalog summary is merged into the instructions field on the MCP initialize response, and on the server/discover result for MCP 2026-07-28 clients (up to 1.9.2 server/discover sent the server’s instructions alone, without the channel hint or the catalog). The summary is generated by composeInitializeInstructions(...) and buildSkillsCatalogSummary(...) (exported from @frontmcp/sdk). It is bounded at 16 KB with a truncation footer. Its header and footer point clients at the SEP-2640 skill://index.json resource, which lists each skill’s SKILL.md URI. With skillsConfig.mcpResources: false no skill:// resource is served, so they point at the skills/load and skills/search methods instead. The composer is re-evaluated on every initialize request, so skills registered dynamically after server boot are picked up automatically. The catalog is composed for the client that initializes, like skills/list: it only names skills whose authorities that caller satisfies and that the hookable skills:filter flow keeps (a skill whose feature flag is off, for one). The SEP-2640 skill:// hints added under skillsConfig.sep2640InInstructions follow the same rule. When nothing gates a skill, the instructions are unchanged. The transports use composeCallerInstructions(scope, { ctx }), also exported from @frontmcp/sdk, for embedders that build their own initialize response.

Audit log

skillsConfig.audit enables a tamper-evident, hash-chained audit log of skill action executions (authority pass / authority fail / HTTP success / HTTP failure phases). Records are signed and chained so that any later mutation breaks verification. The audit module lives in @frontmcp/adapters/skills, which the SDK does not import: register it once at boot with setSkillAuditFactory(() => auditModule). See the skill audit log extensibility page for the full architecture, threat model, and chain verification recipe.
The writer is single-writer only: it serializes writes within one process, but two pods appending to the same store can link their records to the same tail, which verifyChain reports as a prevHash mismatch. Route audit writes to a single elected leader pod, or use per-pod chains and stitch them offline.

Bootstrap Methods

HTTP Server

Serverless Handler

Stdio Transport

Direct Client

@App

Define application modules

FrontMcpInstance

Server lifecycle management