Skip to content

mcp-core API

Everything the package exports, by the path you import it from. Open an export for its signature and options.

@evolve-framework/mcp-core

The MCP server: tool, prompt and resource registration, the GraphQL client the tools call, the OAuth authorization server, JWT validation and token refresh.

Classes

GraphQLClientGraphQL client for communicating with the Evolve GraphQL Gateway.
import { GraphQLClient } from "@evolve-framework/mcp-core";

This client sends HTTP requests to the Apollo Gateway, which federates queries across all backend microservices (catalog, checkout, orders, etc.).

Usage:

const data = await graphqlClient.query(MyQuery, { id: "123" });
new GraphQLClient(config: GraphQLClientConfig)
OptionTypeDescription
gatewayEndpointstring
componentNamestring
componentVersion?string
persistedDocumentIdSeparator?string
Default: "~"

Joins component name, version and hash into a persisted document id.

More

Hive Router expects a tilde. A gateway that resolves the id as a CDN path (/apps/<name>/<version>/<hash>) needs a forward slash instead.

includeQueryWithDocumentId?boolean
Default: false

Send the raw query next to documentId on session requests.

More

Some gateways reject a payload carrying only a documentId. The gateway still resolves the persisted document; the query is ignored.

MethodDescription
buildDocumentId(hash: string): string | undefinedBuild a full document ID path for use with persisted documents.
query<TResult, TVariables>( document: DocumentTypeDecoration<TResult, TVariables>, variables: TVariables | undefined, options: GraphQLRequestContext, ): Promise<TResult>Execute a GraphQL query or mutation.
queryForSession<TResult>( query: string, variables: Record<string, unknown> | undefined, options: GraphQLRequestContext, documentId?: string, ): Promise<GraphQLResultWithSessionTokens & { data: TResult; }>Execute a GraphQL query/mutation and return response headers.
McpCodegenErrorThrown when codegen has not been run or generated files are missing.
import { McpCodegenError } from "@evolve-framework/mcp-core";

Extends McpError

new McpCodegenError(message: string, cause?: unknown)
MCPCoreConfigBase configuration class for MCP services.
import { MCPCoreConfig } from "@evolve-framework/mcp-core";

Extends BaseConfig

