Skip to content

Interface: AttachOptions<TContext>

Defined in: packages/core/src/server/ServerAttachment.ts:71

Options for attaching to an MCP Server

Type Parameters

Type Parameter
TContext

Properties

actionSeparator?

ts
optional actionSeparator: string;

Defined in: packages/core/src/server/ServerAttachment.ts:242

Delimiter for deterministic naming interpolation in flat mode. Used to join {toolName}{separator}{actionKey}.

Default

ts
'_'

Example

typescript
// '_' → projects_list, projects_create
// '.' → projects.list, projects.create
// '-' → projects-list, projects-create

contextFactory()?

ts
optional contextFactory: (extra) => TContext | Promise<TContext>;

Defined in: packages/core/src/server/ServerAttachment.ts:80

Factory function to create a per-request context. Receives the MCP extra object (session info, meta, etc.). If omitted, undefined is used as context (suitable for ToolRegistry<void>). Supports async factories (e.g. for token verification, DB connection).

Parameters

ParameterType
extraunknown

Returns

TContext | Promise<TContext>


debug?

ts
optional debug: DebugObserverFn;

Defined in: packages/core/src/server/ServerAttachment.ts:97

Enable debug observability for ALL registered tools.

When set, the observer is automatically propagated to every tool builder, and registry-level routing events are also emitted.

Example

typescript
registry.attachToServer(server, {
    contextFactory: createContext,
    debug: createDebugObserver(),
});

See

createDebugObserver for creating an observer


filter?

ts
optional filter: {
  anyTag?: string[];
  exclude?: string[];
  tags?: string[];
};

Defined in: packages/core/src/server/ServerAttachment.ts:73

Only expose tools matching these tag filters

anyTag?

ts
optional anyTag: string[];

exclude?

ts
optional exclude: string[];

tags?

ts
optional tags: string[];

fsm?

ts
optional fsm: StateMachineGate;

Defined in: packages/core/src/server/ServerAttachment.ts:353

FSM gate for temporal anti-hallucination.

When configured, tools bound to FSM states (via .bindState()) are dynamically filtered from tools/list based on the current workflow state. The LLM physically cannot call tools that don't exist in its reality.

On successful tool execution, the FSM transitions automatically (if a transition event is bound), and notifications/tools/list_changed is emitted so the client re-fetches the tool list.

Zero overhead when omitted — no FSM code runs.

Example

typescript
const gate = new StateMachineGate({
    id: 'checkout',
    initial: 'empty',
    states: {
        empty:     { on: { ADD_ITEM: 'has_items' } },
        has_items: { on: { CHECKOUT: 'payment' } },
        payment:   { on: { PAY: 'confirmed' } },
        confirmed: { type: 'final' },
    },
});

registry.attachToServer(server, {
    contextFactory: createContext,
    fsm: gate,
});

See

StateMachineGate for the FSM engine


fsmStore?

ts
optional fsmStore: FsmStateStore;

Defined in: packages/core/src/server/ServerAttachment.ts:380

External state store for FSM persistence in serverless/edge deployments.

When MCP runs over Streamable HTTP (Vercel, Cloudflare Workers), there is no persistent process — FSM state must be externalized. The sessionId comes from the Mcp-Session-Id request header.

Zero overhead when omitted — FSM state lives in-memory.

Example

typescript
registry.attachToServer(server, {
    fsm: gate,
    fsmStore: {
        load: async (sessionId) => {
            const data = await redis.get(`fsm:${sessionId}`);
            return data ? JSON.parse(data) : undefined;
        },
        save: async (sessionId, snapshot) => {
            await redis.set(`fsm:${sessionId}`, JSON.stringify(snapshot), { EX: 3600 });
        },
    },
});

introspection?

ts
optional introspection: IntrospectionConfig<TContext>;

Defined in: packages/core/src/server/ServerAttachment.ts:158

Enable dynamic introspection manifest (MCP Resource).

When enabled, the framework registers a resources/list and resources/read handler exposing a structured manifest of all registered tools, actions, and presenters.

Security: Opt-in only. Never enabled silently. RBAC: The filter callback allows dynamic per-session manifest filtering. Unauthorized agents never see hidden tools.

Example

typescript
registry.attachToServer(server, {
    contextFactory: createContext,
    introspection: {
        enabled: process.env.NODE_ENV !== 'production',
        uri: 'fusion://manifest.json',
        filter: (manifest, ctx) => {
            if (ctx.user.role !== 'admin') {
                delete manifest.capabilities.tools['admin.delete_user'];
            }
            return manifest;
        },
    },
});

See

IntrospectionConfig for configuration options


prompts?

ts
optional prompts: PromptRegistry<TContext>;

Defined in: packages/core/src/server/ServerAttachment.ts:269

