@openagentid/mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/server.ts"],"names":[],"mappings":"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","file":"server.cjs","sourcesContent":["/**\n * Error types for @openagentid/mcp.\n *\n * These map onto MCP JSON-RPC error codes so callers see consistent\n * failure modes regardless of which middleware step rejected the call.\n *\n * Reference: https://www.jsonrpc.org/specification#error_object\n */\n\n/** Standard JSON-RPC + MCP error codes used by the middleware. */\nexport const McpErrorCode = {\n /** -32600 — request was malformed at the JSON-RPC layer. */\n InvalidRequest: -32600,\n /** -32601 — the requested method/tool was not found. */\n MethodNotFound: -32601,\n /** -32602 — params failed validation. */\n InvalidParams: -32602,\n /** -32603 — internal server error. */\n InternalError: -32603,\n /** -32000 — generic server error (used for auth failures by default). */\n ServerError: -32000,\n /** -32001 — identity verification failed. */\n AuthenticationFailed: -32001,\n /** -32002 — caller does not hold the required scope. */\n AuthorizationDenied: -32002,\n /** -32003 — skills policy rejected the call. */\n SkillsPolicyDenied: -32003,\n} as const;\n\nexport type McpErrorCodeValue =\n (typeof McpErrorCode)[keyof typeof McpErrorCode];\n\n/**\n * Base class for all middleware errors. Subclasses set a default\n * {@link OpenAgentMcpError.code} that maps to a JSON-RPC error code.\n */\nexport class OpenAgentMcpError extends Error {\n public readonly code: McpErrorCodeValue;\n public readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: McpErrorCodeValue,\n data?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'OpenAgentMcpError';\n this.code = code;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Convert to a plain JSON-RPC error payload that the MCP SDK can\n * serialize over the wire.\n */\n toJsonRpcError(): {\n code: McpErrorCodeValue;\n message: string;\n data?: Record<string, unknown>;\n } {\n if (this.data !== undefined) {\n return { code: this.code, message: this.message, data: this.data };\n }\n return { code: this.code, message: this.message };\n }\n}\n\n/** Caller did not present an OpenAgent identity envelope. */\nexport class MissingIdentityError extends OpenAgentMcpError {\n constructor(toolName: string) {\n super(\n `Tool '${toolName}' requires an OpenAgent identity in _meta.openagent.identity`,\n McpErrorCode.AuthenticationFailed,\n { toolName },\n );\n this.name = 'MissingIdentityError';\n }\n}\n\n/** Identity envelope was present but the verifier rejected it. */\nexport class IdentityVerificationError extends OpenAgentMcpError {\n constructor(toolName: string, cause: unknown) {\n super(\n `Identity verification failed for tool '${toolName}': ${formatCause(cause)}`,\n McpErrorCode.AuthenticationFailed,\n { toolName, cause: formatCause(cause) },\n );\n this.name = 'IdentityVerificationError';\n }\n}\n\n/** Caller's verified identity does not hold the required scopes. */\nexport class AuthorizationDeniedError extends OpenAgentMcpError {\n constructor(\n toolName: string,\n requiredScopes: ReadonlyArray<string>,\n heldScopes: ReadonlyArray<string>,\n ) {\n super(\n `Tool '${toolName}' requires scopes [${requiredScopes.join(', ')}], caller holds [${heldScopes.join(', ')}]`,\n McpErrorCode.AuthorizationDenied,\n {\n toolName,\n requiredScopes: [...requiredScopes],\n heldScopes: [...heldScopes],\n },\n );\n this.name = 'AuthorizationDeniedError';\n }\n}\n\n/** Skills policy hook returned `allow: false`. */\nexport class SkillsPolicyDeniedError extends OpenAgentMcpError {\n constructor(toolName: string, reason: string | undefined) {\n super(\n `Skills policy denied tool '${toolName}'${reason ? `: ${reason}` : ''}`,\n McpErrorCode.SkillsPolicyDenied,\n reason !== undefined ? { toolName, reason } : { toolName },\n );\n this.name = 'SkillsPolicyDeniedError';\n }\n}\n\nfunction formatCause(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n return 'unknown error';\n}\n","/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * The real `@openagentid/sdk` exports types that are structurally compatible\n * with these — there is no runtime dependency.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The verifier interface — implemented by `@openagentid/sdk` (production) and\n * by the in-memory test agent shipped here.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Agent;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n","/**\n * Server-side middleware for @openagentid/mcp.\n *\n * Wraps an MCP {@link McpServer} (from `@modelcontextprotocol/sdk`) so that\n * every tool registration runs through an OpenAgent authentication\n * pipeline:\n *\n * 1. Extract the identity envelope from `extra._meta.openagent.identity`.\n * 2. Verify it via the configured {@link IdentityVerifier} and check\n * that the caller holds the scopes returned by `requireScopes`.\n * 3. Run the optional skills policy hook.\n * 4. Run the optional pre-call hook.\n * 5. Invoke the user's tool callback.\n * 6. Run the optional post-call hook with the result + duration.\n * 7. Stamp `audit_id` + `verified_did` into the result `_meta.openagent`.\n * 8. On error, run the optional onError hook and re-throw.\n *\n * Implementation note — version pinning:\n * The middleware is built against `@modelcontextprotocol/sdk@^1.27.0`.\n * The TypeScript SDK changed its tool registration API between 1.17 and\n * 1.27 (`tool(name, cb, ...)` → `registerTool(name, config, cb)`); both\n * call sites are intercepted here so any 1.x server still works.\n *\n * We deliberately do NOT touch the private `_registeredTools` map. The\n * middleware uses a JavaScript {@link Proxy} so callbacks are wrapped\n * exactly once at registration time, before the SDK's internal\n * request handler ever sees them.\n */\n\nimport {\n AuthorizationDeniedError,\n IdentityVerificationError,\n MissingIdentityError,\n OpenAgentMcpError,\n SkillsPolicyDeniedError,\n} from './errors.js';\nimport {\n Agent,\n AuditedResultMeta,\n ErrorHook,\n OpenAgentMcpConfig,\n OpenAgentRequestIdentity,\n PostCallHook,\n PreCallHook,\n ScopeDeriver,\n SkillsPolicyHook,\n VerifiedIdentity,\n defaultRequireScopes,\n} from './types.js';\n\n/**\n * Minimal McpServer surface used by the middleware. We avoid importing\n * concrete types from `@modelcontextprotocol/sdk` because peer-dep\n * versions vary across host applications and the SDK's own type exports\n * are subject to change. The shape below is the intersection of every\n * `1.x` McpServer release.\n */\nexport interface McpServerLike {\n tool(...args: unknown[]): unknown;\n registerTool(...args: unknown[]): unknown;\n}\n\n/**\n * Names of methods on the underlying server that take a tool callback as\n * one of their arguments. Both APIs are intercepted; if the SDK adds new\n * registration methods, append to this list.\n */\nconst TOOL_REGISTRATION_METHODS = ['tool', 'registerTool'] as const;\n\ntype ToolRegistrationMethod = (typeof TOOL_REGISTRATION_METHODS)[number];\n\n/**\n * Wrap an MCP server so every tool call is authenticated against an\n * OpenAgent identity.\n *\n * @example\n * ```ts\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { withOpenAgent } from '@openagentid/mcp';\n * import { agent } from './my-agent.js';\n *\n * const server = new McpServer({ name: 'my-tools', version: '0.1.0' });\n * const authedServer = withOpenAgent(server, { agent });\n *\n * authedServer.tool('search_web', searchHandler);\n * ```\n *\n * The returned proxy is type-compatible with the underlying server, so\n * existing code that calls `tool()`, `registerTool()`, `connect()`, etc.\n * keeps working without changes.\n */\nexport function withOpenAgent<T extends McpServerLike>(\n server: T,\n config: OpenAgentMcpConfig,\n): T {\n validateConfig(config);\n const middleware = new ToolMiddleware(config);\n\n return new Proxy(server, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n if (\n typeof property === 'string' &&\n TOOL_REGISTRATION_METHODS.includes(property as ToolRegistrationMethod)\n ) {\n return wrapRegistrationMethod(\n value as (...args: unknown[]) => unknown,\n target,\n middleware,\n );\n }\n // Bind methods so `this` stays correct when destructured.\n return value.bind(target);\n },\n }) as T;\n}\n\nfunction validateConfig(config: OpenAgentMcpConfig): void {\n if (config === null || typeof config !== 'object') {\n throw new TypeError('OpenAgentMcpConfig must be an object');\n }\n if (config.agent === undefined || config.agent === null) {\n throw new TypeError('OpenAgentMcpConfig.agent is required');\n }\n if (\n config.agent.verifier === undefined ||\n typeof config.agent.verifier.verify !== 'function'\n ) {\n throw new TypeError('OpenAgentMcpConfig.agent.verifier.verify is required');\n }\n}\n\n/**\n * Wrap a single registration method so the user-supplied callback gets\n * replaced by an auth-wrapped one. The MCP SDK accepts the callback in\n * different positional slots depending on overload — we walk the args\n * list and replace the FIRST function we find. This is the same approach\n * the SDK itself uses internally.\n */\nfunction wrapRegistrationMethod(\n original: (...args: unknown[]) => unknown,\n thisArg: unknown,\n middleware: ToolMiddleware,\n): (...args: unknown[]) => unknown {\n return function wrapped(this: unknown, ...args: unknown[]): unknown {\n const toolName = extractToolName(args);\n const callbackIndex = findCallbackIndex(args);\n if (callbackIndex === -1) {\n // No callback in the args — defensive: forward as-is so we don't\n // mask SDK-level errors that the host would otherwise see.\n return original.apply(thisArg, args);\n }\n const userCallback = args[callbackIndex] as (\n ...callbackArgs: unknown[]\n ) => unknown;\n const wrappedCallback = middleware.wrap(toolName, userCallback);\n const newArgs = [...args];\n newArgs[callbackIndex] = wrappedCallback;\n return original.apply(thisArg, newArgs);\n };\n}\n\nfunction extractToolName(args: ReadonlyArray<unknown>): string {\n if (args.length > 0 && typeof args[0] === 'string') {\n return args[0];\n }\n // registerTool's first arg is also a string in 1.27, so this should\n // never trigger — kept as a safety net.\n return '<unknown>';\n}\n\nfunction findCallbackIndex(args: ReadonlyArray<unknown>): number {\n // Walk the args from the end so we find the LAST function — that's\n // the tool body in every overload of both `tool()` and\n // `registerTool()`.\n for (let i = args.length - 1; i >= 0; i -= 1) {\n if (typeof args[i] === 'function') {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Holds the middleware configuration and wraps individual tool callbacks.\n */\nclass ToolMiddleware {\n private readonly agent: Agent;\n private readonly requireScopes: ScopeDeriver;\n private readonly requireIdentity: boolean;\n private readonly skillsPolicy: SkillsPolicyHook | undefined;\n private readonly preCall: PreCallHook | undefined;\n private readonly postCall: PostCallHook | undefined;\n private readonly onError: ErrorHook | undefined;\n\n constructor(config: OpenAgentMcpConfig) {\n this.agent = config.agent;\n this.requireScopes = config.requireScopes ?? defaultRequireScopes;\n this.requireIdentity = config.requireIdentity ?? true;\n this.skillsPolicy = config.skillsPolicy;\n this.preCall = config.preCall;\n this.postCall = config.postCall;\n this.onError = config.onError;\n }\n\n wrap(\n toolName: string,\n userCallback: (...args: unknown[]) => unknown,\n ): (...args: unknown[]) => Promise<unknown> {\n const middleware = this;\n return async function wrappedCallback(\n this: unknown,\n ...callbackArgs: unknown[]\n ): Promise<unknown> {\n // The MCP SDK invokes tool callbacks in two shapes depending on\n // whether the tool has an input schema:\n // (extra) — no schema\n // (args, extra) — with schema\n // The `extra` is always the LAST arg.\n const { args, extra } = splitToolArgs(callbackArgs);\n const startedAt = nowMs();\n let identity: VerifiedIdentity | null = null;\n\n try {\n identity = await middleware.runAuthPipeline(toolName, args, extra);\n\n if (middleware.preCall !== undefined) {\n await middleware.preCall({ toolName, args, identity });\n }\n\n const result = await Promise.resolve(\n userCallback.apply(this, callbackArgs),\n );\n\n const stamped = stampAuditMeta(result, identity);\n\n if (middleware.postCall !== undefined) {\n await middleware.postCall({\n toolName,\n args,\n identity,\n durationMs: nowMs() - startedAt,\n result: stamped,\n });\n }\n return stamped;\n } catch (error: unknown) {\n if (middleware.onError !== undefined) {\n // The error hook MUST NOT throw — if it does, swallow so the\n // original error propagates to the caller intact.\n try {\n await middleware.onError({ toolName, args, identity, error });\n } catch {\n /* intentionally ignored */\n }\n }\n throw normalizeError(error);\n }\n };\n }\n\n private async runAuthPipeline(\n toolName: string,\n args: unknown,\n extra: unknown,\n ): Promise<VerifiedIdentity> {\n const identityEnvelope = extractIdentityEnvelope(extra);\n if (identityEnvelope === null) {\n if (this.requireIdentity) {\n throw new MissingIdentityError(toolName);\n }\n // Permissive mode: synthesize an \"anonymous\" identity so hooks\n // still run with a stable shape.\n return ANONYMOUS_IDENTITY;\n }\n\n const requiredScopes = this.requireScopes(toolName, args);\n let identity: VerifiedIdentity;\n try {\n identity = await this.agent.verifier.verify(\n identityEnvelope,\n requiredScopes,\n );\n } catch (cause: unknown) {\n throw new IdentityVerificationError(toolName, cause);\n }\n\n enforceScopes(toolName, requiredScopes, identity.scopes);\n\n if (this.skillsPolicy !== undefined) {\n const decision = await Promise.resolve(\n this.skillsPolicy({ toolName, args, identity }),\n );\n if (!decision.allow) {\n throw new SkillsPolicyDeniedError(toolName, decision.reason);\n }\n }\n\n return identity;\n }\n}\n\nfunction enforceScopes(\n toolName: string,\n required: ReadonlyArray<string>,\n held: ReadonlyArray<string>,\n): void {\n const missing = required.filter((scope) => !held.includes(scope));\n if (missing.length > 0) {\n throw new AuthorizationDeniedError(toolName, required, held);\n }\n}\n\nfunction splitToolArgs(callbackArgs: ReadonlyArray<unknown>): {\n args: unknown;\n extra: unknown;\n} {\n if (callbackArgs.length === 0) {\n return { args: undefined, extra: undefined };\n }\n if (callbackArgs.length === 1) {\n // Single argument is the `extra` object.\n return { args: undefined, extra: callbackArgs[0] };\n }\n return {\n args: callbackArgs[0],\n extra: callbackArgs[callbackArgs.length - 1],\n };\n}\n\nfunction extractIdentityEnvelope(\n extra: unknown,\n): OpenAgentRequestIdentity | null {\n if (extra === null || typeof extra !== 'object') {\n return null;\n }\n const meta = (extra as { _meta?: unknown })._meta;\n if (meta === null || typeof meta !== 'object') {\n return null;\n }\n const openAgent = (meta as { openagent?: unknown }).openagent;\n if (openAgent === null || typeof openAgent !== 'object') {\n return null;\n }\n const identity = (openAgent as { identity?: unknown }).identity;\n if (identity === null || typeof identity !== 'object') {\n return null;\n }\n const candidate = identity as Record<string, unknown>;\n if (\n typeof candidate['did'] !== 'string' ||\n typeof candidate['proof'] !== 'string'\n ) {\n return null;\n }\n const envelope: OpenAgentRequestIdentity = {\n did: candidate['did'],\n proof: candidate['proof'],\n };\n if (typeof candidate['nonce'] === 'string') {\n envelope.nonce = candidate['nonce'];\n }\n if (\n typeof candidate['context'] === 'object' &&\n candidate['context'] !== null\n ) {\n envelope.context = candidate['context'] as Record<string, unknown>;\n }\n return envelope;\n}\n\nfunction stampAuditMeta(result: unknown, identity: VerifiedIdentity): unknown {\n if (result === null || typeof result !== 'object') {\n return result;\n }\n const auditMeta: AuditedResultMeta = {\n audit_id: identity.auditId,\n verified_did: identity.did,\n scopes: identity.scopes,\n };\n const existingMeta =\n typeof (result as { _meta?: unknown })._meta === 'object' &&\n (result as { _meta?: unknown })._meta !== null\n ? ((result as { _meta: Record<string, unknown> })._meta)\n : {};\n return {\n ...(result as Record<string, unknown>),\n _meta: {\n ...existingMeta,\n openagent: auditMeta,\n },\n };\n}\n\nfunction normalizeError(error: unknown): unknown {\n if (error instanceof OpenAgentMcpError) {\n // Surface the JSON-RPC code on the error so the SDK's error\n // serializer picks it up.\n const jsonRpc = error.toJsonRpcError();\n Object.assign(error, { code: jsonRpc.code, data: jsonRpc.data });\n }\n return error;\n}\n\nfunction nowMs(): number {\n if (\n typeof performance !== 'undefined' &&\n typeof performance.now === 'function'\n ) {\n return performance.now();\n }\n return Date.now();\n}\n\nconst ANONYMOUS_IDENTITY: VerifiedIdentity = {\n did: 'did:oas:anonymous',\n scopes: [],\n auditId: 'anonymous',\n claims: {},\n};\n\nexport { ANONYMOUS_IDENTITY };\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/request-boundary.ts","../src/server.ts"],"names":["AsyncLocalStorage"],"mappings":"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","file":"server.cjs","sourcesContent":["/**\n * Error types for @openagentid/mcp.\n *\n * These map onto MCP JSON-RPC error codes so callers see consistent\n * failure modes regardless of which middleware step rejected the call.\n *\n * Reference: https://www.jsonrpc.org/specification#error_object\n */\n\n/** Standard JSON-RPC + MCP error codes used by the middleware. */\nexport const McpErrorCode = {\n /** -32600 — request was malformed at the JSON-RPC layer. */\n InvalidRequest: -32600,\n /** -32601 — the requested method/tool was not found. */\n MethodNotFound: -32601,\n /** -32602 — params failed validation. */\n InvalidParams: -32602,\n /** -32603 — internal server error. */\n InternalError: -32603,\n /** -32000 — generic server error (used for auth failures by default). */\n ServerError: -32000,\n /** -32001 — identity verification failed. */\n AuthenticationFailed: -32001,\n /** -32002 — caller does not hold the required scope. */\n AuthorizationDenied: -32002,\n /** -32003 — skills policy rejected the call. */\n SkillsPolicyDenied: -32003,\n} as const;\n\nexport type McpErrorCodeValue =\n (typeof McpErrorCode)[keyof typeof McpErrorCode];\n\n/**\n * Base class for all middleware errors. Subclasses set a default\n * {@link OpenAgentMcpError.code} that maps to a JSON-RPC error code.\n */\nexport class OpenAgentMcpError extends Error {\n public readonly code: McpErrorCodeValue;\n public readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: McpErrorCodeValue,\n data?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'OpenAgentMcpError';\n this.code = code;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Convert to a plain JSON-RPC error payload that the MCP SDK can\n * serialize over the wire.\n */\n toJsonRpcError(): {\n code: McpErrorCodeValue;\n message: string;\n data?: Record<string, unknown>;\n } {\n if (this.data !== undefined) {\n return { code: this.code, message: this.message, data: this.data };\n }\n return { code: this.code, message: this.message };\n }\n}\n\n/** Caller did not present an OpenAgent identity envelope. */\nexport class MissingIdentityError extends OpenAgentMcpError {\n constructor(toolName: string) {\n super(\n `Tool '${toolName}' requires an OpenAgent identity in _meta.openagent.identity`,\n McpErrorCode.AuthenticationFailed,\n { toolName },\n );\n this.name = 'MissingIdentityError';\n }\n}\n\n/** Identity envelope was present but the verifier rejected it. */\nexport class IdentityVerificationError extends OpenAgentMcpError {\n constructor(toolName: string, cause: unknown) {\n super(\n `Identity verification failed for tool '${toolName}': ${formatCause(cause)}`,\n McpErrorCode.AuthenticationFailed,\n { toolName, cause: formatCause(cause) },\n );\n this.name = 'IdentityVerificationError';\n }\n}\n\n/** Caller's verified identity does not hold the required scopes. */\nexport class AuthorizationDeniedError extends OpenAgentMcpError {\n constructor(\n toolName: string,\n requiredScopes: ReadonlyArray<string>,\n heldScopes: ReadonlyArray<string>,\n ) {\n super(\n `Tool '${toolName}' requires scopes [${requiredScopes.join(', ')}], caller holds [${heldScopes.join(', ')}]`,\n McpErrorCode.AuthorizationDenied,\n {\n toolName,\n requiredScopes: [...requiredScopes],\n heldScopes: [...heldScopes],\n },\n );\n this.name = 'AuthorizationDeniedError';\n }\n}\n\n/** Skills policy hook returned `allow: false`. */\nexport class SkillsPolicyDeniedError extends OpenAgentMcpError {\n constructor(toolName: string, reason: string | undefined) {\n super(\n `Skills policy denied tool '${toolName}'${reason ? `: ${reason}` : ''}`,\n McpErrorCode.SkillsPolicyDenied,\n reason !== undefined ? { toolName, reason } : { toolName },\n );\n this.name = 'SkillsPolicyDeniedError';\n }\n}\n\nfunction formatCause(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n return 'unknown error';\n}\n","/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * Use the workspace adapters for the current SDK. These interfaces also\n * support applications that supply their own signing and verification authority.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Verifier adapter contract — supplied by createWorkspaceMcpServer or an\n * application-owned identity authority.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n /** Original wire arguments before tool schema defaults/transforms; scopes are derived from parsed arguments. */\n request?: { toolName: string; args: unknown },\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n args?: Record<string, unknown>,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Pick<Agent, 'did' | 'verifier'>;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface InboundToolRequest {\n readonly toolName: string;\n readonly args: unknown;\n}\n\ninterface TransportLike {\n onmessage?: (message: unknown, ...extra: unknown[]) => unknown;\n}\n\ninterface Connectable {\n connect?(transport: unknown, ...options: unknown[]): Promise<void>;\n readonly server?: { readonly transport?: unknown };\n}\n\n/** Capture the wire request before McpServer applies the tool's Zod schema.\n * Public transport callbacks are the only boundary touched. Async context keeps\n * concurrent calls isolated even when they reuse a JSON-RPC request ID. */\nexport function installRequestBoundary(server: Connectable): AsyncLocalStorage<InboundToolRequest | undefined> {\n const context = new AsyncLocalStorage<InboundToolRequest | undefined>();\n const wrap = (handler: NonNullable<TransportLike['onmessage']>, transport: object) =>\n (message: unknown, ...extra: unknown[]) => {\n let request: InboundToolRequest | undefined;\n if (message && typeof message === 'object' && 'method' in message && message.method === 'tools/call' &&\n 'params' in message && message.params && typeof message.params === 'object' &&\n 'name' in message.params && typeof message.params.name === 'string') {\n // Snapshot before schemas or application transforms can mutate the input.\n request = { toolName: message.params.name,\n args: structuredClone('arguments' in message.params ? message.params.arguments : undefined) };\n }\n return context.run(request, () => handler.call(transport, message, ...extra));\n };\n\n // Also support wrapping an already-connected McpServer via its public transport.\n const existing = server.server?.transport;\n if (existing && typeof existing === 'object') {\n const transport = existing as TransportLike;\n if (transport.onmessage) transport.onmessage = wrap(transport.onmessage, transport);\n }\n const connect = server.connect;\n if (connect) {\n // Patch the public method so both rawServer.connect() and proxy.connect()\n // work; existing callers need not change which handle they connect.\n server.connect = async function (transport: unknown, ...options: unknown[]) {\n if (!transport || typeof transport !== 'object') throw new TypeError('MCP transport is required');\n const wrapped = new Proxy(transport as TransportLike, {\n set(target, key, value) {\n return Reflect.set(target, key, key === 'onmessage' && typeof value === 'function'\n ? wrap(value as NonNullable<TransportLike['onmessage']>, target) : value, target);\n },\n get(target, key) {\n const value = Reflect.get(target, key, target);\n return typeof value === 'function' ? value.bind(target) : value;\n },\n });\n await connect.call(this, wrapped, ...options);\n };\n }\n return context;\n}\n","/**\n * Server-side middleware for @openagentid/mcp.\n *\n * Wraps an MCP {@link McpServer} (from `@modelcontextprotocol/sdk`) so that\n * every tool registration runs through an OpenAgent authentication\n * pipeline:\n *\n * 1. Extract the identity envelope from `extra._meta.openagent.identity`.\n * 2. Verify it via the configured {@link IdentityVerifier} and check\n * that the caller holds the scopes returned by `requireScopes`.\n * 3. Run the optional skills policy hook.\n * 4. Run the optional pre-call hook.\n * 5. Invoke the user's tool callback.\n * 6. Run the optional post-call hook with the result + duration.\n * 7. Stamp `audit_id` + `verified_did` into the result `_meta.openagent`.\n * 8. On error, run the optional onError hook and re-throw.\n *\n * Implementation note — version pinning:\n * The middleware is built against `@modelcontextprotocol/sdk@^1.27.0`.\n * The TypeScript SDK changed its tool registration API between 1.17 and\n * 1.27 (`tool(name, cb, ...)` → `registerTool(name, config, cb)`); both\n * call sites are intercepted here so any 1.x server still works.\n *\n * We deliberately do NOT touch the private `_registeredTools` map. The\n * middleware uses a JavaScript {@link Proxy} so callbacks are wrapped\n * exactly once at registration time, before the SDK's internal\n * request handler ever sees them.\n */\n\nimport {\n AuthorizationDeniedError,\n IdentityVerificationError,\n MissingIdentityError,\n OpenAgentMcpError,\n SkillsPolicyDeniedError,\n} from './errors.js';\nimport {\n Agent,\n AuditedResultMeta,\n ErrorHook,\n OpenAgentMcpConfig,\n OpenAgentRequestIdentity,\n PostCallHook,\n PreCallHook,\n ScopeDeriver,\n SkillsPolicyHook,\n VerifiedIdentity,\n defaultRequireScopes,\n} from './types.js';\nimport { installRequestBoundary } from './request-boundary.js';\n\n/**\n * Minimal McpServer surface used by the middleware. We avoid importing\n * concrete types from `@modelcontextprotocol/sdk` because peer-dep\n * versions vary across host applications and the SDK's own type exports\n * are subject to change. The shape below is the intersection of every\n * `1.x` McpServer release.\n */\nexport interface McpServerLike {\n tool(...args: unknown[]): unknown;\n registerTool(...args: unknown[]): unknown;\n connect?(transport: unknown, ...options: unknown[]): Promise<void>;\n readonly server?: { readonly transport?: unknown };\n}\n\n/**\n * Names of methods on the underlying server that take a tool callback as\n * one of their arguments. Both APIs are intercepted; if the SDK adds new\n * registration methods, append to this list.\n */\nconst TOOL_REGISTRATION_METHODS = ['tool', 'registerTool'] as const;\n\ntype ToolRegistrationMethod = (typeof TOOL_REGISTRATION_METHODS)[number];\n\n/**\n * Wrap an MCP server so every tool call is authenticated against an\n * OpenAgent identity.\n *\n * @example\n * ```ts\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { withOpenAgent } from '@openagentid/mcp';\n * import { agent } from './my-agent.js';\n *\n * const server = new McpServer({ name: 'my-tools', version: '0.1.0' });\n * const authedServer = withOpenAgent(server, { agent });\n *\n * authedServer.tool('search_web', searchHandler);\n * ```\n *\n * The returned proxy is type-compatible with the underlying server, so\n * existing code that calls `tool()`, `registerTool()`, `connect()`, etc.\n * keeps working without changes.\n */\nexport function withOpenAgent<T extends McpServerLike>(\n server: T,\n config: OpenAgentMcpConfig,\n): T {\n validateConfig(config);\n const middleware = new ToolMiddleware(config, installRequestBoundary(server));\n\n return new Proxy(server, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n if (\n typeof property === 'string' &&\n TOOL_REGISTRATION_METHODS.includes(property as ToolRegistrationMethod)\n ) {\n return wrapRegistrationMethod(\n value as (...args: unknown[]) => unknown,\n target,\n middleware,\n );\n }\n // Bind methods so `this` stays correct when destructured.\n return value.bind(target);\n },\n }) as T;\n}\n\nfunction validateConfig(config: OpenAgentMcpConfig): void {\n if (config === null || typeof config !== 'object') {\n throw new TypeError('OpenAgentMcpConfig must be an object');\n }\n if (config.agent === undefined || config.agent === null) {\n throw new TypeError('OpenAgentMcpConfig.agent is required');\n }\n if (\n config.agent.verifier === undefined ||\n typeof config.agent.verifier.verify !== 'function'\n ) {\n throw new TypeError('OpenAgentMcpConfig.agent.verifier.verify is required');\n }\n}\n\n/**\n * Wrap a single registration method so the user-supplied callback gets\n * replaced by an auth-wrapped one. The MCP SDK accepts the callback in\n * different positional slots depending on overload — we walk the args\n * list and replace the FIRST function we find. This is the same approach\n * the SDK itself uses internally.\n */\nfunction wrapRegistrationMethod(\n original: (...args: unknown[]) => unknown,\n thisArg: unknown,\n middleware: ToolMiddleware,\n): (...args: unknown[]) => unknown {\n return function wrapped(this: unknown, ...args: unknown[]): unknown {\n const toolName = extractToolName(args);\n const callbackIndex = findCallbackIndex(args);\n if (callbackIndex === -1) {\n // No callback in the args — defensive: forward as-is so we don't\n // mask SDK-level errors that the host would otherwise see.\n return original.apply(thisArg, args);\n }\n const userCallback = args[callbackIndex] as (\n ...callbackArgs: unknown[]\n ) => unknown;\n const wrappedCallback = middleware.wrap(toolName, userCallback);\n const newArgs = [...args];\n newArgs[callbackIndex] = wrappedCallback;\n return original.apply(thisArg, newArgs);\n };\n}\n\nfunction extractToolName(args: ReadonlyArray<unknown>): string {\n if (args.length > 0 && typeof args[0] === 'string') {\n return args[0];\n }\n // registerTool's first arg is also a string in 1.27, so this should\n // never trigger — kept as a safety net.\n return '<unknown>';\n}\n\nfunction findCallbackIndex(args: ReadonlyArray<unknown>): number {\n // Walk the args from the end so we find the LAST function — that's\n // the tool body in every overload of both `tool()` and\n // `registerTool()`.\n for (let i = args.length - 1; i >= 0; i -= 1) {\n if (typeof args[i] === 'function') {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Holds the middleware configuration and wraps individual tool callbacks.\n */\nclass ToolMiddleware {\n private readonly agent: Pick<Agent, 'did' | 'verifier'>;\n private readonly requireScopes: ScopeDeriver;\n private readonly requireIdentity: boolean;\n private readonly skillsPolicy: SkillsPolicyHook | undefined;\n private readonly preCall: PreCallHook | undefined;\n private readonly postCall: PostCallHook | undefined;\n private readonly onError: ErrorHook | undefined;\n\n constructor(config: OpenAgentMcpConfig, private readonly requests: ReturnType<typeof installRequestBoundary>) {\n this.agent = config.agent;\n this.requireScopes = config.requireScopes ?? (config.scopeFormat ? tool => [config.scopeFormat!(tool)] : defaultRequireScopes);\n this.requireIdentity = config.requireIdentity ?? true;\n this.skillsPolicy = config.skillsPolicy;\n this.preCall = config.preCall;\n this.postCall = config.postCall;\n this.onError = config.onError;\n }\n\n wrap(\n toolName: string,\n userCallback: (...args: unknown[]) => unknown,\n ): (...args: unknown[]) => Promise<unknown> {\n const middleware = this;\n return async function wrappedCallback(\n this: unknown,\n ...callbackArgs: unknown[]\n ): Promise<unknown> {\n // The MCP SDK invokes tool callbacks in two shapes depending on\n // whether the tool has an input schema:\n // (extra) — no schema\n // (args, extra) — with schema\n // The `extra` is always the LAST arg.\n const { args, extra } = splitToolArgs(callbackArgs);\n const startedAt = nowMs();\n let identity: VerifiedIdentity | null = null;\n\n try {\n identity = await middleware.runAuthPipeline(toolName, args, extra);\n\n if (middleware.preCall !== undefined) {\n await middleware.preCall({ toolName, args, identity });\n }\n\n const result = await Promise.resolve(\n userCallback.apply(this, callbackArgs),\n );\n\n const stamped = stampAuditMeta(result, identity);\n\n if (middleware.postCall !== undefined) {\n await middleware.postCall({\n toolName,\n args,\n identity,\n durationMs: nowMs() - startedAt,\n result: stamped,\n });\n }\n return stamped;\n } catch (error: unknown) {\n if (middleware.onError !== undefined) {\n // The error hook MUST NOT throw — if it does, swallow so the\n // original error propagates to the caller intact.\n try {\n await middleware.onError({ toolName, args, identity, error });\n } catch {\n /* intentionally ignored */\n }\n }\n throw normalizeError(error);\n }\n };\n }\n\n private async runAuthPipeline(\n toolName: string,\n args: unknown,\n extra: unknown,\n ): Promise<VerifiedIdentity> {\n const identityEnvelope = extractIdentityEnvelope(extra);\n if (identityEnvelope === null) {\n if (this.requireIdentity) {\n throw new MissingIdentityError(toolName);\n }\n // Permissive mode: synthesize an \"anonymous\" identity so hooks\n // still run with a stable shape.\n return ANONYMOUS_IDENTITY;\n }\n\n const requiredScopes = this.requireScopes(toolName, args);\n let identity: VerifiedIdentity;\n try {\n // Identity binds the original transmitted request. Authorization policies\n // and tool callbacks intentionally use the SDK's parsed/effective arguments.\n const inbound = this.requests.getStore();\n if (inbound && inbound.toolName !== toolName) throw new Error('MCP request/tool binding mismatch');\n identity = await this.agent.verifier.verify(\n identityEnvelope,\n requiredScopes,\n inbound ?? { toolName, args },\n );\n } catch (cause: unknown) {\n throw new IdentityVerificationError(toolName, cause);\n }\n\n enforceScopes(toolName, requiredScopes, identity.scopes);\n\n if (this.skillsPolicy !== undefined) {\n const decision = await Promise.resolve(\n this.skillsPolicy({ toolName, args, identity }),\n );\n if (!decision.allow) {\n throw new SkillsPolicyDeniedError(toolName, decision.reason);\n }\n }\n\n return identity;\n }\n}\n\nfunction enforceScopes(\n toolName: string,\n required: ReadonlyArray<string>,\n held: ReadonlyArray<string>,\n): void {\n const missing = required.filter((scope) => !held.includes(scope));\n if (missing.length > 0) {\n throw new AuthorizationDeniedError(toolName, required, held);\n }\n}\n\nfunction splitToolArgs(callbackArgs: ReadonlyArray<unknown>): {\n args: unknown;\n extra: unknown;\n} {\n if (callbackArgs.length === 0) {\n return { args: undefined, extra: undefined };\n }\n if (callbackArgs.length === 1) {\n // Single argument is the `extra` object.\n return { args: undefined, extra: callbackArgs[0] };\n }\n return {\n args: callbackArgs[0],\n extra: callbackArgs[callbackArgs.length - 1],\n };\n}\n\nfunction extractIdentityEnvelope(\n extra: unknown,\n): OpenAgentRequestIdentity | null {\n if (extra === null || typeof extra !== 'object') {\n return null;\n }\n const meta = (extra as { _meta?: unknown })._meta;\n if (meta === null || typeof meta !== 'object') {\n return null;\n }\n const openAgent = (meta as { openagent?: unknown }).openagent;\n if (openAgent === null || typeof openAgent !== 'object') {\n return null;\n }\n const identity = (openAgent as { identity?: unknown }).identity;\n if (identity === null || typeof identity !== 'object') {\n return null;\n }\n const candidate = identity as Record<string, unknown>;\n if (\n typeof candidate['did'] !== 'string' ||\n typeof candidate['proof'] !== 'string'\n ) {\n return null;\n }\n const envelope: OpenAgentRequestIdentity = {\n did: candidate['did'],\n proof: candidate['proof'],\n };\n if (typeof candidate['nonce'] === 'string') {\n envelope.nonce = candidate['nonce'];\n }\n if (\n typeof candidate['context'] === 'object' &&\n candidate['context'] !== null\n ) {\n envelope.context = candidate['context'] as Record<string, unknown>;\n }\n return envelope;\n}\n\nfunction stampAuditMeta(result: unknown, identity: VerifiedIdentity): unknown {\n if (result === null || typeof result !== 'object') {\n return result;\n }\n const auditMeta: AuditedResultMeta = {\n audit_id: identity.auditId,\n verified_did: identity.did,\n scopes: identity.scopes,\n };\n const existingMeta =\n typeof (result as { _meta?: unknown })._meta === 'object' &&\n (result as { _meta?: unknown })._meta !== null\n ? ((result as { _meta: Record<string, unknown> })._meta)\n : {};\n return {\n ...(result as Record<string, unknown>),\n _meta: {\n ...existingMeta,\n openagent: auditMeta,\n },\n };\n}\n\nfunction normalizeError(error: unknown): unknown {\n if (error instanceof OpenAgentMcpError) {\n // Surface the JSON-RPC code on the error so the SDK's error\n // serializer picks it up.\n const jsonRpc = error.toJsonRpcError();\n Object.assign(error, { code: jsonRpc.code, data: jsonRpc.data });\n }\n return error;\n}\n\nfunction nowMs(): number {\n if (\n typeof performance !== 'undefined' &&\n typeof performance.now === 'function'\n ) {\n return performance.now();\n }\n return Date.now();\n}\n\nconst ANONYMOUS_IDENTITY: VerifiedIdentity = {\n did: 'did:oas:anonymous',\n scopes: [],\n auditId: 'anonymous',\n claims: {},\n};\n\nexport { ANONYMOUS_IDENTITY };\n"]}
package/dist/server.d.cts CHANGED
@@ -39,6 +39,10 @@ import { VerifiedIdentity, OpenAgentMcpConfig } from './types.cjs';
39
39
  interface McpServerLike {
40
40
  tool(...args: unknown[]): unknown;
41
41
  registerTool(...args: unknown[]): unknown;
42
+ connect?(transport: unknown, ...options: unknown[]): Promise<void>;
43
+ readonly server?: {
44
+ readonly transport?: unknown;
45
+ };
42
46
  }
43
47
  /**
44
48
  * Wrap an MCP server so every tool call is authenticated against an
package/dist/server.d.ts CHANGED
@@ -39,6 +39,10 @@ import { VerifiedIdentity, OpenAgentMcpConfig } from './types.js';
39
39
  interface McpServerLike {
40
40
  tool(...args: unknown[]): unknown;
41
41
  registerTool(...args: unknown[]): unknown;
42
+ connect?(transport: unknown, ...options: unknown[]): Promise<void>;
43
+ readonly server?: {
44
+ readonly transport?: unknown;
45
+ };
42
46
  }
43
47
  /**
44
48
  * Wrap an MCP server so every tool call is authenticated against an
package/dist/server.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
+
1
3
  // src/errors.ts
2
4
  var McpErrorCode = {
3
5
  /** -32001 — identity verification failed. */
@@ -86,12 +88,47 @@ function formatCause(cause) {
86
88
  // src/types.ts
87
89
  var defaultScopeFormat = (toolName) => `mcp:${toolName}:invoke`;
88
90
  var defaultRequireScopes = (toolName) => [defaultScopeFormat(toolName)];
91
+ function installRequestBoundary(server) {
92
+ const context = new AsyncLocalStorage();
93
+ const wrap = (handler, transport) => (message, ...extra) => {
94
+ let request;
95
+ if (message && typeof message === "object" && "method" in message && message.method === "tools/call" && "params" in message && message.params && typeof message.params === "object" && "name" in message.params && typeof message.params.name === "string") {
96
+ request = {
97
+ toolName: message.params.name,
98
+ args: structuredClone("arguments" in message.params ? message.params.arguments : void 0)
99
+ };
100
+ }
101
+ return context.run(request, () => handler.call(transport, message, ...extra));
102
+ };
103
+ const existing = server.server?.transport;
104
+ if (existing && typeof existing === "object") {
105
+ const transport = existing;
106
+ if (transport.onmessage) transport.onmessage = wrap(transport.onmessage, transport);
107
+ }
108
+ const connect = server.connect;
109
+ if (connect) {
110
+ server.connect = async function(transport, ...options) {
111
+ if (!transport || typeof transport !== "object") throw new TypeError("MCP transport is required");
112
+ const wrapped = new Proxy(transport, {
113
+ set(target, key, value) {
114
+ return Reflect.set(target, key, key === "onmessage" && typeof value === "function" ? wrap(value, target) : value, target);
115
+ },
116
+ get(target, key) {
117
+ const value = Reflect.get(target, key, target);
118
+ return typeof value === "function" ? value.bind(target) : value;
119
+ }
120
+ });
121
+ await connect.call(this, wrapped, ...options);
122
+ };
123
+ }
124
+ return context;
125
+ }
89
126
 
90
127
  // src/server.ts
91
128
  var TOOL_REGISTRATION_METHODS = ["tool", "registerTool"];
92
129
  function withOpenAgent(server, config) {
93
130
  validateConfig(config);
94
- const middleware = new ToolMiddleware(config);
131
+ const middleware = new ToolMiddleware(config, installRequestBoundary(server));
95
132
  return new Proxy(server, {
96
133
  get(target, property, receiver) {
97
134
  const value = Reflect.get(target, property, receiver);
@@ -149,22 +186,24 @@ function findCallbackIndex(args) {
149
186
  return -1;
150
187
  }
151
188
  var ToolMiddleware = class {
152
- agent;
153
- requireScopes;
154
- requireIdentity;
155
- skillsPolicy;
156
- preCall;
157
- postCall;
158
- onError;
159
- constructor(config) {
189
+ constructor(config, requests) {
190
+ this.requests = requests;
160
191
  this.agent = config.agent;
161
- this.requireScopes = config.requireScopes ?? defaultRequireScopes;
192
+ this.requireScopes = config.requireScopes ?? (config.scopeFormat ? (tool) => [config.scopeFormat(tool)] : defaultRequireScopes);
162
193
  this.requireIdentity = config.requireIdentity ?? true;
163
194
  this.skillsPolicy = config.skillsPolicy;
164
195
  this.preCall = config.preCall;
165
196
  this.postCall = config.postCall;
166
197
  this.onError = config.onError;
167
198
  }
199
+ requests;
200
+ agent;
201
+ requireScopes;
202
+ requireIdentity;
203
+ skillsPolicy;
204
+ preCall;
205
+ postCall;
206
+ onError;
168
207
  wrap(toolName, userCallback) {
169
208
  const middleware = this;
170
209
  return async function wrappedCallback(...callbackArgs) {
@@ -212,9 +251,12 @@ var ToolMiddleware = class {
212
251
  const requiredScopes = this.requireScopes(toolName, args);
213
252
  let identity;
214
253
  try {
254
+ const inbound = this.requests.getStore();
255
+ if (inbound && inbound.toolName !== toolName) throw new Error("MCP request/tool binding mismatch");
215
256
  identity = await this.agent.verifier.verify(
216
257
  identityEnvelope,
217
- requiredScopes
258
+ requiredScopes,
259
+ inbound ?? { toolName, args }
218
260
  );
219
261
  } catch (cause) {
220
262
  throw new IdentityVerificationError(toolName, cause);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/server.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["/**\n * Error types for @openagentid/mcp.\n *\n * These map onto MCP JSON-RPC error codes so callers see consistent\n * failure modes regardless of which middleware step rejected the call.\n *\n * Reference: https://www.jsonrpc.org/specification#error_object\n */\n\n/** Standard JSON-RPC + MCP error codes used by the middleware. */\nexport const McpErrorCode = {\n /** -32600 — request was malformed at the JSON-RPC layer. */\n InvalidRequest: -32600,\n /** -32601 — the requested method/tool was not found. */\n MethodNotFound: -32601,\n /** -32602 — params failed validation. */\n InvalidParams: -32602,\n /** -32603 — internal server error. */\n InternalError: -32603,\n /** -32000 — generic server error (used for auth failures by default). */\n ServerError: -32000,\n /** -32001 — identity verification failed. */\n AuthenticationFailed: -32001,\n /** -32002 — caller does not hold the required scope. */\n AuthorizationDenied: -32002,\n /** -32003 — skills policy rejected the call. */\n SkillsPolicyDenied: -32003,\n} as const;\n\nexport type McpErrorCodeValue =\n (typeof McpErrorCode)[keyof typeof McpErrorCode];\n\n/**\n * Base class for all middleware errors. Subclasses set a default\n * {@link OpenAgentMcpError.code} that maps to a JSON-RPC error code.\n */\nexport class OpenAgentMcpError extends Error {\n public readonly code: McpErrorCodeValue;\n public readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: McpErrorCodeValue,\n data?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'OpenAgentMcpError';\n this.code = code;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Convert to a plain JSON-RPC error payload that the MCP SDK can\n * serialize over the wire.\n */\n toJsonRpcError(): {\n code: McpErrorCodeValue;\n message: string;\n data?: Record<string, unknown>;\n } {\n if (this.data !== undefined) {\n return { code: this.code, message: this.message, data: this.data };\n }\n return { code: this.code, message: this.message };\n }\n}\n\n/** Caller did not present an OpenAgent identity envelope. */\nexport class MissingIdentityError extends OpenAgentMcpError {\n constructor(toolName: string) {\n super(\n `Tool '${toolName}' requires an OpenAgent identity in _meta.openagent.identity`,\n McpErrorCode.AuthenticationFailed,\n { toolName },\n );\n this.name = 'MissingIdentityError';\n }\n}\n\n/** Identity envelope was present but the verifier rejected it. */\nexport class IdentityVerificationError extends OpenAgentMcpError {\n constructor(toolName: string, cause: unknown) {\n super(\n `Identity verification failed for tool '${toolName}': ${formatCause(cause)}`,\n McpErrorCode.AuthenticationFailed,\n { toolName, cause: formatCause(cause) },\n );\n this.name = 'IdentityVerificationError';\n }\n}\n\n/** Caller's verified identity does not hold the required scopes. */\nexport class AuthorizationDeniedError extends OpenAgentMcpError {\n constructor(\n toolName: string,\n requiredScopes: ReadonlyArray<string>,\n heldScopes: ReadonlyArray<string>,\n ) {\n super(\n `Tool '${toolName}' requires scopes [${requiredScopes.join(', ')}], caller holds [${heldScopes.join(', ')}]`,\n McpErrorCode.AuthorizationDenied,\n {\n toolName,\n requiredScopes: [...requiredScopes],\n heldScopes: [...heldScopes],\n },\n );\n this.name = 'AuthorizationDeniedError';\n }\n}\n\n/** Skills policy hook returned `allow: false`. */\nexport class SkillsPolicyDeniedError extends OpenAgentMcpError {\n constructor(toolName: string, reason: string | undefined) {\n super(\n `Skills policy denied tool '${toolName}'${reason ? `: ${reason}` : ''}`,\n McpErrorCode.SkillsPolicyDenied,\n reason !== undefined ? { toolName, reason } : { toolName },\n );\n this.name = 'SkillsPolicyDeniedError';\n }\n}\n\nfunction formatCause(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n return 'unknown error';\n}\n","/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * The real `@openagentid/sdk` exports types that are structurally compatible\n * with these — there is no runtime dependency.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The verifier interface — implemented by `@openagentid/sdk` (production) and\n * by the in-memory test agent shipped here.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Agent;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n","/**\n * Server-side middleware for @openagentid/mcp.\n *\n * Wraps an MCP {@link McpServer} (from `@modelcontextprotocol/sdk`) so that\n * every tool registration runs through an OpenAgent authentication\n * pipeline:\n *\n * 1. Extract the identity envelope from `extra._meta.openagent.identity`.\n * 2. Verify it via the configured {@link IdentityVerifier} and check\n * that the caller holds the scopes returned by `requireScopes`.\n * 3. Run the optional skills policy hook.\n * 4. Run the optional pre-call hook.\n * 5. Invoke the user's tool callback.\n * 6. Run the optional post-call hook with the result + duration.\n * 7. Stamp `audit_id` + `verified_did` into the result `_meta.openagent`.\n * 8. On error, run the optional onError hook and re-throw.\n *\n * Implementation note — version pinning:\n * The middleware is built against `@modelcontextprotocol/sdk@^1.27.0`.\n * The TypeScript SDK changed its tool registration API between 1.17 and\n * 1.27 (`tool(name, cb, ...)` → `registerTool(name, config, cb)`); both\n * call sites are intercepted here so any 1.x server still works.\n *\n * We deliberately do NOT touch the private `_registeredTools` map. The\n * middleware uses a JavaScript {@link Proxy} so callbacks are wrapped\n * exactly once at registration time, before the SDK's internal\n * request handler ever sees them.\n */\n\nimport {\n AuthorizationDeniedError,\n IdentityVerificationError,\n MissingIdentityError,\n OpenAgentMcpError,\n SkillsPolicyDeniedError,\n} from './errors.js';\nimport {\n Agent,\n AuditedResultMeta,\n ErrorHook,\n OpenAgentMcpConfig,\n OpenAgentRequestIdentity,\n PostCallHook,\n PreCallHook,\n ScopeDeriver,\n SkillsPolicyHook,\n VerifiedIdentity,\n defaultRequireScopes,\n} from './types.js';\n\n/**\n * Minimal McpServer surface used by the middleware. We avoid importing\n * concrete types from `@modelcontextprotocol/sdk` because peer-dep\n * versions vary across host applications and the SDK's own type exports\n * are subject to change. The shape below is the intersection of every\n * `1.x` McpServer release.\n */\nexport interface McpServerLike {\n tool(...args: unknown[]): unknown;\n registerTool(...args: unknown[]): unknown;\n}\n\n/**\n * Names of methods on the underlying server that take a tool callback as\n * one of their arguments. Both APIs are intercepted; if the SDK adds new\n * registration methods, append to this list.\n */\nconst TOOL_REGISTRATION_METHODS = ['tool', 'registerTool'] as const;\n\ntype ToolRegistrationMethod = (typeof TOOL_REGISTRATION_METHODS)[number];\n\n/**\n * Wrap an MCP server so every tool call is authenticated against an\n * OpenAgent identity.\n *\n * @example\n * ```ts\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { withOpenAgent } from '@openagentid/mcp';\n * import { agent } from './my-agent.js';\n *\n * const server = new McpServer({ name: 'my-tools', version: '0.1.0' });\n * const authedServer = withOpenAgent(server, { agent });\n *\n * authedServer.tool('search_web', searchHandler);\n * ```\n *\n * The returned proxy is type-compatible with the underlying server, so\n * existing code that calls `tool()`, `registerTool()`, `connect()`, etc.\n * keeps working without changes.\n */\nexport function withOpenAgent<T extends McpServerLike>(\n server: T,\n config: OpenAgentMcpConfig,\n): T {\n validateConfig(config);\n const middleware = new ToolMiddleware(config);\n\n return new Proxy(server, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n if (\n typeof property === 'string' &&\n TOOL_REGISTRATION_METHODS.includes(property as ToolRegistrationMethod)\n ) {\n return wrapRegistrationMethod(\n value as (...args: unknown[]) => unknown,\n target,\n middleware,\n );\n }\n // Bind methods so `this` stays correct when destructured.\n return value.bind(target);\n },\n }) as T;\n}\n\nfunction validateConfig(config: OpenAgentMcpConfig): void {\n if (config === null || typeof config !== 'object') {\n throw new TypeError('OpenAgentMcpConfig must be an object');\n }\n if (config.agent === undefined || config.agent === null) {\n throw new TypeError('OpenAgentMcpConfig.agent is required');\n }\n if (\n config.agent.verifier === undefined ||\n typeof config.agent.verifier.verify !== 'function'\n ) {\n throw new TypeError('OpenAgentMcpConfig.agent.verifier.verify is required');\n }\n}\n\n/**\n * Wrap a single registration method so the user-supplied callback gets\n * replaced by an auth-wrapped one. The MCP SDK accepts the callback in\n * different positional slots depending on overload — we walk the args\n * list and replace the FIRST function we find. This is the same approach\n * the SDK itself uses internally.\n */\nfunction wrapRegistrationMethod(\n original: (...args: unknown[]) => unknown,\n thisArg: unknown,\n middleware: ToolMiddleware,\n): (...args: unknown[]) => unknown {\n return function wrapped(this: unknown, ...args: unknown[]): unknown {\n const toolName = extractToolName(args);\n const callbackIndex = findCallbackIndex(args);\n if (callbackIndex === -1) {\n // No callback in the args — defensive: forward as-is so we don't\n // mask SDK-level errors that the host would otherwise see.\n return original.apply(thisArg, args);\n }\n const userCallback = args[callbackIndex] as (\n ...callbackArgs: unknown[]\n ) => unknown;\n const wrappedCallback = middleware.wrap(toolName, userCallback);\n const newArgs = [...args];\n newArgs[callbackIndex] = wrappedCallback;\n return original.apply(thisArg, newArgs);\n };\n}\n\nfunction extractToolName(args: ReadonlyArray<unknown>): string {\n if (args.length > 0 && typeof args[0] === 'string') {\n return args[0];\n }\n // registerTool's first arg is also a string in 1.27, so this should\n // never trigger — kept as a safety net.\n return '<unknown>';\n}\n\nfunction findCallbackIndex(args: ReadonlyArray<unknown>): number {\n // Walk the args from the end so we find the LAST function — that's\n // the tool body in every overload of both `tool()` and\n // `registerTool()`.\n for (let i = args.length - 1; i >= 0; i -= 1) {\n if (typeof args[i] === 'function') {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Holds the middleware configuration and wraps individual tool callbacks.\n */\nclass ToolMiddleware {\n private readonly agent: Agent;\n private readonly requireScopes: ScopeDeriver;\n private readonly requireIdentity: boolean;\n private readonly skillsPolicy: SkillsPolicyHook | undefined;\n private readonly preCall: PreCallHook | undefined;\n private readonly postCall: PostCallHook | undefined;\n private readonly onError: ErrorHook | undefined;\n\n constructor(config: OpenAgentMcpConfig) {\n this.agent = config.agent;\n this.requireScopes = config.requireScopes ?? defaultRequireScopes;\n this.requireIdentity = config.requireIdentity ?? true;\n this.skillsPolicy = config.skillsPolicy;\n this.preCall = config.preCall;\n this.postCall = config.postCall;\n this.onError = config.onError;\n }\n\n wrap(\n toolName: string,\n userCallback: (...args: unknown[]) => unknown,\n ): (...args: unknown[]) => Promise<unknown> {\n const middleware = this;\n return async function wrappedCallback(\n this: unknown,\n ...callbackArgs: unknown[]\n ): Promise<unknown> {\n // The MCP SDK invokes tool callbacks in two shapes depending on\n // whether the tool has an input schema:\n // (extra) — no schema\n // (args, extra) — with schema\n // The `extra` is always the LAST arg.\n const { args, extra } = splitToolArgs(callbackArgs);\n const startedAt = nowMs();\n let identity: VerifiedIdentity | null = null;\n\n try {\n identity = await middleware.runAuthPipeline(toolName, args, extra);\n\n if (middleware.preCall !== undefined) {\n await middleware.preCall({ toolName, args, identity });\n }\n\n const result = await Promise.resolve(\n userCallback.apply(this, callbackArgs),\n );\n\n const stamped = stampAuditMeta(result, identity);\n\n if (middleware.postCall !== undefined) {\n await middleware.postCall({\n toolName,\n args,\n identity,\n durationMs: nowMs() - startedAt,\n result: stamped,\n });\n }\n return stamped;\n } catch (error: unknown) {\n if (middleware.onError !== undefined) {\n // The error hook MUST NOT throw — if it does, swallow so the\n // original error propagates to the caller intact.\n try {\n await middleware.onError({ toolName, args, identity, error });\n } catch {\n /* intentionally ignored */\n }\n }\n throw normalizeError(error);\n }\n };\n }\n\n private async runAuthPipeline(\n toolName: string,\n args: unknown,\n extra: unknown,\n ): Promise<VerifiedIdentity> {\n const identityEnvelope = extractIdentityEnvelope(extra);\n if (identityEnvelope === null) {\n if (this.requireIdentity) {\n throw new MissingIdentityError(toolName);\n }\n // Permissive mode: synthesize an \"anonymous\" identity so hooks\n // still run with a stable shape.\n return ANONYMOUS_IDENTITY;\n }\n\n const requiredScopes = this.requireScopes(toolName, args);\n let identity: VerifiedIdentity;\n try {\n identity = await this.agent.verifier.verify(\n identityEnvelope,\n requiredScopes,\n );\n } catch (cause: unknown) {\n throw new IdentityVerificationError(toolName, cause);\n }\n\n enforceScopes(toolName, requiredScopes, identity.scopes);\n\n if (this.skillsPolicy !== undefined) {\n const decision = await Promise.resolve(\n this.skillsPolicy({ toolName, args, identity }),\n );\n if (!decision.allow) {\n throw new SkillsPolicyDeniedError(toolName, decision.reason);\n }\n }\n\n return identity;\n }\n}\n\nfunction enforceScopes(\n toolName: string,\n required: ReadonlyArray<string>,\n held: ReadonlyArray<string>,\n): void {\n const missing = required.filter((scope) => !held.includes(scope));\n if (missing.length > 0) {\n throw new AuthorizationDeniedError(toolName, required, held);\n }\n}\n\nfunction splitToolArgs(callbackArgs: ReadonlyArray<unknown>): {\n args: unknown;\n extra: unknown;\n} {\n if (callbackArgs.length === 0) {\n return { args: undefined, extra: undefined };\n }\n if (callbackArgs.length === 1) {\n // Single argument is the `extra` object.\n return { args: undefined, extra: callbackArgs[0] };\n }\n return {\n args: callbackArgs[0],\n extra: callbackArgs[callbackArgs.length - 1],\n };\n}\n\nfunction extractIdentityEnvelope(\n extra: unknown,\n): OpenAgentRequestIdentity | null {\n if (extra === null || typeof extra !== 'object') {\n return null;\n }\n const meta = (extra as { _meta?: unknown })._meta;\n if (meta === null || typeof meta !== 'object') {\n return null;\n }\n const openAgent = (meta as { openagent?: unknown }).openagent;\n if (openAgent === null || typeof openAgent !== 'object') {\n return null;\n }\n const identity = (openAgent as { identity?: unknown }).identity;\n if (identity === null || typeof identity !== 'object') {\n return null;\n }\n const candidate = identity as Record<string, unknown>;\n if (\n typeof candidate['did'] !== 'string' ||\n typeof candidate['proof'] !== 'string'\n ) {\n return null;\n }\n const envelope: OpenAgentRequestIdentity = {\n did: candidate['did'],\n proof: candidate['proof'],\n };\n if (typeof candidate['nonce'] === 'string') {\n envelope.nonce = candidate['nonce'];\n }\n if (\n typeof candidate['context'] === 'object' &&\n candidate['context'] !== null\n ) {\n envelope.context = candidate['context'] as Record<string, unknown>;\n }\n return envelope;\n}\n\nfunction stampAuditMeta(result: unknown, identity: VerifiedIdentity): unknown {\n if (result === null || typeof result !== 'object') {\n return result;\n }\n const auditMeta: AuditedResultMeta = {\n audit_id: identity.auditId,\n verified_did: identity.did,\n scopes: identity.scopes,\n };\n const existingMeta =\n typeof (result as { _meta?: unknown })._meta === 'object' &&\n (result as { _meta?: unknown })._meta !== null\n ? ((result as { _meta: Record<string, unknown> })._meta)\n : {};\n return {\n ...(result as Record<string, unknown>),\n _meta: {\n ...existingMeta,\n openagent: auditMeta,\n },\n };\n}\n\nfunction normalizeError(error: unknown): unknown {\n if (error instanceof OpenAgentMcpError) {\n // Surface the JSON-RPC code on the error so the SDK's error\n // serializer picks it up.\n const jsonRpc = error.toJsonRpcError();\n Object.assign(error, { code: jsonRpc.code, data: jsonRpc.data });\n }\n return error;\n}\n\nfunction nowMs(): number {\n if (\n typeof performance !== 'undefined' &&\n typeof performance.now === 'function'\n ) {\n return performance.now();\n }\n return Date.now();\n}\n\nconst ANONYMOUS_IDENTITY: VerifiedIdentity = {\n did: 'did:oas:anonymous',\n scopes: [],\n auditId: 'anonymous',\n claims: {},\n};\n\nexport { ANONYMOUS_IDENTITY };\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/types.ts","../src/request-boundary.ts","../src/server.ts"],"names":[],"mappings":"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","file":"server.js","sourcesContent":["/**\n * Error types for @openagentid/mcp.\n *\n * These map onto MCP JSON-RPC error codes so callers see consistent\n * failure modes regardless of which middleware step rejected the call.\n *\n * Reference: https://www.jsonrpc.org/specification#error_object\n */\n\n/** Standard JSON-RPC + MCP error codes used by the middleware. */\nexport const McpErrorCode = {\n /** -32600 — request was malformed at the JSON-RPC layer. */\n InvalidRequest: -32600,\n /** -32601 — the requested method/tool was not found. */\n MethodNotFound: -32601,\n /** -32602 — params failed validation. */\n InvalidParams: -32602,\n /** -32603 — internal server error. */\n InternalError: -32603,\n /** -32000 — generic server error (used for auth failures by default). */\n ServerError: -32000,\n /** -32001 — identity verification failed. */\n AuthenticationFailed: -32001,\n /** -32002 — caller does not hold the required scope. */\n AuthorizationDenied: -32002,\n /** -32003 — skills policy rejected the call. */\n SkillsPolicyDenied: -32003,\n} as const;\n\nexport type McpErrorCodeValue =\n (typeof McpErrorCode)[keyof typeof McpErrorCode];\n\n/**\n * Base class for all middleware errors. Subclasses set a default\n * {@link OpenAgentMcpError.code} that maps to a JSON-RPC error code.\n */\nexport class OpenAgentMcpError extends Error {\n public readonly code: McpErrorCodeValue;\n public readonly data?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: McpErrorCodeValue,\n data?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'OpenAgentMcpError';\n this.code = code;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Convert to a plain JSON-RPC error payload that the MCP SDK can\n * serialize over the wire.\n */\n toJsonRpcError(): {\n code: McpErrorCodeValue;\n message: string;\n data?: Record<string, unknown>;\n } {\n if (this.data !== undefined) {\n return { code: this.code, message: this.message, data: this.data };\n }\n return { code: this.code, message: this.message };\n }\n}\n\n/** Caller did not present an OpenAgent identity envelope. */\nexport class MissingIdentityError extends OpenAgentMcpError {\n constructor(toolName: string) {\n super(\n `Tool '${toolName}' requires an OpenAgent identity in _meta.openagent.identity`,\n McpErrorCode.AuthenticationFailed,\n { toolName },\n );\n this.name = 'MissingIdentityError';\n }\n}\n\n/** Identity envelope was present but the verifier rejected it. */\nexport class IdentityVerificationError extends OpenAgentMcpError {\n constructor(toolName: string, cause: unknown) {\n super(\n `Identity verification failed for tool '${toolName}': ${formatCause(cause)}`,\n McpErrorCode.AuthenticationFailed,\n { toolName, cause: formatCause(cause) },\n );\n this.name = 'IdentityVerificationError';\n }\n}\n\n/** Caller's verified identity does not hold the required scopes. */\nexport class AuthorizationDeniedError extends OpenAgentMcpError {\n constructor(\n toolName: string,\n requiredScopes: ReadonlyArray<string>,\n heldScopes: ReadonlyArray<string>,\n ) {\n super(\n `Tool '${toolName}' requires scopes [${requiredScopes.join(', ')}], caller holds [${heldScopes.join(', ')}]`,\n McpErrorCode.AuthorizationDenied,\n {\n toolName,\n requiredScopes: [...requiredScopes],\n heldScopes: [...heldScopes],\n },\n );\n this.name = 'AuthorizationDeniedError';\n }\n}\n\n/** Skills policy hook returned `allow: false`. */\nexport class SkillsPolicyDeniedError extends OpenAgentMcpError {\n constructor(toolName: string, reason: string | undefined) {\n super(\n `Skills policy denied tool '${toolName}'${reason ? `: ${reason}` : ''}`,\n McpErrorCode.SkillsPolicyDenied,\n reason !== undefined ? { toolName, reason } : { toolName },\n );\n this.name = 'SkillsPolicyDeniedError';\n }\n}\n\nfunction formatCause(cause: unknown): string {\n if (cause instanceof Error) {\n return cause.message;\n }\n if (typeof cause === 'string') {\n return cause;\n }\n return 'unknown error';\n}\n","/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * Use the workspace adapters for the current SDK. These interfaces also\n * support applications that supply their own signing and verification authority.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Verifier adapter contract — supplied by createWorkspaceMcpServer or an\n * application-owned identity authority.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n /** Original wire arguments before tool schema defaults/transforms; scopes are derived from parsed arguments. */\n request?: { toolName: string; args: unknown },\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n args?: Record<string, unknown>,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Pick<Agent, 'did' | 'verifier'>;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface InboundToolRequest {\n readonly toolName: string;\n readonly args: unknown;\n}\n\ninterface TransportLike {\n onmessage?: (message: unknown, ...extra: unknown[]) => unknown;\n}\n\ninterface Connectable {\n connect?(transport: unknown, ...options: unknown[]): Promise<void>;\n readonly server?: { readonly transport?: unknown };\n}\n\n/** Capture the wire request before McpServer applies the tool's Zod schema.\n * Public transport callbacks are the only boundary touched. Async context keeps\n * concurrent calls isolated even when they reuse a JSON-RPC request ID. */\nexport function installRequestBoundary(server: Connectable): AsyncLocalStorage<InboundToolRequest | undefined> {\n const context = new AsyncLocalStorage<InboundToolRequest | undefined>();\n const wrap = (handler: NonNullable<TransportLike['onmessage']>, transport: object) =>\n (message: unknown, ...extra: unknown[]) => {\n let request: InboundToolRequest | undefined;\n if (message && typeof message === 'object' && 'method' in message && message.method === 'tools/call' &&\n 'params' in message && message.params && typeof message.params === 'object' &&\n 'name' in message.params && typeof message.params.name === 'string') {\n // Snapshot before schemas or application transforms can mutate the input.\n request = { toolName: message.params.name,\n args: structuredClone('arguments' in message.params ? message.params.arguments : undefined) };\n }\n return context.run(request, () => handler.call(transport, message, ...extra));\n };\n\n // Also support wrapping an already-connected McpServer via its public transport.\n const existing = server.server?.transport;\n if (existing && typeof existing === 'object') {\n const transport = existing as TransportLike;\n if (transport.onmessage) transport.onmessage = wrap(transport.onmessage, transport);\n }\n const connect = server.connect;\n if (connect) {\n // Patch the public method so both rawServer.connect() and proxy.connect()\n // work; existing callers need not change which handle they connect.\n server.connect = async function (transport: unknown, ...options: unknown[]) {\n if (!transport || typeof transport !== 'object') throw new TypeError('MCP transport is required');\n const wrapped = new Proxy(transport as TransportLike, {\n set(target, key, value) {\n return Reflect.set(target, key, key === 'onmessage' && typeof value === 'function'\n ? wrap(value as NonNullable<TransportLike['onmessage']>, target) : value, target);\n },\n get(target, key) {\n const value = Reflect.get(target, key, target);\n return typeof value === 'function' ? value.bind(target) : value;\n },\n });\n await connect.call(this, wrapped, ...options);\n };\n }\n return context;\n}\n","/**\n * Server-side middleware for @openagentid/mcp.\n *\n * Wraps an MCP {@link McpServer} (from `@modelcontextprotocol/sdk`) so that\n * every tool registration runs through an OpenAgent authentication\n * pipeline:\n *\n * 1. Extract the identity envelope from `extra._meta.openagent.identity`.\n * 2. Verify it via the configured {@link IdentityVerifier} and check\n * that the caller holds the scopes returned by `requireScopes`.\n * 3. Run the optional skills policy hook.\n * 4. Run the optional pre-call hook.\n * 5. Invoke the user's tool callback.\n * 6. Run the optional post-call hook with the result + duration.\n * 7. Stamp `audit_id` + `verified_did` into the result `_meta.openagent`.\n * 8. On error, run the optional onError hook and re-throw.\n *\n * Implementation note — version pinning:\n * The middleware is built against `@modelcontextprotocol/sdk@^1.27.0`.\n * The TypeScript SDK changed its tool registration API between 1.17 and\n * 1.27 (`tool(name, cb, ...)` → `registerTool(name, config, cb)`); both\n * call sites are intercepted here so any 1.x server still works.\n *\n * We deliberately do NOT touch the private `_registeredTools` map. The\n * middleware uses a JavaScript {@link Proxy} so callbacks are wrapped\n * exactly once at registration time, before the SDK's internal\n * request handler ever sees them.\n */\n\nimport {\n AuthorizationDeniedError,\n IdentityVerificationError,\n MissingIdentityError,\n OpenAgentMcpError,\n SkillsPolicyDeniedError,\n} from './errors.js';\nimport {\n Agent,\n AuditedResultMeta,\n ErrorHook,\n OpenAgentMcpConfig,\n OpenAgentRequestIdentity,\n PostCallHook,\n PreCallHook,\n ScopeDeriver,\n SkillsPolicyHook,\n VerifiedIdentity,\n defaultRequireScopes,\n} from './types.js';\nimport { installRequestBoundary } from './request-boundary.js';\n\n/**\n * Minimal McpServer surface used by the middleware. We avoid importing\n * concrete types from `@modelcontextprotocol/sdk` because peer-dep\n * versions vary across host applications and the SDK's own type exports\n * are subject to change. The shape below is the intersection of every\n * `1.x` McpServer release.\n */\nexport interface McpServerLike {\n tool(...args: unknown[]): unknown;\n registerTool(...args: unknown[]): unknown;\n connect?(transport: unknown, ...options: unknown[]): Promise<void>;\n readonly server?: { readonly transport?: unknown };\n}\n\n/**\n * Names of methods on the underlying server that take a tool callback as\n * one of their arguments. Both APIs are intercepted; if the SDK adds new\n * registration methods, append to this list.\n */\nconst TOOL_REGISTRATION_METHODS = ['tool', 'registerTool'] as const;\n\ntype ToolRegistrationMethod = (typeof TOOL_REGISTRATION_METHODS)[number];\n\n/**\n * Wrap an MCP server so every tool call is authenticated against an\n * OpenAgent identity.\n *\n * @example\n * ```ts\n * import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n * import { withOpenAgent } from '@openagentid/mcp';\n * import { agent } from './my-agent.js';\n *\n * const server = new McpServer({ name: 'my-tools', version: '0.1.0' });\n * const authedServer = withOpenAgent(server, { agent });\n *\n * authedServer.tool('search_web', searchHandler);\n * ```\n *\n * The returned proxy is type-compatible with the underlying server, so\n * existing code that calls `tool()`, `registerTool()`, `connect()`, etc.\n * keeps working without changes.\n */\nexport function withOpenAgent<T extends McpServerLike>(\n server: T,\n config: OpenAgentMcpConfig,\n): T {\n validateConfig(config);\n const middleware = new ToolMiddleware(config, installRequestBoundary(server));\n\n return new Proxy(server, {\n get(target, property, receiver) {\n const value = Reflect.get(target, property, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n if (\n typeof property === 'string' &&\n TOOL_REGISTRATION_METHODS.includes(property as ToolRegistrationMethod)\n ) {\n return wrapRegistrationMethod(\n value as (...args: unknown[]) => unknown,\n target,\n middleware,\n );\n }\n // Bind methods so `this` stays correct when destructured.\n return value.bind(target);\n },\n }) as T;\n}\n\nfunction validateConfig(config: OpenAgentMcpConfig): void {\n if (config === null || typeof config !== 'object') {\n throw new TypeError('OpenAgentMcpConfig must be an object');\n }\n if (config.agent === undefined || config.agent === null) {\n throw new TypeError('OpenAgentMcpConfig.agent is required');\n }\n if (\n config.agent.verifier === undefined ||\n typeof config.agent.verifier.verify !== 'function'\n ) {\n throw new TypeError('OpenAgentMcpConfig.agent.verifier.verify is required');\n }\n}\n\n/**\n * Wrap a single registration method so the user-supplied callback gets\n * replaced by an auth-wrapped one. The MCP SDK accepts the callback in\n * different positional slots depending on overload — we walk the args\n * list and replace the FIRST function we find. This is the same approach\n * the SDK itself uses internally.\n */\nfunction wrapRegistrationMethod(\n original: (...args: unknown[]) => unknown,\n thisArg: unknown,\n middleware: ToolMiddleware,\n): (...args: unknown[]) => unknown {\n return function wrapped(this: unknown, ...args: unknown[]): unknown {\n const toolName = extractToolName(args);\n const callbackIndex = findCallbackIndex(args);\n if (callbackIndex === -1) {\n // No callback in the args — defensive: forward as-is so we don't\n // mask SDK-level errors that the host would otherwise see.\n return original.apply(thisArg, args);\n }\n const userCallback = args[callbackIndex] as (\n ...callbackArgs: unknown[]\n ) => unknown;\n const wrappedCallback = middleware.wrap(toolName, userCallback);\n const newArgs = [...args];\n newArgs[callbackIndex] = wrappedCallback;\n return original.apply(thisArg, newArgs);\n };\n}\n\nfunction extractToolName(args: ReadonlyArray<unknown>): string {\n if (args.length > 0 && typeof args[0] === 'string') {\n return args[0];\n }\n // registerTool's first arg is also a string in 1.27, so this should\n // never trigger — kept as a safety net.\n return '<unknown>';\n}\n\nfunction findCallbackIndex(args: ReadonlyArray<unknown>): number {\n // Walk the args from the end so we find the LAST function — that's\n // the tool body in every overload of both `tool()` and\n // `registerTool()`.\n for (let i = args.length - 1; i >= 0; i -= 1) {\n if (typeof args[i] === 'function') {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Holds the middleware configuration and wraps individual tool callbacks.\n */\nclass ToolMiddleware {\n private readonly agent: Pick<Agent, 'did' | 'verifier'>;\n private readonly requireScopes: ScopeDeriver;\n private readonly requireIdentity: boolean;\n private readonly skillsPolicy: SkillsPolicyHook | undefined;\n private readonly preCall: PreCallHook | undefined;\n private readonly postCall: PostCallHook | undefined;\n private readonly onError: ErrorHook | undefined;\n\n constructor(config: OpenAgentMcpConfig, private readonly requests: ReturnType<typeof installRequestBoundary>) {\n this.agent = config.agent;\n this.requireScopes = config.requireScopes ?? (config.scopeFormat ? tool => [config.scopeFormat!(tool)] : defaultRequireScopes);\n this.requireIdentity = config.requireIdentity ?? true;\n this.skillsPolicy = config.skillsPolicy;\n this.preCall = config.preCall;\n this.postCall = config.postCall;\n this.onError = config.onError;\n }\n\n wrap(\n toolName: string,\n userCallback: (...args: unknown[]) => unknown,\n ): (...args: unknown[]) => Promise<unknown> {\n const middleware = this;\n return async function wrappedCallback(\n this: unknown,\n ...callbackArgs: unknown[]\n ): Promise<unknown> {\n // The MCP SDK invokes tool callbacks in two shapes depending on\n // whether the tool has an input schema:\n // (extra) — no schema\n // (args, extra) — with schema\n // The `extra` is always the LAST arg.\n const { args, extra } = splitToolArgs(callbackArgs);\n const startedAt = nowMs();\n let identity: VerifiedIdentity | null = null;\n\n try {\n identity = await middleware.runAuthPipeline(toolName, args, extra);\n\n if (middleware.preCall !== undefined) {\n await middleware.preCall({ toolName, args, identity });\n }\n\n const result = await Promise.resolve(\n userCallback.apply(this, callbackArgs),\n );\n\n const stamped = stampAuditMeta(result, identity);\n\n if (middleware.postCall !== undefined) {\n await middleware.postCall({\n toolName,\n args,\n identity,\n durationMs: nowMs() - startedAt,\n result: stamped,\n });\n }\n return stamped;\n } catch (error: unknown) {\n if (middleware.onError !== undefined) {\n // The error hook MUST NOT throw — if it does, swallow so the\n // original error propagates to the caller intact.\n try {\n await middleware.onError({ toolName, args, identity, error });\n } catch {\n /* intentionally ignored */\n }\n }\n throw normalizeError(error);\n }\n };\n }\n\n private async runAuthPipeline(\n toolName: string,\n args: unknown,\n extra: unknown,\n ): Promise<VerifiedIdentity> {\n const identityEnvelope = extractIdentityEnvelope(extra);\n if (identityEnvelope === null) {\n if (this.requireIdentity) {\n throw new MissingIdentityError(toolName);\n }\n // Permissive mode: synthesize an \"anonymous\" identity so hooks\n // still run with a stable shape.\n return ANONYMOUS_IDENTITY;\n }\n\n const requiredScopes = this.requireScopes(toolName, args);\n let identity: VerifiedIdentity;\n try {\n // Identity binds the original transmitted request. Authorization policies\n // and tool callbacks intentionally use the SDK's parsed/effective arguments.\n const inbound = this.requests.getStore();\n if (inbound && inbound.toolName !== toolName) throw new Error('MCP request/tool binding mismatch');\n identity = await this.agent.verifier.verify(\n identityEnvelope,\n requiredScopes,\n inbound ?? { toolName, args },\n );\n } catch (cause: unknown) {\n throw new IdentityVerificationError(toolName, cause);\n }\n\n enforceScopes(toolName, requiredScopes, identity.scopes);\n\n if (this.skillsPolicy !== undefined) {\n const decision = await Promise.resolve(\n this.skillsPolicy({ toolName, args, identity }),\n );\n if (!decision.allow) {\n throw new SkillsPolicyDeniedError(toolName, decision.reason);\n }\n }\n\n return identity;\n }\n}\n\nfunction enforceScopes(\n toolName: string,\n required: ReadonlyArray<string>,\n held: ReadonlyArray<string>,\n): void {\n const missing = required.filter((scope) => !held.includes(scope));\n if (missing.length > 0) {\n throw new AuthorizationDeniedError(toolName, required, held);\n }\n}\n\nfunction splitToolArgs(callbackArgs: ReadonlyArray<unknown>): {\n args: unknown;\n extra: unknown;\n} {\n if (callbackArgs.length === 0) {\n return { args: undefined, extra: undefined };\n }\n if (callbackArgs.length === 1) {\n // Single argument is the `extra` object.\n return { args: undefined, extra: callbackArgs[0] };\n }\n return {\n args: callbackArgs[0],\n extra: callbackArgs[callbackArgs.length - 1],\n };\n}\n\nfunction extractIdentityEnvelope(\n extra: unknown,\n): OpenAgentRequestIdentity | null {\n if (extra === null || typeof extra !== 'object') {\n return null;\n }\n const meta = (extra as { _meta?: unknown })._meta;\n if (meta === null || typeof meta !== 'object') {\n return null;\n }\n const openAgent = (meta as { openagent?: unknown }).openagent;\n if (openAgent === null || typeof openAgent !== 'object') {\n return null;\n }\n const identity = (openAgent as { identity?: unknown }).identity;\n if (identity === null || typeof identity !== 'object') {\n return null;\n }\n const candidate = identity as Record<string, unknown>;\n if (\n typeof candidate['did'] !== 'string' ||\n typeof candidate['proof'] !== 'string'\n ) {\n return null;\n }\n const envelope: OpenAgentRequestIdentity = {\n did: candidate['did'],\n proof: candidate['proof'],\n };\n if (typeof candidate['nonce'] === 'string') {\n envelope.nonce = candidate['nonce'];\n }\n if (\n typeof candidate['context'] === 'object' &&\n candidate['context'] !== null\n ) {\n envelope.context = candidate['context'] as Record<string, unknown>;\n }\n return envelope;\n}\n\nfunction stampAuditMeta(result: unknown, identity: VerifiedIdentity): unknown {\n if (result === null || typeof result !== 'object') {\n return result;\n }\n const auditMeta: AuditedResultMeta = {\n audit_id: identity.auditId,\n verified_did: identity.did,\n scopes: identity.scopes,\n };\n const existingMeta =\n typeof (result as { _meta?: unknown })._meta === 'object' &&\n (result as { _meta?: unknown })._meta !== null\n ? ((result as { _meta: Record<string, unknown> })._meta)\n : {};\n return {\n ...(result as Record<string, unknown>),\n _meta: {\n ...existingMeta,\n openagent: auditMeta,\n },\n };\n}\n\nfunction normalizeError(error: unknown): unknown {\n if (error instanceof OpenAgentMcpError) {\n // Surface the JSON-RPC code on the error so the SDK's error\n // serializer picks it up.\n const jsonRpc = error.toJsonRpcError();\n Object.assign(error, { code: jsonRpc.code, data: jsonRpc.data });\n }\n return error;\n}\n\nfunction nowMs(): number {\n if (\n typeof performance !== 'undefined' &&\n typeof performance.now === 'function'\n ) {\n return performance.now();\n }\n return Date.now();\n}\n\nconst ANONYMOUS_IDENTITY: VerifiedIdentity = {\n did: 'did:oas:anonymous',\n scopes: [],\n auditId: 'anonymous',\n claims: {},\n};\n\nexport { ANONYMOUS_IDENTITY };\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAkMO,IAAM,kBAAA,GAAqB,CAAC,QAAA,KACjC,CAAA,IAAA,EAAO,QAAQ,CAAA,OAAA;AAMV,IAAM,uBAAuB,CAAC,QAAA,KACnC,CAAC,kBAAA,CAAmB,QAAQ,CAAC","file":"types.cjs","sourcesContent":["/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * The real `@openagentid/sdk` exports types that are structurally compatible\n * with these — there is no runtime dependency.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * The verifier interface — implemented by `@openagentid/sdk` (production) and\n * by the in-memory test agent shipped here.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Agent;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n"]}
1
+ {"version":3,"sources":["../src/types.ts"],"names":[],"mappings":";;;AAqMO,IAAM,kBAAA,GAAqB,CAAC,QAAA,KACjC,CAAA,IAAA,EAAO,QAAQ,CAAA,OAAA;AAMV,IAAM,uBAAuB,CAAC,QAAA,KACnC,CAAC,kBAAA,CAAmB,QAAQ,CAAC","file":"types.cjs","sourcesContent":["/**\n * Public types for @openagentid/mcp.\n *\n * These interfaces describe the contract the middleware expects from an\n * OpenAgent {@link Agent} instance and the surrounding configuration. They are\n * defined locally so the package can be installed without `@openagentid/sdk` in\n * tests, in CI, and in environments where the host application brings its own\n * verifier implementation.\n *\n * Use the workspace adapters for the current SDK. These interfaces also\n * support applications that supply their own signing and verification authority.\n */\n\n/**\n * A decentralized identifier following the `did:oas:*` method or any other\n * DID method understood by the configured verifier.\n */\nexport type Did = string;\n\n/**\n * The four pieces of metadata an MCP request carries about the calling\n * agent. Populated by the {@link createClientInterceptor} on the call site\n * and consumed by the server middleware.\n */\nexport interface OpenAgentRequestIdentity {\n /** Caller's DID — typically `did:oas:...`. */\n did: Did;\n /**\n * A signed challenge response or capability token (Arsenal ACT) the\n * server can verify offline. Format is opaque to the middleware.\n */\n proof: string;\n /**\n * Optional bearer-style nonce. Servers may require it for replay\n * protection. Verifiers MUST treat the value as untrusted until\n * verification succeeds.\n */\n nonce?: string;\n /**\n * Free-form context the verifier may use (issuer DID, audience, scopes\n * the caller claims). Always validated against the verifier's policy.\n */\n context?: Record<string, unknown>;\n}\n\n/**\n * The result of running the auth pipeline against an incoming MCP request.\n * Available to post-call hooks and audit log emitters.\n */\nexport interface VerifiedIdentity {\n did: Did;\n scopes: ReadonlyArray<string>;\n /** Audit identifier echoed back to the caller in result `_meta`. */\n auditId: string;\n /** Verifier-issued claims about the caller. */\n claims: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Verifier adapter contract — supplied by createWorkspaceMcpServer or an\n * application-owned identity authority.\n *\n * Implementations MUST be deterministic for a given input and MUST NOT\n * mutate the request identity object.\n */\nexport interface IdentityVerifier {\n verify(\n identity: OpenAgentRequestIdentity,\n requiredScopes: ReadonlyArray<string>,\n /** Original wire arguments before tool schema defaults/transforms; scopes are derived from parsed arguments. */\n request?: { toolName: string; args: unknown },\n ): Promise<VerifiedIdentity>;\n}\n\n/**\n * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that\n * the MCP middleware actually needs.\n */\nexport interface Agent {\n did: Did;\n verifier: IdentityVerifier;\n /**\n * Sign an outbound MCP call so the receiving server can verify the\n * caller. Returns the identity envelope to attach as `_meta.openagent`.\n */\n signRequest(\n toolName: string,\n audience?: Did,\n args?: Record<string, unknown>,\n ): Promise<OpenAgentRequestIdentity>;\n}\n\n/**\n * Result envelope returned by an authenticated tool call. The `auditId` is\n * pushed into `_meta.openagent.audit_id` on the response, so callers can\n * correlate logs end-to-end.\n */\nexport interface AuditedResultMeta {\n audit_id: string;\n verified_did: Did;\n scopes: ReadonlyArray<string>;\n}\n\n/** Per-tool scope deriver. */\nexport type ScopeDeriver = (\n toolName: string,\n args: unknown,\n) => ReadonlyArray<string>;\n\n/**\n * Hook signature for the skills policy. The hook receives the tool name,\n * the arguments, and the verified identity, and decides whether the call\n * should be allowed.\n */\nexport type SkillsPolicyHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<SkillsPolicyDecision> | SkillsPolicyDecision;\n\nexport interface SkillsPolicyDecision {\n allow: boolean;\n reason?: string;\n}\n\n/**\n * Hook fired before a tool body executes — after the identity has been\n * verified and the skills policy has approved the call.\n */\nexport type PreCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n}) => Promise<void> | void;\n\n/**\n * Hook fired after a tool body executes successfully. Use it for audit\n * logging, metrics, and trace propagation. Throwing from this hook does\n * NOT roll back the tool call.\n */\nexport type PostCallHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity;\n durationMs: number;\n result: unknown;\n}) => Promise<void> | void;\n\n/**\n * Hook fired when the tool body or any earlier middleware step throws.\n * The middleware re-throws the error after running this hook so MCP\n * clients still observe the original failure mode.\n */\nexport type ErrorHook = (input: {\n toolName: string;\n args: unknown;\n identity: VerifiedIdentity | null;\n error: unknown;\n}) => Promise<void> | void;\n\n/**\n * Configuration for {@link withOpenAgent}.\n */\nexport interface OpenAgentMcpConfig {\n /** The agent that owns this MCP server (used for outbound signing). */\n agent: Pick<Agent, 'did' | 'verifier'>;\n /**\n * Per-tool required scope set. Defaults to\n * `(toolName) => [`mcp:${toolName}:invoke`]`.\n */\n requireScopes?: ScopeDeriver;\n /**\n * If true (default), tool calls without an `_meta.openagent.identity`\n * envelope are rejected. Set to false to opt-in to permissive mode for\n * local development — the middleware will still run hooks but skip\n * verification.\n */\n requireIdentity?: boolean;\n /** Optional skills policy hook. */\n skillsPolicy?: SkillsPolicyHook;\n /** Optional pre-call hook. */\n preCall?: PreCallHook;\n /** Optional post-call hook for audit/log emission. */\n postCall?: PostCallHook;\n /** Optional error hook. */\n onError?: ErrorHook;\n /**\n * Override the default `mcp:<tool>:invoke` scope format. Receives the\n * tool name and returns the canonical scope string.\n */\n scopeFormat?: (toolName: string) => string;\n}\n\n/**\n * Default scope format used when {@link OpenAgentMcpConfig.scopeFormat} is\n * not supplied.\n */\nexport const defaultScopeFormat = (toolName: string): string =>\n `mcp:${toolName}:invoke`;\n\n/**\n * Default scope deriver used when {@link OpenAgentMcpConfig.requireScopes}\n * is not supplied.\n */\nexport const defaultRequireScopes = (toolName: string): ReadonlyArray<string> =>\n [defaultScopeFormat(toolName)];\n"]}
package/dist/types.d.cts CHANGED
@@ -7,8 +7,8 @@
7
7
  * tests, in CI, and in environments where the host application brings its own
8
8
  * verifier implementation.
9
9
  *
10
- * The real `@openagentid/sdk` exports types that are structurally compatible
11
- * with these — there is no runtime dependency.
10
+ * Use the workspace adapters for the current SDK. These interfaces also
11
+ * support applications that supply their own signing and verification authority.
12
12
  */
13
13
  /**
14
14
  * A decentralized identifier following the `did:oas:*` method or any other
@@ -53,14 +53,19 @@ interface VerifiedIdentity {
53
53
  claims: Readonly<Record<string, unknown>>;
54
54
  }
55
55
  /**
56
- * The verifier interface — implemented by `@openagentid/sdk` (production) and
57
- * by the in-memory test agent shipped here.
56
+ * Verifier adapter contract — supplied by createWorkspaceMcpServer or an
57
+ * application-owned identity authority.
58
58
  *
59
59
  * Implementations MUST be deterministic for a given input and MUST NOT
60
60
  * mutate the request identity object.
61
61
  */
62
62
  interface IdentityVerifier {
63
- verify(identity: OpenAgentRequestIdentity, requiredScopes: ReadonlyArray<string>): Promise<VerifiedIdentity>;
63
+ verify(identity: OpenAgentRequestIdentity, requiredScopes: ReadonlyArray<string>,
64
+ /** Original wire arguments before tool schema defaults/transforms; scopes are derived from parsed arguments. */
65
+ request?: {
66
+ toolName: string;
67
+ args: unknown;
68
+ }): Promise<VerifiedIdentity>;
64
69
  }
65
70
  /**
66
71
  * Minimal Agent surface — only the parts of the OpenAgent SDK Agent that
@@ -73,7 +78,7 @@ interface Agent {
73
78
  * Sign an outbound MCP call so the receiving server can verify the
74
79
  * caller. Returns the identity envelope to attach as `_meta.openagent`.
75
80
  */
76
- signRequest(toolName: string, audience?: Did): Promise<OpenAgentRequestIdentity>;
81
+ signRequest(toolName: string, audience?: Did, args?: Record<string, unknown>): Promise<OpenAgentRequestIdentity>;
77
82
  }
78
83
  /**
79
84
  * Result envelope returned by an authenticated tool call. The `auditId` is
@@ -138,7 +143,7 @@ type ErrorHook = (input: {
138
143
  */
139
144
  interface OpenAgentMcpConfig {
140
145
  /** The agent that owns this MCP server (used for outbound signing). */
141
- agent: Agent;
146
+ agent: Pick<Agent, 'did' | 'verifier'>;
142
147
  /**
143
148
  * Per-tool required scope set. Defaults to
144
149
  * `(toolName) => [`mcp:${toolName}:invoke`]`.