The core FrontMCP server — start with the minimum and scale up with HTTP, sessions, logging, providers, and authentication.
This page covers Server Mode (HTTP). For embedded SDK usage or serverless handlers, see Runtime Modes.
FrontMCP servers are defined with a single decorator, @FrontMcp({ ... }). This page shows the minimal config and then every top-level option you can use. Deep dives live in the pages listed under Servers.
FrontMCP can host many apps. Choose how they’re exposed:
Multi-App (default): splitByApp: false
One server scope. You may configure server-level auth and all apps inherit it (apps can still override with app-level auth).
Split-By-App: splitByApp: true
Each app is isolated under its own scope/base path (for example /billing). Streamable HTTP, the /message SSE endpoint, and OAuth issuers reuse that scope automatically. Server-level auth is disallowed; configure auth per app. (See Authentication → Overview.)
If you’re offering multiple products or tenants, splitByApp: true gives clean separation and per-app auth.
entryPath: your MCP JSON-RPC entry ('' or '/mcp'). Must align with discovery.
hostFactory: advanced — provide/construct a custom host implementation.
socketPath: listen on a Unix socket instead of a TCP port. The entire HTTP feature set (streamable HTTP, SSE, elicitation, sessions) works unchanged over Unix sockets.
Split-by-app scopes: when splitByApp is enabled, clients hit <entryPath>/<appId> (for example /mcp/billing) and subscribe via <entryPath>/<appId>/message; FrontMCP handles the prefixing.
Allowed origins; true reflects the request Origin header. Defaults to true only via the built-in DEFAULT_CORS when cors is omitted entirely.
credentials
boolean
false
Whether to allow credentials (cookies, authorization headers)
maxAge
number
—
How long (in seconds) browsers may cache preflight responses
The permissive default (origin: true, credentials: false) only applies when using the built-in Express adapter (i.e. no hostFactory). When a custom hostFactory is provided, the factory receives the full http config (including cors) but is responsible for applying CORS itself — FrontMCP does not install CORS middleware automatically.
An empty cors: {} object (without an origin key) will not enable CORS middleware — the adapter requires an explicit origin value. To enable permissive CORS, omit cors entirely or pass cors: { origin: true }.
FrontMCP automatically adds Mcp-Session-Id (alongside WWW-Authenticate) to the Access-Control-Expose-Headers response header when CORS is enabled. This ensures Streamable HTTP clients can read the session ID from cross-origin responses without additional configuration.
@FrontMcp({ http: { port: 3001 }, // cors is undefined → permissive CORS (origin: true, credentials: false)})
New in v0.6: Transport configuration has moved from auth.transport and session to a dedicated top-level transport property. This separates transport/session lifecycle concerns from authentication. See Migration below.
The transport config controls session lifecycle, protocol presets, and session persistence. Configure it at the server level or per-app when using splitByApp: true.
Enable streamable HTTP transport (POST with SSE response)
json
false
Enable JSON-only responses (stateful HTTP)
stateless
false
Enable stateless HTTP mode (no session required)
legacy
true
Enable legacy SSE transport for older clients
strictSession
true
Require session ID for streamable HTTP
Use protocol: 'legacy' (the default) for maximum backwards compatibility with older MCP clients. Use protocol: 'modern' when you only need to support newer Streamable HTTP clients.
Session persistence is automatically enabled when you configure top-level redis. Sessions are persisted to Redis/Vercel KV and transports can be recreated after server restart.
@FrontMcp({ redis: { host: 'redis.example.com', port: 6379, }, // persistence auto-enabled using global redis config})
To explicitly disable persistence when redis is configured:
Session persistence uses the top-level redis config. Configure redis once and it’s automatically shared by transport.persistence and auth.tokenStorage.
You can apply different transport policies per app when splitByApp: true. Sensitive apps stay stream-only with strict session IDs, while demo or health-check apps can enable stateful/stateless HTTP for easier automation.
Apps can also define their own auth (and mark themselves standalone) to expose an isolated auth surface — useful
when mixing public and private apps under one server.