new MCPCoreConfig()
McpServerHigh-level MCP server that provides a simpler API for working with resources, tools, and prompts.
import { McpServer } from "@evolve-framework/mcp-core";
new McpServer(serverInfo: { version: string; name: string; websiteUrl?: string | undefined; description?: string | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?…, options?: McpServerOptions)
MethodDescription
toolInputSchemaJson(name: string): Record<string, unknown> | undefinedThe JSON-serialized inputSchema of a registered tool, or undefined when no such tool is registered.
connect(transport: Transport): Promise<void>Attaches to the given transport, starts it, and starts listening for messages.
close(): Promise<void>Closes the connection.
registerResource( name: string, uriOrTemplate: string, config: ResourceMetadata & { cacheHint?: CacheHint | undefined; scopeChallenge?: ScopeChallengeHandler | undefined; }, readCallback: ReadResourceCallback, ): RegisteredResourceRegisters a resource with a config object and callback.
registerTool<OutputArgs, InputArgs>( name: string, config: { title?: string | undefined; description?: string | undefined; inputSchema?: InputArgs | undefined; outputSchema?: OutputArgs | undefined; annotations?: { title?: string | undefined; readOnlyHint?: boolean | undefined; destructiveHint?: boolean | undefined; idempotentHint?: boolean | undefined; openWorldHint?: boolean | undefined; } | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; scopeChallenge?: ScopeChallengeHandler | undefined; _meta?: Record<string, unknown> | undefined; }, cb: BaseToolCallback<{ [x: string]: unknown; content: ({ type: "text"; text: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "image"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "audio"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; name: string; type: "resource_link"; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | { type: "resource"; resource: { uri: string; text: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; }; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; })[]; _meta?: { [x: string]: unknown; "io.modelcontextprotocol/serverInfo"?: { version: string; name: string; websiteUrl?: string | undefined; description?: string | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | undefined; } | undefined; structuredContent?: unknown; isError?: boolean | undefined; } | InputRequiredResult, ServerContext, InputArgs>, ): RegisteredToolRegisters a tool with a config object and callback.
registerPrompt( name: string, config: { title?: string | undefined; description?: string | undefined; argsSchema?: undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; scopeChallenge?: ScopeChallengeHandler | undefined; _meta?: Record<string, unknown> | undefined; }, cb: (ctx: ServerContext) => InputRequiredResult | { [x: string]: unknown; messages: { role: "user" | "assistant"; content: { type: "text"; text: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "image"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "audio"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; name: string; type: "resource_link"; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | { type: "resource"; resource: { uri: string; text: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; }; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; }; }[]; _meta?: { [x: string]: unknown; "io.modelcontextprotocol/serverInfo"?: { version: string; name: string; websiteUrl?: string | undefined; description?: string | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | undefined; } | undefined; description?: string | undefined; } | Promise<InputRequiredResult | { [x: string]: unknown; messages: { role: "user" | "assistant"; content: { type: "text"; text: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "image"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { type: "audio"; data: string; mimeType: string; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; name: string; type: "resource_link"; description?: string | undefined; mimeType?: string | undefined; size?: number | undefined; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | { type: "resource"; resource: { uri: string; text: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; } | { uri: string; blob: string; mimeType?: string | undefined; _meta?: { [x: string]: unknown; } | undefined; }; annotations?: { audience?: ("user" | "assistant")[] | undefined; priority?: number | undefined; lastModified?: string | undefined; } | undefined; _meta?: { [x: string]: unknown; } | undefined; }; }[]; _meta?: { [x: string]: unknown; "io.modelcontextprotocol/serverInfo"?: { version: string; name: string; websiteUrl?: string | undefined; description?: string | undefined; icons?: { src: string; mimeType?: string | undefined; sizes?: string[] | undefined; theme?: "light" | "dark" | undefined; }[] | undefined; title?: string | undefined; } | undefined; } | undefined; description?: string | undefined; }>, ): RegisteredPromptRegisters a prompt with a config object and callback.
isConnected(): booleanChecks if the server is connected to a transport.
sendLoggingMessage( params: { level: "error" | "debug" | "info" | "notice" | "warning" | "critical" | "alert" | "emergency"; data: unknown; _meta?: { [x: string]: unknown; progressToken?: string | number | undefined; "io.modelcontextprotocol/related-task"?: { taskId: string; } | undefined; } | undefined; logger?: string | undefined; }, sessionId?: string, ): Promise<void>Sends a logging message to the client, if connected.
sendResourceListChanged(): voidSends a resource list changed event to the client, if connected.
sendToolListChanged(): voidSends a tool list changed event to the client, if connected.
sendPromptListChanged(): voidSends a prompt list changed event to the client, if connected.

Functions

createGuestSessionFactoryCreates a guest session factory function.
import { createGuestSessionFactory } from "@evolve-framework/mcp-core";
function createGuestSessionFactory(
graphqlClient: GraphQLClient,
tokenConfig: TokenValidationConfig,
documentHash?: string,
options?: GuestSessionOptions,
): (storeContext: StoreContext) => Promise<SessionAuthContext>
OptionTypeDescription
jwtIssuerstring | string[]
jwtAudiencestring | string[]
tokenRefreshThresholdSecondsnumber
mutation?string

Mutation that opens a guest session.

More

Only the tokens on the response headers are read, so the response shape does not matter. Supply your own when your schema names the operation differently. If the operation is marked @mcpTool(exclude: true), its query string is available from the codegen output's excludedOperationQueries, keyed by operation name.

Returns (storeContext: StoreContext) => Promise<SessionAuthContext>

createHealthcheckHandler
import { createHealthcheckHandler } from "@evolve-framework/mcp-core";
function createHealthcheckHandler(componentName: string): RouteHandler

Returns RouteHandler

createMcpRouteHandlersCreates MCP route handlers with the given server factory.
import { createMcpRouteHandlers } from "@evolve-framework/mcp-core";
function createMcpRouteHandlers(
options: McpRouteHandlerOptions,
): {
postHandler: RouteHandler;
/**
* The optional server-to-client SSE stream. Every reply is a JSON body, so
* there is nothing to stream, and a long-lived stream behind a buffering
* ingress stalls until an idle timeout and blocks the client.
*/
getHandler: RouteHandler;
/** Session termination. There are no sessions to terminate. */
deleteHandler: RouteHandler;
}
OptionTypeDescription
createServerCreateServerWithContext

Factory that creates a new MCP Server instance per request.

clientIdstring

Client identifier used for requests through these handlers.

storeDefaults?StoreContext

Fallbacks for store context headers. When omitted, all three X-StoreContext-* headers are required and a request missing any of them is rejected with 400. Any other X-StoreContext-* header is kept for the request, on top of headers.

jwtValidation?JwtValidationConfig

Pre-validates a bearer JWT. Ignored when oauth is given, where a bearer token has to be one this service issued.

proxyAuthEnabled?boolean
Default: false

Accept a pre-authenticated session forwarded by a trusted proxy through X-Access-Token / X-Data-Token / X-Refresh-Token. Takes precedence over a bearer token.

oauth?OAuthResourceServer

Requires every request to carry an access token issued by this service.

Returns { postHandler: RouteHandler; /** * The optional server-to-client SSE stream. Every reply is a JSON body, so * there is nothing to stream, and a long-lived stream behind a buffering * ingress stalls until an idle timeout and blocks the client. */ getHandler: RouteHandler; /** Session termination. There are no sessions to terminate. */ deleteHandler: RouteHandler; }

createMcpServerFactoryCreates the createServer that registerMcpRoutes and startStdioServer take: a server exposing the generated tools, with guest sessions and token refresh wired to the gateway.
import { createMcpServerFactory } from "@evolve-framework/mcp-core";
function createMcpServerFactory(
options: McpServiceOptions,
): CreateServerWithContext
OptionTypeDescription
configMCPCoreConfig

The service's configuration, already loaded when the factory runs.

namestring

The MCP server name, shown to clients.

loadTools() => Promise<GeneratedTools>

Imports the generated tools, for example () => import("#generated/…").

version?string
Default: "1.0.0"

The server version.

plugins?MCPPlugin[]
contextArguments?((tools: GeneratedTools) => ToolContextArgument[])

Arguments that select the context a tool runs in.

Returns CreateServerWithContext

createRateLimitOptionsCreates rate limit plugin options for Fastify.
import { createRateLimitOptions } from "@evolve-framework/mcp-core";
function createRateLimitOptions(
config?: RateLimitOptions,
grantOf?: GrantOf,
): RateLimitPluginOptions
OptionTypeDescription
max?number
Default: 100

Maximum number of requests per time window.

addressMax?number
Default: 1000

With OAuth, max is per connected client and this is the maximum per IP address, for requests without a valid token. It is higher because clients in the cloud, such as Claude, share their addresses.

timeWindowSeconds?number
Default: 60 (1 minute)

Time window in seconds.

allowList?string[] | ((req: FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger…

Keys or a predicate that are exempt from rate limiting. Use this for infrastructure probes or internal callers that must never be throttled. An array is matched against the generated key.

keyGenerator?((req: FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFa…

Overrides how a request is bucketed. The default keys on the connection with OAuth, and otherwise on request.ip, which behind a proxy needs trustProxy on the application to be the client's address.

store?FastifyRateLimitStoreCtor

Custom store implementation for the request counters. The default store is in-process, so counters are per-instance and reset when the process restarts — provide a shared store to limit across instances.

More

Takes precedence over redis when both are set.

redis?any

Redis client used to share counters across instances.

More

Silently ignored when store is also set, as a custom store wins — pass only one of the two.

Returns RateLimitPluginOptions

createSessionLoggerCreates a child logger with session context (clientId and sessionId).
import { createSessionLogger } from "@evolve-framework/mcp-core";

This branches off the root logger rather than the context-aware one: a session logger outlives the request that opened the session and is reused for every later request on it, so binding the opening request's trace id and path into it would label all subsequent traffic with the wrong trace.

function createSessionLogger(
context: { clientId: string; sessionId: string; },
): Logger$1
OptionTypeDescription
clientIdstring
sessionIdstring

Returns Logger$1

createTokenRefresherCreates the token refresher helpers used by the tool execution flow: - ensureRefreshTokens proactively refreshes tokens if they are near expiry (best-effort: returns the original context if refresh fails).
import { createTokenRefresher } from "@evolve-framework/mcp-core";
function createTokenRefresher(
graphqlClient: GraphQLClient,
tokenConfig: TokenValidationConfig,
documentHash?: string,
options?: TokenRefresherOptions,
): {
ensureRefreshTokens: EnsureRefreshTokens;
refreshSessionTokens: RefreshSessionTokens;
}
OptionTypeDescription
jwtIssuerstring | string[]
jwtAudiencestring | string[]
tokenRefreshThresholdSecondsnumber
mutation?string

Mutation that renews the session tokens.

More

If the operation is marked @mcpTool(exclude: true), its query string is available from the codegen output's excludedOperationQueries, keyed by operation name.

isRefreshSuccessful?((data: unknown) => boolean)

Reads success out of the mutation response. Response shapes differ across schemas, so a consumer whose mutation does not return { success } must supply this.

Returns { ensureRefreshTokens: EnsureRefreshTokens; refreshSessionTokens: RefreshSessionTokens; }

createToolFromGeneratedCreates an executable MCP tool from a generated tool definition.
import { createToolFromGenerated } from "@evolve-framework/mcp-core";

The handler executes the GraphQL query/mutation using the queryString and passes the arguments as variables. Blank string arguments are stripped via stripBlankStrings before they reach the gateway.

function createToolFromGenerated(generated: GeneratedMCPTool): ExecutableMCPTool
OptionTypeDescription
namestring
descriptionstring
inputSchema{ type: "object"; properties: Record<string, unknown>; required?: string[] | undefined; }
documentIdstring
queryStringstring
requiredScopes?string[]
businessUnit?"REQUIRED" | "NONE"

From @mcpTool(businessUnit:). Left out, a call may name a company.

Returns ExecutableMCPTool

endToolInvocation
import { endToolInvocation } from "@evolve-framework/mcp-core";
function endToolInvocation(
timer: ToolInvocationTimer,
success: boolean,
errorType?: string,
): void
OptionTypeDescription
toolNamestring
startTimenumber

Returns void

getToolDurationHistogram
import { getToolDurationHistogram } from "@evolve-framework/mcp-core";
function getToolDurationHistogram(): Histogram<Attributes>

Returns Histogram

getToolInvocationsCounter
import { getToolInvocationsCounter } from "@evolve-framework/mcp-core";
function getToolInvocationsCounter(): Counter<Attributes>

Returns Counter

oauthFromConfigThe authorization server for a service's configuration, or undefined while MCP_OAUTH_SECRETS is unset, which leaves OAuth off.
import { oauthFromConfig } from "@evolve-framework/mcp-core";
function oauthFromConfig(
config: MCPCoreConfig,
options: OAuthFromConfigOptions,
): OAuthServerOptions | undefined
OptionTypeDescription
scopesstring[]

The scopes this service offers.

resourceName?string

The display name of this resource in its metadata.

accessTokenTtlSeconds?number
Default: 900

Access token lifetime.

refreshTokenTtlSeconds?number
Default: 2592000 (30 days)

Refresh token lifetime.

authorizationCodeTtlSeconds?number
Default: 60

Authorization code lifetime.

replayStore?OAuthReplayStore

Enforces single use across instances. When given, a used refresh token is refused as well, which is what makes rotation mean anything.

clients?OAuthClient[]

Clients known ahead of time, next to metadata documents.

allowClient?((client: OAuthClient) => boolean | Promise<boolean>)
Default: every client with a valid registration

Decides whether a client may connect.

refreshSession?((session: SealedSession) => Promise<SealedSession | null>)

Renews a session through the gateway, or returns null when it ended.

reapplySession?((session: SealedSession) => Promise<SealedSession>)

Restores what a refresh reset, such as the customer's selection.

revokeSession?((session: SealedSession) => Promise<void>)

Ends a session through the gateway, for token revocation.

generated?GeneratedTools

Returns OAuthServerOptions | undefined

preValidateJwtPre-validates a JWT token for use with the MCP server.
import { preValidateJwt } from "@evolve-framework/mcp-core";

Why Pre-validation?

This function provides defense in depth by validating tokens before they are forwarded to the GraphQL Gateway. Benefits include:

  1. Fail Fast: Invalid tokens are rejected immediately at the MCP layer, providing faster feedback to clients and reducing unnecessary Gateway calls.

  2. Better Error Messages: Specific validation errors (expired, wrong issuer, etc.) can be returned to clients instead of generic authentication failures.

  3. Reduced Load: Obviously invalid tokens never reach the Gateway, reducing load on downstream services.

  4. Security Logging: Token validation failures can be logged at the edge for security monitoring.

Important Notes

  • This does NOT verify the token signature. Signature verification requires access to the signing keys and is performed by the GraphQL Gateway.
  • This validates claims (iss, aud, exp) against configured values.
  • The Gateway remains the authoritative source for authentication decisions.
function preValidateJwt(
token: string,
config: JwtValidationConfig,
): JwtValidationResult
OptionTypeDescription
jwtIssuerstring | string[]
jwtAudiencestring | string[]

Returns JwtValidationResult

recordToolInvocation
import { recordToolInvocation } from "@evolve-framework/mcp-core";
function recordToolInvocation(
toolName: string,
durationMs: number,
success: boolean,
errorType?: string,
): void

Returns void

registerMcpRateLimitRegisters the rate limiter with MCP-aware defaults on a Fastify instance.
import { registerMcpRateLimit } from "@evolve-framework/mcp-core";

For a service that registers its own MCP routes — several endpoints in one process, for instance. Register it inside an encapsulated scope if the instance also carries routes that must not be throttled.

function registerMcpRateLimit(
app: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>,
options?: RateLimitOptions,
): void
OptionTypeDescription
max?number
Default: 100

Maximum number of requests per time window.

addressMax?number
Default: 1000

With OAuth, max is per connected client and this is the maximum per IP address, for requests without a valid token. It is higher because clients in the cloud, such as Claude, share their addresses.

timeWindowSeconds?number
Default: 60 (1 minute)

Time window in seconds.

allowList?string[] | ((req: FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger…

Keys or a predicate that are exempt from rate limiting. Use this for infrastructure probes or internal callers that must never be throttled. An array is matched against the generated key.

keyGenerator?((req: FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFa…

Overrides how a request is bucketed. The default keys on the connection with OAuth, and otherwise on request.ip, which behind a proxy needs trustProxy on the application to be the client's address.

store?FastifyRateLimitStoreCtor

Custom store implementation for the request counters. The default store is in-process, so counters are per-instance and reset when the process restarts — provide a shared store to limit across instances.

More

Takes precedence over redis when both are set.

redis?any

Redis client used to share counters across instances.

More

Silently ignored when store is also set, as a custom store wins — pass only one of the two.

Returns void

registerMcpRoutes
import { registerMcpRoutes } from "@evolve-framework/mcp-core";
function registerMcpRoutes(
app: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>,
options: CreateAppOptions,
): void
OptionTypeDescription
createServerCreateServerWithContext

Factory function that creates a new MCP Server instance.

clientIdstring

Client identifier used for sessions created by this MCP service.

mcpEndpointPath?string
Default: "/mcp"

The endpoint path for MCP requests.

storeDefaults?StoreContext

Fallbacks for store context headers. When omitted, all three X-StoreContext-* headers are required on every request.

jwtValidation?JwtValidationConfig

JWT validation configuration for pre-validating tokens. If not provided, JWT pre-validation is skipped.

proxyAuthEnabled?boolean

Enable trusted-proxy auth via X-Access-Token / X-Data-Token / X-Refresh-Token headers (takes precedence over Authorization: Bearer).

oauth?OAuthServerOptions

Serves an OAuth 2.1 authorization server next to the MCP endpoint and requires its tokens on every request. Takes the place of jwtValidation.

rateLimit?RateLimitOptions

Rate limiting configuration for the MCP routes.

More

Rate limiting is opt-in: the limiter is only registered when this option is provided. Pass an empty object to accept the defaults (100 requests per 60 seconds), or omit it to run without a limiter.

healthcheck?boolean

Serves GET /healthcheck. Turn it off next to something that already does, such as a GraphQL server in the same application. Defaults to true.

Returns void

registerPromptsRegisters all MCP prompts on the server.
import { registerPrompts } from "@evolve-framework/mcp-core";

Prompts are templated messages that MCP clients can use to provide context or instructions to AI assistants.

function registerPrompts(
mcp: McpServer,
graphqlClient: GraphQLClient,
prompts?: MCPPrompt[],
): void

Returns void

registerResourcesRegisters all MCP resources on the server.
import { registerResources } from "@evolve-framework/mcp-core";

Resources are read-only data sources that MCP clients can fetch. Each resource executes a GraphQL query to retrieve data.

function registerResources(
mcp: McpServer,
graphqlClient: GraphQLClient,
resources?: MCPResource[],
): void

Returns void

registerToolsRegisters all MCP tools on the server with authentication and plugin support.
import { registerTools } from "@evolve-framework/mcp-core";
function registerTools(options: RegisterToolsOptions): void
OptionTypeDescription
mcpMcpServer
toolsExecutableMCPTool[]
graphqlClientGraphQLClient
getSessionContextGetSessionContext
setSessionAuthSetSessionAuth
pluginsMCPPlugin[]
ensureRefreshTokensEnsureRefreshTokens
refreshSessionTokensRefreshSessionTokens
createGuestSessionCreateGuestSession
contextArguments?ToolContextArgument[]

Arguments that select the context a tool runs in, added to its schema.

Returns void

startStdioServerStarts the MCP Server with stdio transport.
import { startStdioServer } from "@evolve-framework/mcp-core";

The server communicates via stdin/stdout, making it compatible with MCP clients like Claude Desktop.

function startStdioServer(config: StdioTransportConfig): Promise<void>
OptionTypeDescription
clientIdstring
storeDefaultsStoreContext
createMCPServer(clientId: string, getSessionContext: () => SessionContext, setSessionAuth: SetSessionAuth, setSessionStoreContext: SetSessionStoreContext) => Promise<McpServer…

Returns Promise<void>

startToolInvocation
import { startToolInvocation } from "@evolve-framework/mcp-core";
function startToolInvocation(toolName: string): ToolInvocationTimer

Returns ToolInvocationTimer

Constants

loggerThe logger to be used by all applications.
import { logger } from "@evolve-framework/mcp-core";
const logger: Logger

Types

AuthChallengeWhat ends an HTTP request instead of its tool result, so the client can authorize: 401 to renew its token, 403 to ask for the scopes in scope.
import { type AuthChallenge } from "@evolve-framework/mcp-core";
export type AuthChallenge = {
status: 401 | 403;
scope?: string[];
description?: string;
};
CreateServerWithContextFactory function type for creating MCP servers with request context callbacks.
import { type CreateServerWithContext } from "@evolve-framework/mcp-core";
export type CreateServerWithContext = (clientId: string, getSessionContext: GetSessionContext, setSessionAuth: SetSessionAuth, setSessionStoreContext: SetSessionStoreContext) => Promise<McpServer>;
ExecutableMCPToolExecutable MCP tool with a handler function.
import { type ExecutableMCPTool } from "@evolve-framework/mcp-core";

Tools are actions that MCP clients can execute. Each tool can perform GraphQL mutations or queries against the Evolve GraphQL Gateway.

export type ExecutableMCPTool = MCPToolBase & {
requiredScopes?: string[];
handler: (client: GraphQLClient, args: Record<string, unknown>, context: SessionContext) => Promise<unknown>;
};
GeneratedMCPToolGenerated MCP tool definition (data-only, serializable).
import { type GeneratedMCPTool } from "@evolve-framework/mcp-core";

This type represents tool metadata extracted from GraphQL operations marked with

export type GeneratedMCPTool = MCPToolBase & {
documentId: string;
queryString: string;
requiredScopes?: string[];
businessUnit?: "REQUIRED" | "NONE";
};
GeneratedToolsWhat codegen/tools writes to mcp-tools.generated.ts.
import { type GeneratedTools } from "@evolve-framework/mcp-core";
export type GeneratedTools = {
generatedMcpTools: GeneratedMCPTool[];
persistedDocumentIds?: Record<string, string>;
excludedOperationQueries?: Record<string, string>;
};
GetSessionContextCallback to retrieve the context of the current request or process.
import { type GetSessionContext } from "@evolve-framework/mcp-core";
export type GetSessionContext = () => SessionContext | undefined;
InitialSessionContextThe context of one HTTP request.
import { type InitialSessionContext } from "@evolve-framework/mcp-core";

Store fields are resolved by the route handler before this point, from headers first and configured defaults second.

export type InitialSessionContext = StoreContext & {
auth?: SessionAuthContext;
scopes?: ReadonlySet<string>;
};
JwtValidationErrorStructured JWT validation error
import { type JwtValidationError } from "@evolve-framework/mcp-core";
export type JwtValidationError = {
code: JwtValidationErrorCode;
message: string;
};
JwtValidationErrorCodeError codes for JWT validation failures
import { type JwtValidationErrorCode } from "@evolve-framework/mcp-core";
export type JwtValidationErrorCode = "MALFORMED_TOKEN" | "INVALID_STRUCTURE" | "DECODE_FAILED" | "TOKEN_EXPIRED" | "INVALID_ISSUER" | "INVALID_AUDIENCE" | "MISSING_CLAIMS";
JwtValidationResultResult of JWT pre-validation
import { type JwtValidationResult } from "@evolve-framework/mcp-core";
export type JwtValidationResult = {
valid: true;
payload: JWTPayload;
} | {
valid: false;
error: JwtValidationError;
};
MCPPluginMCP Plugin interface.
import { type MCPPlugin } from "@evolve-framework/mcp-core";

Plugins can intercept tool calls and add custom behavior. They are registered when creating an MCP service and are applied in order of registration.

export interface MCPPlugin {
name: string;
version: string;
interceptTools?: string[];
handleTool?: (toolName: string, args: Record<string, unknown>, context: SessionContext, setSessionAuth: SetSessionAuth) => Promise<ToolHandlerResult | undefined>;
}
MCPPromptMCP Prompt definition.
import { type MCPPrompt } from "@evolve-framework/mcp-core";

Prompts are templated messages that MCP clients can use to provide context or instructions to AI assistants.

export type MCPPrompt = {
name: string;
description: string;
arguments?: Array<{
name: string;
description: string;
required?: boolean;
}>;
handler: (client: GraphQLClient, args: Record<string, unknown>) => Promise<PromptMessage[]>;
};
MCPResourceMCP Resource definition.
import { type MCPResource } from "@evolve-framework/mcp-core";

Resources are read-only data sources that MCP clients can fetch. Each resource executes a GraphQL query to retrieve data from the Evolve GraphQL Gateway.

export type MCPResource = {
uri: string;
name: string;
description: string;
mimeType: string;
handler: (client: GraphQLClient) => Promise<unknown>;
};
OAuthClientA client as the authorization server knows it.
import { type OAuthClient } from "@evolve-framework/mcp-core";
export type OAuthClient = {
clientId: string;
name: string;
redirectUris: string[];
host?: string;
};
OAuthReplayStoreRemembers what may only happen once.
import { type OAuthReplayStore } from "@evolve-framework/mcp-core";
export type OAuthReplayStore = {
consumeOnce: (key: string, ttlSeconds: number) => Promise<boolean>;
};
OAuthServerOptionsConfiguration of the authorization server and the MCP resource.
import { type OAuthServerOptions } from "@evolve-framework/mcp-core";
export type OAuthServerOptions = OAuthSecretOptions & {
resource: string;
loginUrl: string;
interactionSecret: string;
scopes: string[];
resourceName?: string;
accessTokenTtlSeconds?: number;
refreshTokenTtlSeconds?: number;
authorizationCodeTtlSeconds?: number;
replayStore?: OAuthReplayStore;
clients?: OAuthClient[];
allowClient?: (client: OAuthClient) => boolean | Promise<boolean>;
refreshSession: (session: SealedSession) => Promise<SealedSession | null>;
reapplySession?: (session: SealedSession) => Promise<SealedSession>;
revokeSession: (session: SealedSession) => Promise<void>;
};
PluginContextPlugin context provided to plugins during lifecycle events.
import { type PluginContext } from "@evolve-framework/mcp-core";
export interface PluginContext {
sessionId: string;
clientId: string;
auth?: SessionAuthContext;
}
RegisterMcpRoutesOptions
import { type RegisterMcpRoutesOptions } from "@evolve-framework/mcp-core";
export type RegisterMcpRoutesOptions = CreateAppOptions;
SealedSessionA gateway session, sealed into the tokens a client holds.
import { type SealedSession } from "@evolve-framework/mcp-core";
export type SealedSession = {
accessToken: string;
dataToken?: string;
refreshToken?: string;
isAuthenticated: boolean;
store: StoreSelection;
selection?: Record<string, string>;
};
SessionAuthContextAuthentication context for a request.
import { type SessionAuthContext } from "@evolve-framework/mcp-core";
export type SessionAuthContext = {
accessToken: string;
refreshToken: string;
dataToken?: string;
createdAt: number;
expiresAt?: number;
isAuthenticated: boolean;
};
SessionContextEverything a tool call runs with.
import { type SessionContext } from "@evolve-framework/mcp-core";
export type SessionContext = {
sessionId: string;
clientId: string;
logger: Logger;
auth?: SessionAuthContext;
storeKey: string;
locale: string;
currency: string;
headers?: Record<string, string>;
scopes?: ReadonlySet<string>;
challenge?: (challenge: AuthChallenge) => void;
};
SetSessionAuthCallback to update the authentication state of the current context, which is one request over HTTP and the process over stdio.
import { type SetSessionAuth } from "@evolve-framework/mcp-core";
export type SetSessionAuth = (auth: SessionAuthContext | null) => void;
SetSessionStoreContextCallback to change the store context, for example from a tool that switches store or storefront variant.
import { type SetSessionStoreContext } from "@evolve-framework/mcp-core";
export type SetSessionStoreContext = (update: Partial<StoreContext>) => void;
StoreContextStore scoping for a GraphQL request.
import { type StoreContext } from "@evolve-framework/mcp-core";

Structurally identical to the framework's own store context, declared here so mcp-core carries no runtime dependency on the framework package.

export type StoreContext = {
storeKey: string;
locale: string;
currency: string;
headers?: Record<string, string>;
};
StoreContextDefaultsStore context defaults.
import { type StoreContextDefaults } from "@evolve-framework/mcp-core";

Structurally identical to StoreContext — this alias exists so transport-facing options can keep their established name.

export type StoreContextDefaults = StoreContext;
StoreSelectionThe store a session was created in.
import { type StoreSelection } from "@evolve-framework/mcp-core";
export type StoreSelection = Pick<StoreContext, "storeKey" | "locale" | "currency">;
ToolContextArgumentAn argument that selects the context a tool runs in rather than reaching the GraphQL operation, such as a business unit.
import { type ToolContextArgument } from "@evolve-framework/mcp-core";
export type ToolContextArgument = {
name: string;
description: string;
requiredForTools?: string[];
exceptTools?: string[];
apply: (value: string, context: SessionContext, client: GraphQLClient) => Promise<SessionContext>;
read: (context: SessionContext) => string | undefined;
};
ToolHandlerResultResult returned by a tool handler.
import { type ToolHandlerResult } from "@evolve-framework/mcp-core";
export type ToolHandlerResult = {
success: boolean;
message?: string;
error?: string;
data?: unknown;
};
ToolInvocationTimer
import { type ToolInvocationTimer } from "@evolve-framework/mcp-core";
export type ToolInvocationTimer = {
toolName: string;
startTime: number;
};

@evolve-framework/mcp-core/codegen

The codegen plugins and transforms that generate tools from operations, plus persisted-document validation.

Functions

createMcpToolTransformDocument transform that filters operations to only include those marked with the
import { createMcpToolTransform } from "@evolve-framework/mcp-core/codegen";
function createMcpToolTransform(
options?: McpToolTransformOptions,
): Types.DocumentTransformObject
OptionTypeDescription
stripDirectives?boolean
Default: false

Strip

Returns Types.DocumentTransformObject

createPersistedDocumentsTerraformHookCreates a codegen hook that copies persisted documents to Terraform cloud folders.
import { createPersistedDocumentsTerraformHook } from "@evolve-framework/mcp-core/codegen";

Each copied operation is sanitized by stripping

function createPersistedDocumentsTerraformHook(
options?: PersistedDocumentsTerraformHookOptions,
): () => void
OptionTypeDescription
cwd?string
Default: process.cwd()

Directory from which paths are resolved.

sourcePath?string
Default: "generated/persisted-documents.json"

Source persisted-documents file path, relative to cwd.

clouds?string[]
Default: ["aws", "gcp", "azure"]

Target cloud folder names under terraform/.

Returns () => void

runPersistedDocumentsValidationCLI runner - validates terraform persisted documents and exits with code 1 on errors.
import { runPersistedDocumentsValidation } from "@evolve-framework/mcp-core/codegen";
function runPersistedDocumentsValidation(
options: ValidatePersistedDocumentsOptions,
): void
OptionTypeDescription
schemaPathstring

Path to GraphQL schema file (supergraph SDL), relative to cwd.

clouds?string[]

Cloud folder names under terraform/.

cwd?string

Base directory for resolving relative paths (defaults to process.cwd()).

Returns void

toolsPluginGraphQL Codegen plugin that generates MCP tool definitions from persisted documents.
import { toolsPlugin } from "@evolve-framework/mcp-core/codegen";

This plugin reads the persisted-documents.json file generated by the client-preset and extracts tool definitions from operations marked with

function toolsPlugin(
schema: GraphQLSchema,
documents: DocumentFile[],
config: MCPToolConfig,
info?: { [key: string]: any; outputFile?: string | undefined; allPlugins?: ConfiguredPlugin[] | undefined; pluginContext?: { [key: string]: any; } | undefined; },
): Types.Promisable<TOutput>
OptionTypeDescription
persistedDocumentsPath?string
Default: "./generated/persisted-documents.json"

Path to the persisted-documents.json file (relative to codegen.ts).

outputFile?string
allPlugins?ConfiguredPlugin[]
pluginContext?{ [key: string]: any; }

Returns Types.Promisable<TOutput>

validatePersistedDocumentsValidates terraform persisted documents against a schema SDL.
import { validatePersistedDocuments } from "@evolve-framework/mcp-core/codegen";
function validatePersistedDocuments(
options: ValidatePersistedDocumentsOptions,
): PersistedDocumentsValidationResult
OptionTypeDescription
schemaPathstring

Path to GraphQL schema file (supergraph SDL), relative to cwd.

clouds?string[]

Cloud folder names under terraform/.

cwd?string

Base directory for resolving relative paths (defaults to process.cwd()).

Returns PersistedDocumentsValidationResult

Constants

mcpToolTransform
import { mcpToolTransform } from "@evolve-framework/mcp-core/codegen";
const mcpToolTransform: DocumentTransformObject<object>

Types

PersistedDocumentsValidationError
import { type PersistedDocumentsValidationError } from "@evolve-framework/mcp-core/codegen";
export type PersistedDocumentsValidationError = {
cloud: string;
hash: string;
message: string;
line?: number;
column?: number;
};
PersistedDocumentsValidationResult
import { type PersistedDocumentsValidationResult } from "@evolve-framework/mcp-core/codegen";
export type PersistedDocumentsValidationResult = {
success: boolean;
errors: PersistedDocumentsValidationError[];
operationCount: number;
checkedClouds: number;
};

@evolve-framework/mcp-core/codegen/tools

The codegen plugin that generates the tool definitions.

Functions

pluginGraphQL Codegen plugin that generates MCP tool definitions from persisted documents.
import { plugin } from "@evolve-framework/mcp-core/codegen/tools";

This plugin reads the persisted-documents.json file generated by the client-preset and extracts tool definitions from operations marked with

function plugin(
schema: GraphQLSchema,
documents: DocumentFile[],
config: MCPToolConfig,
info?: { [key: string]: any; outputFile?: string | undefined; allPlugins?: ConfiguredPlugin[] | undefined; pluginContext?: { [key: string]: any; } | undefined; },
): Types.Promisable<TOutput>
OptionTypeDescription
persistedDocumentsPath?string
Default: "./generated/persisted-documents.json"

Path to the persisted-documents.json file (relative to codegen.ts).

outputFile?string
allPlugins?ConfiguredPlugin[]
pluginContext?{ [key: string]: any; }

Returns Types.Promisable<TOutput>

stripMcpDirectivesStrip
import { stripMcpDirectives } from "@evolve-framework/mcp-core/codegen/tools";
function stripMcpDirectives(query: string): string

Returns string

@evolve-framework/mcp-core/codegen/persisted-queries

The persisted-documents transform that keeps the tool operations registered with the gateway.

Functions

createMcpToolTransformDocument transform that filters operations to only include those marked with the
import { createMcpToolTransform } from "@evolve-framework/mcp-core/codegen/persisted-queries";
function createMcpToolTransform(
options?: McpToolTransformOptions,
): Types.DocumentTransformObject
OptionTypeDescription
stripDirectives?boolean
Default: false

Strip

Returns Types.DocumentTransformObject

Constants

mcpToolTransform
import { mcpToolTransform } from "@evolve-framework/mcp-core/codegen/persisted-queries";
const mcpToolTransform: DocumentTransformObject<object>

@evolve-framework/mcp-core/codegen/validate-persisted-documents

A check that every tool's operation is registered with the gateway.

Functions

runPersistedDocumentsValidationCLI runner - validates terraform persisted documents and exits with code 1 on errors.
import { runPersistedDocumentsValidation } from "@evolve-framework/mcp-core/codegen/validate-persisted-documents";
function runPersistedDocumentsValidation(
options: ValidatePersistedDocumentsOptions,
): void
OptionTypeDescription
schemaPathstring

Path to GraphQL schema file (supergraph SDL), relative to cwd.

clouds?string[]

Cloud folder names under terraform/.

cwd?string

Base directory for resolving relative paths (defaults to process.cwd()).

Returns void

validatePersistedDocumentsValidates terraform persisted documents against a schema SDL.
import { validatePersistedDocuments } from "@evolve-framework/mcp-core/codegen/validate-persisted-documents";
function validatePersistedDocuments(
options: ValidatePersistedDocumentsOptions,
): PersistedDocumentsValidationResult
OptionTypeDescription
schemaPathstring

Path to GraphQL schema file (supergraph SDL), relative to cwd.

clouds?string[]

Cloud folder names under terraform/.

cwd?string

Base directory for resolving relative paths (defaults to process.cwd()).

Returns PersistedDocumentsValidationResult

Types

PersistedDocumentsValidationError
import { type PersistedDocumentsValidationError } from "@evolve-framework/mcp-core/codegen/validate-persisted-documents";
export type PersistedDocumentsValidationError = {
cloud: string;
hash: string;
message: string;
line?: number;
column?: number;
};
PersistedDocumentsValidationResult
import { type PersistedDocumentsValidationResult } from "@evolve-framework/mcp-core/codegen/validate-persisted-documents";
export type PersistedDocumentsValidationResult = {
success: boolean;
errors: PersistedDocumentsValidationError[];
operationCount: number;
checkedClouds: number;
};

@evolve-framework/mcp-core/plugins

The plugin interface for adding tools, prompts and resources.

Types

MCPPluginMCP Plugin interface.
import { type MCPPlugin } from "@evolve-framework/mcp-core/plugins";

Plugins can intercept tool calls and add custom behavior. They are registered when creating an MCP service and are applied in order of registration.

export interface MCPPlugin {
name: string;
version: string;
interceptTools?: string[];
handleTool?: (toolName: string, args: Record<string, unknown>, context: SessionContext, setSessionAuth: SetSessionAuth) => Promise<ToolHandlerResult | undefined>;
}
PluginContextPlugin context provided to plugins during lifecycle events.
import { type PluginContext } from "@evolve-framework/mcp-core/plugins";
export interface PluginContext {
sessionId: string;
clientId: string;
auth?: SessionAuthContext;
}

@evolve-framework/mcp-core/application

createMcpModule, a service as an application module with OAuth when given oauth, and startMcpStdio, the same service over stdio. createMcpHttpDomainService is deprecated.

Functions

createMcpModuleCreates the MCP routes, the healthcheck and OAuth as an application module, from the service's configuration, which must be loaded by then.
import { createMcpModule } from "@evolve-framework/mcp-core/application";
function createMcpModule(
options: McpModuleOptions,
): Promise<McpModule>
OptionTypeDescription
configMCPCoreConfig

The service's configuration, already loaded when the factory runs.

namestring

The MCP server name, shown to clients.

loadTools() => Promise<GeneratedTools>

Imports the generated tools, for example () => import("#generated/…").

version?string
Default: "1.0.0"

The server version.

plugins?MCPPlugin[]
contextArguments?((tools: GeneratedTools) => ToolContextArgument[])

Arguments that select the context a tool runs in.

oauth?McpOAuthOptions
rateLimit?RateLimitOptions

On top of the configuration, such as redis to count across instances.

healthcheck?boolean

Serves GET /healthcheck. Turn it off when the application already does, as one with a GraphQL server. Defaults to true.

Returns Promise<McpModule>

startMcpStdioServes a service over stdin and stdout, for a client that spawns the process.
import { startMcpStdio } from "@evolve-framework/mcp-core/application";
function startMcpStdio(service: McpServiceOptions): Promise<void>
OptionTypeDescription
configMCPCoreConfig

The service's configuration, already loaded when the factory runs.

namestring

The MCP server name, shown to clients.

loadTools() => Promise<GeneratedTools>

Imports the generated tools, for example () => import("#generated/…").

version?string
Default: "1.0.0"

The server version.

plugins?MCPPlugin[]
contextArguments?((tools: GeneratedTools) => ToolContextArgument[])

Arguments that select the context a tool runs in.

Returns Promise<void>

Types

CreateMcpHttpDomainServiceConfig
import { type CreateMcpHttpDomainServiceConfig } from "@evolve-framework/mcp-core/application";
export type HttpDomainServiceConfig = {
name: string;
host: string;
port: number;
mcpEndpointPath?: string;
storeDefaults: StoreContextDefaults;
jwtValidation?: JwtValidationConfig;
proxyAuthEnabled?: boolean;
rateLimit?: RegisterMcpRoutesOptions["rateLimit"];
createServer: CreateServerWithContext;
onStart?: ApplicationOptions["onStart"];
onShutdown?: ApplicationOptions["onShutdown"];
};
McpOAuthOptionsWhat a service decides about OAuth.
import { type McpOAuthOptions } from "@evolve-framework/mcp-core/application";
export type McpOAuthOptions = Omit<OAuthFromConfigOptions, "generated" | "scopes">;

Deprecated

Still exported so existing code keeps working. Each one says what replaces it.

createMcpHttpDomainServiceCreates an HTTP domain service for the MCP module.
import { createMcpHttpDomainService } from "@evolve-framework/mcp-core/application";
function createMcpHttpDomainService(
config: HttpDomainServiceConfig,
): Promise<Application>
OptionTypeDescription
namestring

A unique name for the domain service, used for logging and identification purposes.

hoststring

Host to bind the HTTP server to.

portnumber

Port to bind the HTTP server to.

storeDefaultsStoreContext

Default store context values.

createServerCreateServerWithContext

Factory function that creates a new MCP Server instance. This will be called for each incoming request to create a server with the appropriate context.

mcpEndpointPath?string
Default: "/mcp"

The endpoint path for MCP requests.

jwtValidation?JwtValidationConfig

JWT validation configuration for pre-validating tokens. If provided, tokens will be validated before session creation.

proxyAuthEnabled?boolean

Enable trusted-proxy auth via X-Access-Token / X-Data-Token / X-Refresh-Token headers (takes precedence over Authorization: Bearer).

rateLimit?RateLimitOptions

Rate limiting configuration for incoming requests. If not provided, defaults will be applied (e.g., 100 requests per minute).

onStart?(() => void | Promise<void>)

Sets up what the servers share, such as the cache connection, in start() before the service listens; as onStart on an Application.

onShutdown?(() => void | Promise<void>)

Releases what onStart acquired when the process shuts down.

Returns Promise<Application>

Not listed: 14 options types. They appear as the tables under the constructors and functions they type.