Prompt registry for server-side hydrated prompts.

When provided, the framework registers prompts/list and prompts/get handlers on the MCP server, enabling slash command discovery and Zero-Shot Context hydration.

Zero overhead when omitted — no prompt code runs.

Example

typescript
const promptRegistry = new PromptRegistry<AppContext>();
promptRegistry.register(AuditPrompt);

registry.attachToServer(server, {
    contextFactory: createContext,
    prompts: promptRegistry,
});

See


selfHealing?

ts
optional selfHealing: SelfHealingConfig;

Defined in: packages/core/src/server/ServerAttachment.ts:314

Enable contract-aware self-healing for validation errors.

When configured, Zod validation errors are enriched with contract change context, helping the LLM self-correct when the tool's behavioral contract has changed.

Zero overhead when omitted or when no contract deltas exist.

See

SelfHealingConfig for configuration options


serverName?

ts
optional serverName: string;

Defined in: packages/core/src/server/ServerAttachment.ts:200

Server name used in the introspection manifest.

Default Value

'mcp-fusion-server'


stateSync?

ts
optional stateSync: StateSyncConfig;

Defined in: packages/core/src/server/ServerAttachment.ts:126

Enable State Sync to prevent LLM Temporal Blindness and Causal State Drift.

When configured, Fusion automatically:

  1. Appends [Cache-Control: X] to tool descriptions during tools/list
  2. Prepends [System: Cache invalidated...] after successful mutations in tools/call

Zero overhead when omitted — no state-sync code runs.

Example

typescript
registry.attachToServer(server, {
    contextFactory: createContext,
    stateSync: {
        defaults: { cacheControl: 'no-store' },
        policies: [
            { match: 'sprints.update', invalidates: ['sprints.*'] },
            { match: 'tasks.update',   invalidates: ['tasks.*', 'sprints.*'] },
            { match: 'countries.*',     cacheControl: 'immutable' },
        ],
    },
});

See


telemetry?

ts
optional telemetry: TelemetrySink;

Defined in: packages/core/src/server/ServerAttachment.ts:194

Telemetry sink for the Inspector TUI.

When set, emits route, execute, and error events for each tool call, enabling the real-time TUI dashboard.

Zero overhead when omitted.


toolExposition?

ts
optional toolExposition: ToolExposition;

Defined in: packages/core/src/server/ServerAttachment.ts:227

Exposition strategy for projecting grouped tools onto the MCP wire format.

  • 'flat' (default): Each action becomes an independent atomic MCP tool. Guarantees privilege isolation, deterministic routing, and granular UI. Example: projects_list, projects_create — two separate buttons in Claude.

  • 'grouped': All actions within a builder are merged into a single MCP tool with a discriminated-union schema (legacy behavior).

Default

ts
'flat'

Example

typescript
registry.attachToServer(server, {
    contextFactory: createContext,
    toolExposition: 'flat',      // Each action = 1 MCP tool
    actionSeparator: '_',        // projects_list, projects_create
});

See

ToolExposition for strategy details


tracing?

ts
optional tracing: FusionTracer;

Defined in: packages/core/src/server/ServerAttachment.ts:184

Enable OpenTelemetry-compatible tracing for ALL registered tools.

When set, the tracer is automatically propagated to every tool builder, and registry-level routing spans are also created.

Context propagation limitation: Since MCP Fusion does not depend on @opentelemetry/api, it cannot call context.with(trace.setSpan(...)). Auto-instrumented downstream calls (Prisma, HTTP, Redis) inside tool handlers will appear as siblings, not children, of the MCP span. This is an intentional trade-off for zero runtime dependencies.

Example

typescript
import { trace } from '@opentelemetry/api';

registry.attachToServer(server, {
    contextFactory: createContext,
    tracing: trace.getTracer('mcp-fusion'),
});

See

FusionTracer for the tracer interface contract


zeroTrust?

ts
optional zeroTrust: ZeroTrustConfig;

Defined in: packages/core/src/server/ServerAttachment.ts:299

Enable Zero-Trust runtime verification for behavioral contracts.

When configured, the framework:

  1. Materializes ToolContracts from all registered builders
  2. Computes a server-level behavioral digest
  3. Optionally verifies against a known-good digest (capability pinning)
  4. Exposes the trust capability via MCP server metadata

Zero overhead when omitted — no cryptographic operations run.

Example

typescript
registry.attachToServer(server, {
    contextFactory: createContext,
    zeroTrust: {
        signer: 'hmac',
        secret: process.env.FUSION_SIGNING_SECRET,
        expectedDigest: process.env.FUSION_EXPECTED_DIGEST,
        failOnMismatch: process.env.NODE_ENV === 'production',
    },
});

See

ZeroTrustConfig for configuration options