@agentwares/agentguard 0.1.7 → 0.1.10
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.
- package/CHANGELOG.md +108 -0
- package/README.md +223 -16
- package/dist/audit-5LUDXZLG.js +18 -0
- package/dist/audit-5LUDXZLG.js.map +1 -0
- package/dist/chunk-2QDPPTPY.js +179 -0
- package/dist/chunk-2QDPPTPY.js.map +1 -0
- package/dist/chunk-4WTFMFRY.js +1270 -0
- package/dist/chunk-4WTFMFRY.js.map +1 -0
- package/dist/chunk-5WRI5ZAA.js +31 -0
- package/dist/chunk-5WRI5ZAA.js.map +1 -0
- package/dist/chunk-DEVXG3IB.js +113 -0
- package/dist/chunk-DEVXG3IB.js.map +1 -0
- package/dist/chunk-F73VDY3W.js +202 -0
- package/dist/chunk-F73VDY3W.js.map +1 -0
- package/dist/chunk-IEJK7N3B.js +275 -0
- package/dist/chunk-IEJK7N3B.js.map +1 -0
- package/dist/chunk-IS3DAHZI.js +1698 -0
- package/dist/chunk-IS3DAHZI.js.map +1 -0
- package/dist/chunk-JSELR4SG.js +780 -0
- package/dist/chunk-JSELR4SG.js.map +1 -0
- package/dist/chunk-OM5L7A32.js +199 -0
- package/dist/chunk-OM5L7A32.js.map +1 -0
- package/dist/chunk-SWZQMPDG.js +206 -0
- package/dist/chunk-SWZQMPDG.js.map +1 -0
- package/dist/chunk-TJXZBOHL.js +529 -0
- package/dist/chunk-TJXZBOHL.js.map +1 -0
- package/dist/chunk-XOBFANL4.js +119 -0
- package/dist/chunk-XOBFANL4.js.map +1 -0
- package/dist/chunk-XPNBYSIN.js +23 -0
- package/dist/chunk-XPNBYSIN.js.map +1 -0
- package/dist/chunk-YBVD6HTT.js +1036 -0
- package/dist/chunk-YBVD6HTT.js.map +1 -0
- package/dist/chunk-ZG4LGUJE.js +847 -0
- package/dist/chunk-ZG4LGUJE.js.map +1 -0
- package/dist/cli.js +10 -4775
- package/dist/cli.js.map +1 -1
- package/dist/fixtures/crm-server.js +6 -1272
- package/dist/fixtures/crm-server.js.map +1 -1
- package/dist/fixtures/demo-agent.js +4 -115
- package/dist/fixtures/demo-agent.js.map +1 -1
- package/dist/index.d.ts +73 -14
- package/dist/index.js +247 -5138
- package/dist/index.js.map +1 -1
- package/dist/init-MKPQU2JG.js +17 -0
- package/dist/init-MKPQU2JG.js.map +1 -0
- package/dist/proxy-6GP63TLD.js +146 -0
- package/dist/proxy-6GP63TLD.js.map +1 -0
- package/dist/tools-XS7PMTLT.js +15 -0
- package/dist/tools-XS7PMTLT.js.map +1 -0
- package/llms.txt +10 -4
- package/package.json +16 -4
- package/server.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/mcp-kit/src/errors.ts","../../../packages/mcp-kit/src/tool.ts","../../../packages/mcp-kit/src/conformance-fixtures.ts","../../../packages/mcp-kit/src/payment.ts","../../../packages/mcp-kit/src/example.ts","../../../packages/mcp-kit/src/modern.ts","../../../packages/mcp-kit/src/server.ts","../../../packages/mcp-kit/src/http.ts","../../../packages/mcp-kit/src/node-http.ts","../../../packages/x402/src/facilitator.ts","../../../packages/x402/src/index.ts","../../../packages/mcp-kit/src/paging.ts","../../../packages/mcp-kit/src/stdio.ts","../../../packages/mcp-kit/src/registry.ts","../../../packages/mcp-kit/src/docs.ts","../../../packages/mcp-kit/src/discovery.ts"],"sourcesContent":["/**\n * Structured tool errors. Every error an agent sees carries `code`, `cause`, `fix` and\n * `retryable` (CLAUDE.md \"Writing for agents\") so the caller can decide what to do next\n * without reading prose.\n */\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\n\n/** Standard error codes. Products may add their own (e.g. `MONITOR_PAUSED`). */\nexport const ERROR_CODES = [\n \"INVALID_INPUT\",\n \"NOT_FOUND\",\n \"UNAUTHORIZED\",\n \"PAYMENT_REQUIRED\",\n \"RATE_LIMITED\",\n \"UPSTREAM_ERROR\",\n \"INTERNAL\",\n] as const;\n\nexport type StandardErrorCode = (typeof ERROR_CODES)[number];\n/** A standard code, or a product-specific UPPER_SNAKE code. */\nexport type ErrorCode = StandardErrorCode | (string & Record<never, never>);\n\n/** Wire shape of every error body (tool result text, structuredContent and HTTP JSON alike). */\nexport type ToolErrorBody = {\n code: string;\n /** what went wrong, in one sentence */\n cause: string;\n /** what the caller should do next */\n fix: string;\n /** whether the same call can succeed on retry without changes */\n retryable: boolean;\n /** machine-readable specifics, e.g. validation issues */\n details?: unknown;\n [extra: string]: unknown;\n};\n\nexport interface ToolErrorInit {\n code: ErrorCode;\n cause: string;\n fix: string;\n /** Defaults per code: PAYMENT_REQUIRED, RATE_LIMITED, UPSTREAM_ERROR are retryable; the rest are not. */\n retryable?: boolean;\n details?: unknown;\n /** HTTP status to use when the error is surfaced over plain HTTP. Defaults per code. */\n httpStatus?: number;\n /** Extra top-level fields merged into the serialized body (e.g. a 402's `accepts`). */\n extra?: Record<string, unknown>;\n}\n\nexport const DEFAULT_RETRYABLE: Readonly<Record<StandardErrorCode, boolean>> = {\n INVALID_INPUT: false,\n NOT_FOUND: false,\n UNAUTHORIZED: false,\n PAYMENT_REQUIRED: true,\n RATE_LIMITED: true,\n UPSTREAM_ERROR: true,\n INTERNAL: false,\n};\n\nexport const DEFAULT_HTTP_STATUS: Readonly<Record<StandardErrorCode, number>> = {\n INVALID_INPUT: 400,\n NOT_FOUND: 404,\n UNAUTHORIZED: 401,\n PAYMENT_REQUIRED: 402,\n RATE_LIMITED: 429,\n UPSTREAM_ERROR: 502,\n INTERNAL: 500,\n};\n\nexport const INTERNAL_FIX = \"retry; if it persists, report the request id\";\n\nfunction isStandardCode(code: string): code is StandardErrorCode {\n return (ERROR_CODES as readonly string[]).includes(code);\n}\n\n/** Throw this (or `toolError(...)`) from a handler to return a structured error to the caller. */\nexport class McpToolError extends Error {\n readonly code: string;\n override readonly cause: string;\n readonly fix: string;\n readonly retryable: boolean;\n readonly details?: unknown;\n readonly httpStatus: number;\n readonly extra?: Record<string, unknown>;\n\n constructor(init: ToolErrorInit) {\n super(`${init.code}: ${init.cause}`);\n this.name = \"McpToolError\";\n this.code = init.code;\n this.cause = init.cause;\n this.fix = init.fix;\n this.retryable =\n init.retryable ?? (isStandardCode(init.code) ? DEFAULT_RETRYABLE[init.code] : false);\n this.details = init.details;\n this.httpStatus =\n init.httpStatus ?? (isStandardCode(init.code) ? DEFAULT_HTTP_STATUS[init.code] : 500);\n this.extra = init.extra;\n }\n\n /** The body agents see: `{ code, cause, fix, retryable, details?, ...extra }`. */\n toJSON(): ToolErrorBody {\n const body: ToolErrorBody = {\n ...this.extra,\n code: this.code,\n cause: this.cause,\n fix: this.fix,\n retryable: this.retryable,\n };\n if (this.details !== undefined) body.details = this.details;\n return body;\n }\n}\n\n/** Build a structured error. Object form or `(code, cause, fix, extra?)`. */\nexport function toolError(init: ToolErrorInit): McpToolError;\nexport function toolError(\n code: ErrorCode,\n cause: string,\n fix: string,\n extra?: Omit<ToolErrorInit, \"code\" | \"cause\" | \"fix\">,\n): McpToolError;\nexport function toolError(\n codeOrInit: ErrorCode | ToolErrorInit,\n cause?: string,\n fix?: string,\n extra?: Omit<ToolErrorInit, \"code\" | \"cause\" | \"fix\">,\n): McpToolError {\n if (typeof codeOrInit === \"object\") return new McpToolError(codeOrInit);\n return new McpToolError({ code: codeOrInit, cause: cause ?? \"\", fix: fix ?? \"\", ...extra });\n}\n\nfunction describeUnknown(err: unknown): string {\n if (err instanceof Error) return err.message || err.name;\n if (typeof err === \"string\") return err;\n try {\n return JSON.stringify(err);\n } catch {\n return String(err);\n }\n}\n\n/** Coerce anything thrown into a `McpToolError`. Unknown errors become `INTERNAL`. */\nexport function normalizeError(err: unknown): McpToolError {\n if (err instanceof McpToolError) return err;\n return new McpToolError({\n code: \"INTERNAL\",\n cause: describeUnknown(err),\n fix: INTERNAL_FIX,\n retryable: false,\n });\n}\n\nexport interface ErrorResultOptions {\n /** Echoed in `_meta.requestId` so \"report the request id\" is actionable. */\n requestId?: string;\n /** Merged into `_meta` (always includes `httpStatus`). */\n meta?: Record<string, unknown>;\n}\n\n/**\n * Turn an error into a `CallToolResult` with `isError: true`. `content[0].text` is the JSON\n * body and `structuredContent` is the same object, so both text-only and structured clients\n * see `{ code, cause, fix, retryable }`.\n */\nexport function errorResult(err: unknown, opts: ErrorResultOptions = {}): CallToolResult {\n const error = normalizeError(err);\n const body = error.toJSON();\n const meta: Record<string, unknown> = { httpStatus: error.httpStatus };\n if (opts.requestId !== undefined) meta.requestId = opts.requestId;\n Object.assign(meta, opts.meta);\n return {\n isError: true,\n content: [{ type: \"text\", text: JSON.stringify(body) }],\n structuredContent: body,\n _meta: meta,\n };\n}\n\n/** True when a result is an error result produced by this kit (or shaped like one). */\nexport function isErrorResult(result: CallToolResult): boolean {\n return result.isError === true;\n}\n\n/** Read the `{ code, cause, fix, retryable }` body out of a tool result, if it is an error. */\nexport function readErrorBody(result: CallToolResult): ToolErrorBody | undefined {\n if (result.isError !== true) return undefined;\n const structured = result.structuredContent;\n if (structured && typeof structured.code === \"string\") return structured as ToolErrorBody;\n const first = result.content[0];\n if (first && first.type === \"text\") {\n try {\n const parsed: unknown = JSON.parse(first.text);\n if (parsed && typeof parsed === \"object\" && \"code\" in parsed) return parsed as ToolErrorBody;\n } catch {\n // not JSON\n }\n }\n return undefined;\n}\n","/**\n * `defineTool` — a typed tool definition with a naming lint, zod input validation and\n * structured error results. The same `ToolDef` is served over stdio and Streamable HTTP.\n */\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolResult,\n ServerNotification,\n ServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { z } from \"zod\";\nimport { errorResult, toolError, type McpToolError } from \"./errors.js\";\n\n/** MCP tool annotations (hints for clients; not enforced by servers). */\nexport interface ToolAnnotations {\n title?: string;\n /** the tool does not modify anything */\n readOnlyHint?: boolean;\n /** the tool may perform destructive updates (default true when not read-only) */\n destructiveHint?: boolean;\n /** repeated calls with the same arguments have no additional effect */\n idempotentHint?: boolean;\n /** the tool interacts with external entities (default true) */\n openWorldHint?: boolean;\n}\n\nexport type LogLevel =\n \"debug\" | \"info\" | \"notice\" | \"warning\" | \"error\" | \"critical\" | \"alert\" | \"emergency\";\n\n/** Per-call context handed to handlers. Built from the SDK's `extra` by the server adapter. */\nexport interface ToolContext {\n /** HTTP request headers (empty over stdio). Use for `Authorization`, payment headers, etc. */\n headers: Headers;\n /** JSON-RPC request id (string form) — quote it in error reports. */\n requestId?: string;\n /** aborted when the client cancels the request */\n signal?: AbortSignal;\n /** transport session id, when the transport is stateful */\n sessionId?: string;\n /** true when the caller asked for a free sample (set by `withPayment`) */\n sample?: boolean;\n /** set by `withPayment`'s `authorize` when the caller is a known user */\n userId?: string;\n /**\n * The public URL this call arrived at, when it arrived over HTTP.\n *\n * `withPayment` quotes the tool's *name* as the resource by default, which is right for a\n * stdio MCP call and wrong for everything a payment facilitator does with it: a discovery\n * catalog keyed on `realestate_deal_memo` lists something no agent can fetch. An HTTP front\n * door sets this so settlements are attributed to a URL instead.\n */\n resourceUrl?: string;\n /** the request's `_meta` (e.g. `progressToken`) */\n meta?: Record<string, unknown>;\n /** send a log notification to the client (no-op when the transport cannot deliver it) */\n log?: (level: LogLevel, data: unknown) => Promise<void>;\n /** report progress; no-op unless the caller supplied a progress token */\n progress?: (progress: number, total?: number, message?: string) => Promise<void>;\n /**\n * The raw SDK request context — `sendRequest` for sampling (`sampling/createMessage`) and\n * elicitation (`elicitation/create`), `authInfo`, task helpers. Absent when invoked directly.\n */\n extra?: RequestHandlerExtra<ServerRequest, ServerNotification>;\n}\n\n/** Build a context for calling `tool.invoke` directly (tests, cron jobs, in-process use). */\nexport function createToolContext(init: Partial<ToolContext> = {}): ToolContext {\n const { headers, ...rest } = init;\n return { headers: headers ?? new Headers(), ...rest };\n}\n\nexport type ToolInput<TInput extends z.ZodObject> = z.output<TInput>;\nexport type ToolOutput<TOutput> = TOutput extends z.ZodType ? z.output<TOutput> : unknown;\n\nexport interface ToolDef<\n TInput extends z.ZodObject = z.ZodObject,\n TOutput extends z.ZodType | undefined = z.ZodType | undefined,\n> {\n /** `<namespace>_<verb>_<object>`, e.g. `agentcheck_create_monitor` */\n readonly name: string;\n readonly title?: string;\n /** written for a new teammate: what it does, when to use it, what it returns */\n readonly description: string;\n readonly input: TInput;\n /** when given, handler results are validated against it and returned as `structuredContent` */\n readonly output?: TOutput;\n readonly annotations?: ToolAnnotations;\n /** The business logic. Throw `toolError(...)` for structured errors. */\n handler(\n input: z.output<TInput>,\n ctx: ToolContext,\n ): ToolOutput<TOutput> | Promise<ToolOutput<TOutput>>;\n /** Validate raw input, run the handler and shape the result. Never throws. */\n invoke(rawInput: unknown, ctx: ToolContext): Promise<CallToolResult>;\n}\n\nexport interface DefineToolOptions<\n TInput extends z.ZodObject,\n TOutput extends z.ZodType | undefined,\n> {\n name: string;\n title?: string;\n description: string;\n input: TInput;\n output?: TOutput;\n annotations?: ToolAnnotations;\n handler(\n input: z.output<TInput>,\n ctx: ToolContext,\n ): ToolOutput<TOutput> | Promise<ToolOutput<TOutput>>;\n}\n\n/** `namespace_verb_object`: lowercase, digits, single underscores, at least one underscore. */\nexport const TOOL_NAME_PATTERN = /^[a-z][a-z0-9]*(_[a-z0-9]+)+$/;\nexport const MIN_NAMESPACE_LENGTH = 3;\nexport const MIN_DESCRIPTION_LENGTH = 20;\n\nexport function isValidToolName(name: string): boolean {\n if (!TOOL_NAME_PATTERN.test(name)) return false;\n const namespace = name.split(\"_\")[0] ?? \"\";\n return namespace.length >= MIN_NAMESPACE_LENGTH;\n}\n\n/** Naming lint: throws unless `name` is `<namespace>_<verb>_<object>` with a namespace of 3+ chars. */\nexport function assertToolName(name: string): void {\n if (!isValidToolName(name)) {\n throw new Error(\n `tool name must be namespaced: <namespace>_<verb>_<object>, got ${JSON.stringify(name)}`,\n );\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n/** A handler may return a ready-made `CallToolResult` (e.g. image/audio content blocks). */\nexport function isCallToolResult(value: unknown): value is CallToolResult {\n if (!isPlainObject(value) || !Array.isArray(value.content)) return false;\n return value.content.every(\n (block: unknown) => isPlainObject(block) && typeof block.type === \"string\",\n );\n}\n\n/** Shape a handler's return value into a `CallToolResult`: JSON text plus `structuredContent`. */\nexport function toCallToolResult(value: unknown): CallToolResult {\n if (isCallToolResult(value)) return value;\n const text = typeof value === \"string\" ? value : JSON.stringify(value ?? null, null, 2);\n const result: CallToolResult = { content: [{ type: \"text\", text }] };\n if (isPlainObject(value)) result.structuredContent = value;\n return result;\n}\n\ninterface IssueLike {\n path: PropertyKey[];\n message: string;\n code?: string;\n}\n\nfunction issuePath(issue: IssueLike): string {\n return issue.path.map(String).join(\".\") || \"(root)\";\n}\n\n/** `INVALID_INPUT` with the offending field names in `fix` and the zod issues in `details`. */\nexport function invalidInputError(issues: readonly IssueLike[]): McpToolError {\n const fields = [...new Set(issues.map(issuePath))];\n const summary = issues.map((issue) => `${issuePath(issue)}: ${issue.message}`).join(\"; \");\n return toolError({\n code: \"INVALID_INPUT\",\n cause: `invalid input for ${fields.join(\", \")} — ${summary}`,\n fix: `fix ${fields.join(\", \")} to match the tool's inputSchema (see details.issues), then retry`,\n retryable: false,\n details: {\n fields,\n issues: issues.map((issue) => ({\n path: issue.path.map(String),\n code: issue.code,\n message: issue.message,\n })),\n },\n });\n}\n\n/**\n * Define a tool. Throws at definition time when the name is not namespaced or the description\n * is too short, so mistakes surface at boot rather than in an agent's transcript.\n */\nexport function defineTool<\n TInput extends z.ZodObject,\n TOutput extends z.ZodType | undefined = undefined,\n>(opts: DefineToolOptions<TInput, TOutput>): ToolDef<TInput, TOutput> {\n assertToolName(opts.name);\n if (\n typeof opts.description !== \"string\" ||\n opts.description.trim().length < MIN_DESCRIPTION_LENGTH\n ) {\n throw new Error(\n `tool ${opts.name}: description must be at least ${MIN_DESCRIPTION_LENGTH} characters — say what it does, when to use it and what it returns`,\n );\n }\n const { name, title, description, input, output, annotations } = opts;\n const handler = opts.handler.bind(opts);\n\n const tool: ToolDef<TInput, TOutput> = {\n name,\n title,\n description,\n input,\n output,\n annotations,\n handler,\n async invoke(rawInput, ctx) {\n // The SDK client validates any structuredContent against the advertised outputSchema, even\n // on error results, so tools with an output schema carry the error body in text only.\n const fail = (err: unknown): CallToolResult => {\n const result = errorResult(err, { requestId: ctx.requestId });\n if (output) delete result.structuredContent;\n return result;\n };\n const parsed = input.safeParse(rawInput ?? {});\n if (!parsed.success) return fail(invalidInputError(parsed.error.issues));\n try {\n const value: unknown = await handler(parsed.data, ctx);\n if (output && !isCallToolResult(value)) {\n const checked = output.safeParse(value);\n if (!checked.success) {\n throw toolError({\n code: \"INTERNAL\",\n cause: `tool ${name} returned a value that does not match its output schema — ${checked.error.issues\n .map((issue) => `${issuePath(issue)}: ${issue.message}`)\n .join(\"; \")}`,\n fix: \"this is a bug in the tool, not in your call; report it with the request id\",\n retryable: false,\n details: { issues: checked.error.issues },\n });\n }\n return toCallToolResult(checked.data);\n }\n return toCallToolResult(value);\n } catch (err) {\n return fail(err);\n }\n },\n };\n return tool;\n}\n","/**\n * Fixture tools, resources and prompts with the names and shapes the official conformance\n * suite (`@modelcontextprotocol/conformance`) expects. Add them to any kit server to run\n * `conformance server --url …` against it. Not for production.\n */\nimport { completable } from \"@modelcontextprotocol/sdk/server/completable.js\";\nimport { type McpServer, ResourceTemplate } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n CreateMessageResultSchema,\n ElicitResultSchema,\n SubscribeRequestSchema,\n UnsubscribeRequestSchema,\n type ElicitRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { toolError } from \"./errors.js\";\nimport { defineTool, type ToolContext, type ToolDef } from \"./tool.js\";\n\n/** 1×1 transparent PNG */\nconst PNG_BASE64 =\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\";\n/** 44-byte WAV header, zero samples */\nconst WAV_BASE64 = \"UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=\";\n\nconst STATIC_TEXT_URI = \"test://static-text\";\nconst STATIC_TEXT = \"This is a static text resource for testing.\";\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Form-mode elicitation schema (the params type is a union with URL-mode elicitation). */\ntype RequestedSchema = Extract<\n ElicitRequest[\"params\"],\n { requestedSchema: unknown }\n>[\"requestedSchema\"];\n\nfunction embeddedResource(): {\n type: \"resource\";\n resource: { uri: string; mimeType: string; text: string };\n} {\n return {\n type: \"resource\",\n resource: { uri: STATIC_TEXT_URI, mimeType: \"text/plain\", text: STATIC_TEXT },\n };\n}\n\nfunction requireExtra(ctx: ToolContext): NonNullable<ToolContext[\"extra\"]> {\n if (!ctx.extra) {\n throw toolError(\"INTERNAL\", \"no client connection in this context\", \"call this tool over MCP\");\n }\n return ctx.extra;\n}\n\nasync function elicit(\n ctx: ToolContext,\n message: string,\n requestedSchema: RequestedSchema,\n): Promise<string> {\n const result = await requireExtra(ctx).sendRequest(\n { method: \"elicitation/create\", params: { message, requestedSchema } },\n ElicitResultSchema,\n );\n return `Elicitation completed: action=${result.action}, content=${JSON.stringify(result.content ?? {})}`;\n}\n\n/** The tool fixtures the suite calls by name. */\nexport const conformanceTools: ToolDef[] = [\n defineTool({\n name: \"test_simple_text\",\n description: \"Conformance fixture: returns a fixed simple text response.\",\n input: z.object({}),\n handler: () => \"This is a simple text response for testing.\",\n }),\n defineTool({\n name: \"test_error_handling\",\n description: \"Conformance fixture: always returns an error result (isError: true).\",\n input: z.object({}),\n handler: () => {\n throw toolError({\n code: \"UPSTREAM_ERROR\",\n cause: \"This tool intentionally returns an error for testing\",\n fix: \"nothing to fix; this fixture always fails\",\n retryable: false,\n });\n },\n }),\n defineTool({\n name: \"test_image_content\",\n description: \"Conformance fixture: returns a 1x1 PNG image content block.\",\n input: z.object({}),\n handler: () => ({ content: [{ type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" }] }),\n }),\n defineTool({\n name: \"test_audio_content\",\n description: \"Conformance fixture: returns an empty WAV audio content block.\",\n input: z.object({}),\n handler: () => ({ content: [{ type: \"audio\", data: WAV_BASE64, mimeType: \"audio/wav\" }] }),\n }),\n defineTool({\n name: \"test_embedded_resource\",\n description: \"Conformance fixture: returns an embedded text resource content block.\",\n input: z.object({}),\n handler: () => ({ content: [embeddedResource()] }),\n }),\n defineTool({\n name: \"test_multiple_content_types\",\n description: \"Conformance fixture: returns text, image and resource content blocks together.\",\n input: z.object({}),\n handler: () => ({\n content: [\n { type: \"text\", text: \"Mixed content response\" },\n { type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" },\n embeddedResource(),\n ],\n }),\n }),\n defineTool({\n name: \"test_tool_with_logging\",\n description: \"Conformance fixture: emits three info log notifications while running.\",\n input: z.object({}),\n handler: async (_input, ctx) => {\n await ctx.log?.(\"info\", \"Tool execution started\");\n await sleep(50);\n await ctx.log?.(\"info\", \"Tool processing data\");\n await sleep(50);\n await ctx.log?.(\"info\", \"Tool execution completed\");\n return \"Tool execution completed with logging\";\n },\n }),\n defineTool({\n name: \"test_tool_with_progress\",\n description: \"Conformance fixture: reports progress 0/100, 50/100, 100/100 while running.\",\n input: z.object({}),\n handler: async (_input, ctx) => {\n await ctx.progress?.(0, 100, \"starting\");\n await sleep(50);\n await ctx.progress?.(50, 100, \"halfway\");\n await sleep(50);\n await ctx.progress?.(100, 100, \"done\");\n return \"Tool execution completed with progress\";\n },\n }),\n defineTool({\n name: \"test_sampling\",\n description: \"Conformance fixture: asks the client to sample a completion and returns it.\",\n input: z.object({ prompt: z.string().describe(\"Prompt to send to the client's model\") }),\n handler: async ({ prompt }, ctx) => {\n const result = await requireExtra(ctx).sendRequest(\n {\n method: \"sampling/createMessage\",\n params: {\n messages: [{ role: \"user\", content: { type: \"text\", text: prompt } }],\n maxTokens: 100,\n },\n },\n CreateMessageResultSchema,\n );\n const content = Array.isArray(result.content) ? result.content[0] : result.content;\n const text = content && content.type === \"text\" ? content.text : JSON.stringify(content);\n return `Sampling completed (${result.model}): ${text}`;\n },\n }),\n defineTool({\n name: \"test_elicitation\",\n description: \"Conformance fixture: asks the client for user input and reports the outcome.\",\n input: z.object({ message: z.string().describe(\"Message shown to the user\") }),\n handler: ({ message }, ctx) =>\n elicit(ctx, message, {\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\", description: \"Your name\" },\n email: { type: \"string\", title: \"Email\", format: \"email\" },\n },\n required: [\"name\"],\n }),\n }),\n defineTool({\n name: \"test_elicitation_sep1034_defaults\",\n description: \"Conformance fixture: elicitation schema with defaults for every primitive type.\",\n input: z.object({}),\n handler: (_input, ctx) =>\n elicit(ctx, \"Please confirm your details\", {\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\", default: \"John Doe\" },\n age: { type: \"integer\", title: \"Age\", default: 30 },\n score: { type: \"number\", title: \"Score\", default: 95.5 },\n status: {\n type: \"string\",\n title: \"Status\",\n enum: [\"active\", \"inactive\", \"pending\"],\n default: \"active\",\n },\n verified: { type: \"boolean\", title: \"Verified\", default: true },\n },\n }),\n }),\n defineTool({\n name: \"test_elicitation_sep1330_enums\",\n description:\n \"Conformance fixture: elicitation schema with titled, untitled and multi-select enums.\",\n input: z.object({}),\n handler: (_input, ctx) =>\n elicit(ctx, \"Pick some options\", {\n type: \"object\",\n properties: {\n untitledSingle: {\n type: \"string\",\n title: \"Untitled single\",\n enum: [\"red\", \"green\", \"blue\"],\n },\n titledSingle: {\n type: \"string\",\n title: \"Titled single\",\n oneOf: [\n { const: \"red\", title: \"Red\" },\n { const: \"green\", title: \"Green\" },\n { const: \"blue\", title: \"Blue\" },\n ],\n },\n legacyEnum: {\n type: \"string\",\n title: \"Legacy titled\",\n enum: [\"red\", \"green\", \"blue\"],\n enumNames: [\"Red\", \"Green\", \"Blue\"],\n },\n untitledMulti: {\n type: \"array\",\n title: \"Untitled multi\",\n items: { type: \"string\", enum: [\"red\", \"green\", \"blue\"] },\n },\n titledMulti: {\n type: \"array\",\n title: \"Titled multi\",\n items: {\n anyOf: [\n { const: \"red\", title: \"Red\" },\n { const: \"green\", title: \"Green\" },\n { const: \"blue\", title: \"Blue\" },\n ],\n },\n },\n },\n } as RequestedSchema),\n }),\n defineTool({\n name: \"json_schema_2020_12_tool\",\n description: \"Conformance fixture: input schema with a $defs reference to an address object.\",\n input: z.object({\n name: z.string(),\n address: z.object({ street: z.string(), city: z.string() }).meta({ id: \"address\" }),\n }),\n handler: (input) => input,\n }),\n];\n\n/** Register the resource and prompt fixtures on a kit server (call before connecting). */\nexport function registerConformanceFixtures(server: McpServer): void {\n server.server.registerCapabilities({ resources: { subscribe: true, listChanged: true } });\n\n server.registerResource(\n \"static-text\",\n STATIC_TEXT_URI,\n { title: \"Static text\", description: \"A static text resource\", mimeType: \"text/plain\" },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"text/plain\", text: STATIC_TEXT }] }),\n );\n server.registerResource(\n \"static-binary\",\n \"test://static-binary\",\n { title: \"Static binary\", description: \"A static binary resource\", mimeType: \"image/png\" },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"image/png\", blob: PNG_BASE64 }] }),\n );\n server.registerResource(\n \"watched-resource\",\n \"test://watched-resource\",\n {\n title: \"Watched resource\",\n description: \"Supports subscribe/unsubscribe\",\n mimeType: \"text/plain\",\n },\n async (uri) => ({ contents: [{ uri: uri.href, mimeType: \"text/plain\", text: \"watched\" }] }),\n );\n server.registerResource(\n \"template-data\",\n new ResourceTemplate(\"test://template/{id}/data\", { list: undefined }),\n { title: \"Template data\", description: \"Data for an id\", mimeType: \"text/plain\" },\n async (uri, variables) => ({\n contents: [\n { uri: uri.href, mimeType: \"text/plain\", text: `Data for id ${String(variables.id)}` },\n ],\n }),\n );\n server.server.setRequestHandler(SubscribeRequestSchema, async () => ({}));\n server.server.setRequestHandler(UnsubscribeRequestSchema, async () => ({}));\n\n server.registerPrompt(\n \"test_simple_prompt\",\n { description: \"A simple prompt without arguments\" },\n () => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"This is a simple prompt for testing.\" } },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_arguments\",\n {\n description: \"A prompt with two arguments\",\n argsSchema: {\n arg1: completable(z.string().describe(\"First argument\"), (value) =>\n [\"test\", \"testValue1\", \"testing\"].filter((v) => v.startsWith(value)),\n ),\n arg2: z.string().describe(\"Second argument\"),\n },\n },\n ({ arg1, arg2 }) => ({\n messages: [\n {\n role: \"user\",\n content: { type: \"text\", text: `Prompt with arg1=${arg1} and arg2=${arg2}` },\n },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_embedded_resource\",\n {\n description: \"A prompt that embeds a resource\",\n argsSchema: { resourceUri: z.string().describe(\"URI of the resource to embed\") },\n },\n ({ resourceUri }) => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"Here is the resource:\" } },\n {\n role: \"user\",\n content: {\n type: \"resource\",\n resource: { uri: resourceUri, mimeType: \"text/plain\", text: STATIC_TEXT },\n },\n },\n ],\n }),\n );\n server.registerPrompt(\n \"test_prompt_with_image\",\n { description: \"A prompt that includes an image\" },\n () => ({\n messages: [\n { role: \"user\", content: { type: \"text\", text: \"Describe this image:\" } },\n { role: \"user\", content: { type: \"image\", data: PNG_BASE64, mimeType: \"image/png\" } },\n ],\n }),\n );\n}\n","/**\n * `withPayment` — gate a tool behind a price. Wave 0: nothing is charged; callers without an\n * entitlement get a 402-shaped `PAYMENT_REQUIRED` result advertising both rails (x402 on Base,\n * Stripe MPP) with `comingSoon: true`, and `sample: true` returns an example for free.\n */\nimport {\n StubVerifier,\n buildPaymentRequired,\n type PaymentRequirement,\n paymentRequiredResponse,\n type PaymentRequiredBody,\n type PaymentVerifier,\n type SelfServe,\n type VerifyResult,\n} from \"@agentwares/x402\";\nimport { z } from \"zod\";\nimport { toolError, type McpToolError } from \"./errors.js\";\nimport { defineTool, type ToolContext, type ToolDef } from \"./tool.js\";\n\nexport interface AuthorizeResult {\n ok: boolean;\n userId?: string;\n /** why not, e.g. \"API key revoked\" — surfaced in `details.reason` */\n reason?: string;\n}\n\nexport interface WithPaymentOptions {\n /** price per successful call, in USD (e.g. 0.05) */\n priceUsd: number;\n /** Entitlement check (API key + credits, subscription tier). `ok: true` skips payment. */\n authorize?: (ctx: ToolContext) => Promise<AuthorizeResult> | AuthorizeResult;\n /** Payment verifier for the request headers. Default: `StubVerifier` (never accepts). */\n verifier?: PaymentVerifier;\n /** set once pay-per-call is live (drops `comingSoon`) */\n live?: boolean;\n /** name of the boolean input field that requests a free sample (default `sample`) */\n sampleField?: string;\n /** shown in the payment requirement */\n description?: string;\n /**\n * Discovery metadata for the x402 `bazaar` extension. Advertised in the 402 so a client can\n * echo it back; without that echo the facilitator will not catalog the resource, however\n * many payments settle against it.\n */\n bazaar?: Record<string, unknown>;\n payTo?: string;\n /** prepaid_credits rail: the URL that takes a card and funds a balance */\n creditsPayTo?: string;\n signupUrl?: string;\n /** the no-human purchase path, advertised in the 402 body once the card rail is live */\n selfServe?: SelfServe;\n /**\n * Called when a call that was already paid for then fails. A verifier that charges up\n * front (the prepaid wallet does) uses this to give the money back, so a caller is never\n * billed for an error. `receipt` is whatever the verifier returned.\n */\n onPaidFailure?: (\n ctx: ToolContext,\n verified: VerifyResult,\n error: unknown,\n ) => Promise<void> | void;\n /**\n * The paid work succeeded but the money did not arrive — an on-chain settlement that was\n * refused or a facilitator that went away. Never throw from here: the buyer has a valid\n * result and this is our accounting problem, not their failed request.\n */\n onSettlementFailure?: (ctx: ToolContext, verified: VerifyResult, reason?: string) => void;\n}\n\n/** A `McpToolError` whose body is the x402 `PaymentRequiredBody` (code `PAYMENT_REQUIRED`). */\nexport function paymentRequiredError(body: PaymentRequiredBody, reason?: string): McpToolError {\n const { code, cause, fix, retryable, ...rest } = body;\n return toolError({\n code,\n cause,\n fix,\n retryable,\n httpStatus: 402,\n details: reason !== undefined ? { reason } : undefined,\n extra: rest,\n });\n}\n\nfunction formatUsd(priceUsd: number): string {\n return priceUsd\n .toFixed(6)\n .replace(/0+$/, \"\")\n .replace(/\\.$/, \".00\")\n .replace(/\\.(\\d)$/, \".$10\");\n}\n\n/**\n * Wrap a tool so it requires an entitlement or payment. The returned tool has the same name,\n * schema and output, plus an optional boolean `sample` input (default false) documented as\n * \"return an example response at no charge\".\n *\n * Flow per call: `sample` → handler with `ctx.sample = true`; else `authorize` ok → handler\n * (with `ctx.userId`); else verifier accepts the request's payment headers → handler; else a\n * `PAYMENT_REQUIRED` error result (`_meta.httpStatus: 402`).\n */\nexport function withPayment(tool: ToolDef, opts: WithPaymentOptions): ToolDef {\n if (!Number.isFinite(opts.priceUsd) || opts.priceUsd < 0) {\n throw new Error(`withPayment(${tool.name}): priceUsd must be a non-negative number`);\n }\n const sampleField = opts.sampleField ?? \"sample\";\n if (sampleField in tool.input.shape) {\n throw new Error(\n `withPayment(${tool.name}): input already has a field named ${JSON.stringify(sampleField)}; pass sampleField to rename it`,\n );\n }\n const verifier: PaymentVerifier = opts.verifier ?? new StubVerifier();\n // A verifier that was configured is a rail that can actually be settled, so when it refuses\n // it knows why (\"insufficient credit: $0.00 available, $0.75 needed\") and its reason is the\n // one the caller can act on. Without one, `authorize`'s reason is all there is.\n const liveRail = opts.verifier !== undefined;\n const input = tool.input.extend({\n [sampleField]: z\n .boolean()\n .default(false)\n .describe(\n \"Set true to return an example response at no charge (sample mode). Default false.\",\n ),\n });\n const description = `${tool.description.trim()} Paid: $${formatUsd(opts.priceUsd)} per call; without credit you get a PAYMENT_REQUIRED result. Set ${sampleField}=true for a free example response.`;\n\n return defineTool({\n name: tool.name,\n title: tool.title,\n description,\n input,\n output: tool.output,\n annotations: tool.annotations,\n async handler(raw, ctx) {\n const record: Record<string, unknown> = { ...raw };\n const sample = record[sampleField] === true;\n delete record[sampleField];\n\n if (sample) return tool.handler(record, { ...ctx, sample: true });\n\n let reason: string | undefined;\n if (opts.authorize) {\n const auth = await opts.authorize(ctx);\n if (auth.ok) return tool.handler(record, { ...ctx, userId: auth.userId });\n reason = auth.reason;\n }\n\n // A tool name is not a resource. Over HTTP the front door knows the real URL and puts\n // it on the context; over stdio there is no URL and the name is the best there is.\n const resource = ctx.resourceUrl ?? tool.name;\n const required = buildPaymentRequired({\n resource,\n priceUsd: opts.priceUsd,\n live: opts.live,\n description: opts.description,\n payTo: opts.payTo,\n creditsPayTo: opts.creditsPayTo,\n signupUrl: opts.signupUrl,\n selfServe: opts.selfServe,\n // withPayment always adds a free `sample` flag to the tool's input schema\n sampleMode: true,\n ...(opts.bazaar ? { bazaar: opts.bazaar } : {}),\n });\n // What we advertise and what we accept are separate questions. `accepts` only lists\n // rails a caller could actually settle, and is empty when none is configured — but a\n // caller may still present credit or a payment header, so the verifier always runs.\n // The card rail is checked first because it is the one that can be settled today.\n const advertised =\n required.body.accepts.find((a) => a.rail === \"prepaid_credits\") ?? required.body.accepts[0];\n const requirement: PaymentRequirement = advertised ?? {\n rail: \"prepaid_credits\",\n amountUsd: String(required.body.priceUsd),\n resource,\n ...(opts.description ? { description: opts.description } : {}),\n };\n const verified = await verifier.verify(\n new Request(`https://mcp.local/${tool.name}`, { headers: ctx.headers }),\n requirement,\n );\n if (verified.ok) {\n let result: Awaited<ReturnType<typeof tool.handler>>;\n try {\n result = await tool.handler(record, ctx);\n } catch (error) {\n // Rails that already took the money refund here. Rails with a `settle` step have\n // not taken it yet, and the early return means they never will — the buyer is not\n // charged for a call that failed.\n await opts.onPaidFailure?.(ctx, verified, error);\n throw error;\n }\n // The work succeeded, so take the money. A settlement that fails now is lost\n // revenue, not a failed request: the buyer has already been served, and turning\n // this into an error would hand them the result *and* a 402.\n const settled = await verifier.settle?.(verified);\n if (settled && !settled.ok) {\n opts.onSettlementFailure?.(ctx, verified, settled.reason);\n }\n return result;\n }\n reason = liveRail ? (verified.reason ?? reason) : (reason ?? verified.reason);\n throw paymentRequiredError(required.body, reason);\n },\n });\n}\n\n/** Web-standard 402 `Response` for plain HTTP endpoints (re-export of `@agentwares/x402`). */\nexport const paymentRequiredHttpResponse = paymentRequiredResponse;\n\nexport { StubVerifier, buildPaymentRequired };\nexport type { PaymentRequiredBody, PaymentVerifier, SelfServe, VerifyResult };\n","/**\n * A tiny example server: two free tools and one paid tool. Used by the README, the HTTP\n * round-trip test and the conformance script.\n */\nimport { z } from \"zod\";\nimport { withPayment } from \"./payment.js\";\nimport { defineTool, type ToolDef } from \"./tool.js\";\n\nexport const exampleServerInfo = {\n name: \"mcp-kit-example\",\n version: \"0.1.0\",\n instructions:\n \"Example server built with @agentwares/mcp-kit. Call example_echo to check the connection, example_add to see typed structured output, and example_paid_lookup (sample=true first) to see how paid tools respond.\",\n};\n\nexport const exampleEcho = defineTool({\n name: \"example_echo\",\n title: \"Echo\",\n description:\n \"Echo a message back unchanged. Use it to check the connection and to see the result shape mcp-kit tools return (JSON text plus structuredContent).\",\n input: z.object({ message: z.string().describe(\"Text to echo back\") }),\n output: z.object({ message: z.string() }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n handler: ({ message }) => ({ message }),\n});\n\nexport const exampleAdd = defineTool({\n name: \"example_add\",\n title: \"Add\",\n description:\n \"Add two numbers and return their sum as { sum }. Demonstrates typed input and output schemas; send non-numbers to see an INVALID_INPUT error result.\",\n input: z.object({\n a: z.number().describe(\"First addend\"),\n b: z.number().describe(\"Second addend\"),\n }),\n output: z.object({ sum: z.number() }),\n annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: false },\n handler: ({ a, b }) => ({ sum: a + b }),\n});\n\nexport const examplePaidLookup = withPayment(\n defineTool({\n name: \"example_paid_lookup\",\n title: \"Paid lookup\",\n description:\n \"Look up a record by query and return { query, result, sample } (fake data). Demonstrates a paid tool: without an entitlement the call returns a PAYMENT_REQUIRED result with x402 and MPP payment options.\",\n input: z.object({ query: z.string().min(1).describe(\"What to look up\") }),\n output: z.object({ query: z.string(), result: z.string(), sample: z.boolean() }),\n annotations: { readOnlyHint: true, idempotentHint: true },\n handler: ({ query }, ctx) => ({\n query,\n result: ctx.sample ? `SAMPLE: example record for \"${query}\"` : `record for \"${query}\"`,\n sample: ctx.sample === true,\n }),\n }),\n { priceUsd: 0.05, description: \"One record lookup\" },\n);\n\nexport const exampleTools: ToolDef[] = [exampleEcho, exampleAdd, examplePaidLookup];\n","/**\n * The 2026-07-28 revision of MCP, served beside the `initialize` handshake.\n *\n * Read on modelcontextprotocol.io on 8 October 2026 (`specification/2026-07-28/changelog`,\n * `…/basic/versioning`, `…/basic/index#_meta`, `…/basic/transports/streamable-http`,\n * `…/basic/transports/stdio`, `…/server/discover`, `…/schema`):\n *\n * - There is no handshake. Every request carries its version and capabilities in `_meta`\n * (`io.modelcontextprotocol/protocolVersion` and `…/clientCapabilities`, both required;\n * a request missing one is rejected with `-32602`, on HTTP with `400`).\n * - Servers MUST implement `server/discover`: supported versions, capabilities, identity.\n * - A version the server does not implement is answered with `UnsupportedProtocolVersionError`\n * (`-32022`, `data.supported`, `data.requested`), on HTTP with `400`.\n * - Every result carries `resultType`, and list results carry `ttlMs` and `cacheScope`.\n * - The spec calls handshake servers *legacy* and the new ones *modern*. A *dual-era* server\n * \"selects its behavior from how the client opens\": a request carrying the modern `_meta` is\n * served statelessly at 2026-07-28; `initialize` selects legacy semantics.\n *\n * mcp-kit is dual-era. Legacy traffic goes to the SDK exactly as before; a request carrying the\n * modern envelope is checked here, `server/discover` is answered here, and everything else is\n * handed to the same SDK server, whose result is then given the fields 2026-07-28 requires.\n * Nothing here touches tool names, schemas or descriptions.\n *\n * Not served at 2026-07-28 (each answers `-32601`, and is left out of `capabilities`):\n * `subscriptions/listen` and list-changed notifications, multi round-trip requests (a tool that\n * asks the client to sample or elicit fails in-band instead), and the tasks extension.\n */\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type {\n Transport,\n TransportSendOptions,\n} from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n SUPPORTED_PROTOCOL_VERSIONS,\n type Implementation,\n type JSONRPCMessage,\n type MessageExtraInfo,\n type RequestId,\n type ServerCapabilities,\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n/** The revision a modern request names in `_meta`. */\nexport const MODERN_PROTOCOL_VERSION = \"2026-07-28\";\n\n/** Modern revisions served here: per-request `_meta`, no handshake. */\nexport const MODERN_PROTOCOL_VERSIONS: readonly string[] = [MODERN_PROTOCOL_VERSION];\n\n/** Handshake revisions served here, through `initialize` (whatever the pinned SDK accepts). */\nexport const LEGACY_PROTOCOL_VERSIONS: readonly string[] = [...SUPPORTED_PROTOCOL_VERSIONS];\n\n/** Everything served, newest first: `server/discover`'s `supportedVersions` and `-32022`'s `supported`. */\nexport const SERVED_PROTOCOL_VERSIONS: readonly string[] = [\n ...MODERN_PROTOCOL_VERSIONS,\n ...LEGACY_PROTOCOL_VERSIONS,\n];\n\n/** The `_meta` keys 2026-07-28 reserves for per-request and per-result protocol fields. */\nexport const MODERN_META = {\n protocolVersion: \"io.modelcontextprotocol/protocolVersion\",\n clientInfo: \"io.modelcontextprotocol/clientInfo\",\n clientCapabilities: \"io.modelcontextprotocol/clientCapabilities\",\n logLevel: \"io.modelcontextprotocol/logLevel\",\n serverInfo: \"io.modelcontextprotocol/serverInfo\",\n} as const;\n\n/** The codes 2026-07-28 reserves (`-32020…-32099` is the spec's own range). */\nexport const MODERN_ERROR_CODES = {\n HeaderMismatch: -32020,\n MissingRequiredClientCapability: -32021,\n UnsupportedProtocolVersion: -32022,\n} as const;\n\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INVALID_PARAMS = -32602;\nconst INTERNAL_ERROR = -32603;\n\n/**\n * Methods a modern request may not call: the handshake, and what 2026-07-28 removed (`ping`,\n * `logging/setLevel`) or replaced (`resources/subscribe` by `subscriptions/listen`, which is not\n * served here either).\n */\nconst NOT_MODERN = new Set([\n \"initialize\",\n \"ping\",\n \"logging/setLevel\",\n \"resources/subscribe\",\n \"resources/unsubscribe\",\n \"subscriptions/listen\",\n]);\n\n/** Results 2026-07-28 types as `CacheableResult` (`ttlMs` and `cacheScope` required). */\nconst CACHEABLE = new Set([\n \"server/discover\",\n \"tools/list\",\n \"prompts/list\",\n \"resources/list\",\n \"resources/read\",\n \"resources/templates/list\",\n]);\n\n/** RFC 5424 order, as `LoggingLevel` uses it. */\nconst LOG_LEVELS = [\n \"debug\",\n \"info\",\n \"notice\",\n \"warning\",\n \"error\",\n \"critical\",\n \"alert\",\n \"emergency\",\n];\n\n/** Five minutes: how long a client may reuse a tool list mcp-kit built from static definitions. */\nconst STATIC_TTL_MS = 300_000;\n\n/**\n * The mark lives on the server object under a registered symbol, not in a module-level set: a\n * bundler that duplicates this module per chunk (Turbopack did, to a shared package's module\n * state, in September 2026) would otherwise mark in one copy and read from another.\n */\nconst STATIC_LISTING = Symbol.for(\"@agentwares/mcp-kit/static-listing\");\n\n/**\n * Mark a server whose `server/discover` and `tools/list` answers do not depend on the caller,\n * so a modern client and shared intermediaries may cache them (`cacheScope: \"public\"`). Anything\n * not marked is answered `private` with `ttlMs: 0`: the agentguard proxy, for one, lists tools\n * per agent key.\n */\nexport function markStaticListing(server: McpServer): void {\n (server as unknown as Record<symbol, unknown>)[STATIC_LISTING] = true;\n}\n\nfunction hasStaticListing(server: McpServer): boolean {\n return (server as unknown as Record<symbol, unknown>)[STATIC_LISTING] === true;\n}\n\nexport interface JsonRpcErrorBody {\n code: number;\n message: string;\n data?: unknown;\n}\n\n/** How one incoming message is served. */\nexport type ModernRoute =\n /** no modern envelope (or one naming a 2025-era version): the SDK serves it as before */\n | { kind: \"legacy\" }\n /** a modern notification: delivered as is (on HTTP, acknowledged with 202) */\n | { kind: \"notification\" }\n /** refused before anything runs; `status` is the HTTP status for it */\n | { kind: \"reject\"; id: RequestId | null; status: 400 | 404; error: JsonRpcErrorBody }\n /** `server/discover`, answered from the server's own identity and capabilities */\n | { kind: \"discover\"; id: RequestId; method: string; version: string }\n /** any other modern request, handed to the SDK server and decorated on the way out */\n | { kind: \"dispatch\"; id: RequestId; method: string; version: string; logLevel?: string };\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction requestId(value: unknown): RequestId | null {\n return typeof value === \"string\" || typeof value === \"number\" ? value : null;\n}\n\n/** The modern envelope's version claim, or undefined when the message carries no envelope. */\nexport function modernClaim(message: unknown): unknown {\n if (!isObject(message) || !isObject(message[\"params\"])) return undefined;\n const meta = message[\"params\"][\"_meta\"];\n return isObject(meta) ? meta[MODERN_META.protocolVersion] : undefined;\n}\n\nexport function unsupportedVersionError(requested: string): JsonRpcErrorBody {\n return {\n code: MODERN_ERROR_CODES.UnsupportedProtocolVersion,\n message: `Unsupported protocol version: ${requested}. Supported: ${SERVED_PROTOCOL_VERSIONS.join(\", \")}`,\n data: { supported: [...SERVED_PROTOCOL_VERSIONS], requested },\n };\n}\n\n/**\n * Decide how a message is served. Body-primary, like the reference SDK: the envelope decides the\n * era, so a proxy that strips a header cannot change it. Headers are checked separately, on HTTP\n * only ({@link checkModernHeaders}).\n */\nexport function routeModern(message: unknown): ModernRoute {\n if (!isObject(message) || typeof message[\"method\"] !== \"string\") return { kind: \"legacy\" };\n const claim = modernClaim(message);\n if (claim === undefined) return { kind: \"legacy\" };\n\n const method = message[\"method\"];\n const hasId = \"id\" in message;\n const id = requestId(message[\"id\"]);\n if (typeof claim !== \"string\") {\n return {\n kind: \"reject\",\n id,\n status: 400,\n error: { code: INVALID_PARAMS, message: `${MODERN_META.protocolVersion} must be a string` },\n };\n }\n // A 2025-era version in the envelope is not a modern request; the handshake path serves it.\n if (LEGACY_PROTOCOL_VERSIONS.includes(claim)) return { kind: \"legacy\" };\n if (!MODERN_PROTOCOL_VERSIONS.includes(claim)) {\n return { kind: \"reject\", id, status: 400, error: unsupportedVersionError(claim) };\n }\n if (!hasId) return { kind: \"notification\" };\n if (id === null) {\n return {\n kind: \"reject\",\n id: null,\n status: 400,\n error: { code: INVALID_REQUEST, message: \"a request id must be a string or a number\" },\n };\n }\n\n const meta = (message[\"params\"] as Record<string, unknown>)[\"_meta\"] as Record<string, unknown>;\n if (!isObject(meta[MODERN_META.clientCapabilities])) {\n return {\n kind: \"reject\",\n id,\n status: 400,\n error: {\n code: INVALID_PARAMS,\n message: `Missing required _meta field ${MODERN_META.clientCapabilities} (an object; {} when the client declares none)`,\n },\n };\n }\n if (method === \"server/discover\") return { kind: \"discover\", id, method, version: claim };\n if (NOT_MODERN.has(method)) {\n return {\n kind: \"reject\",\n id,\n status: 404,\n error: {\n code: METHOD_NOT_FOUND,\n message:\n method === \"initialize\"\n ? `Method not found: initialize is not part of ${claim}; call server/discover, or send initialize without the ${MODERN_META.protocolVersion} _meta field to open a 2025-era session`\n : `Method not found: ${method} is not served at ${claim}`,\n },\n };\n }\n const level = meta[MODERN_META.logLevel];\n return {\n kind: \"dispatch\",\n id,\n method,\n version: claim,\n ...(typeof level === \"string\" ? { logLevel: level } : {}),\n };\n}\n\n/** `Mcp-Name` mirrors `params.name` for these methods and `params.uri` for `resources/read`. */\nfunction nameSource(method: string, params: unknown): string | undefined {\n if (!isObject(params)) return undefined;\n const field =\n method === \"tools/call\" || method === \"prompts/get\"\n ? \"name\"\n : method === \"resources/read\"\n ? \"uri\"\n : undefined;\n const value = field ? params[field] : undefined;\n return typeof value === \"string\" ? value : undefined;\n}\n\n/** `=?base64?…?=` → the UTF-8 value it carries; undefined when the sentinel is malformed. */\nfunction decodeHeaderValue(value: string): string | undefined {\n const match = /^=\\?base64\\?(.*)\\?=$/.exec(value);\n if (!match) return value;\n try {\n const bytes = Uint8Array.from(atob(match[1] ?? \"\"), (c) => c.charCodeAt(0));\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n } catch {\n return undefined;\n }\n}\n\nfunction headerMismatch(id: RequestId | null, message: string): ModernRoute {\n return {\n kind: \"reject\",\n id,\n status: 400,\n error: { code: MODERN_ERROR_CODES.HeaderMismatch, message: `Header mismatch: ${message}` },\n };\n}\n\n/**\n * The Streamable HTTP request headers 2026-07-28 requires on a modern request, checked against\n * the body: `MCP-Protocol-Version` equal to the `_meta` version, `Mcp-Method` equal to `method`,\n * and `Mcp-Name` equal to `params.name` / `params.uri` where the method has one. Any failure is\n * `400` with `HeaderMismatch` (`-32020`), as the spec's server-validation section requires.\n * Never applied to legacy traffic.\n */\nexport function checkModernHeaders(\n headers: Headers,\n message: { method: string; id: RequestId; params?: unknown },\n version: string,\n): ModernRoute | undefined {\n const { id, method } = message;\n const protocolHeader = headers.get(\"mcp-protocol-version\")?.trim();\n if (protocolHeader === undefined) {\n return headerMismatch(id, \"the required MCP-Protocol-Version header is missing\");\n }\n if (protocolHeader !== version) {\n return headerMismatch(\n id,\n `MCP-Protocol-Version header value '${protocolHeader}' does not match body value '${version}'`,\n );\n }\n const methodHeader = headers.get(\"mcp-method\")?.trim();\n if (methodHeader === undefined) {\n return headerMismatch(id, \"the required Mcp-Method header is missing\");\n }\n if (methodHeader !== method) {\n return headerMismatch(\n id,\n `Mcp-Method header value '${methodHeader}' does not match body value '${method}'`,\n );\n }\n const bodyName = nameSource(method, message.params);\n if (bodyName === undefined) return undefined;\n const nameHeader = headers.get(\"mcp-name\")?.trim();\n if (nameHeader === undefined) {\n return headerMismatch(id, `the required Mcp-Name header is missing (body value '${bodyName}')`);\n }\n const decoded = decodeHeaderValue(nameHeader);\n if (decoded === undefined) {\n return headerMismatch(id, \"the Mcp-Name header carries an invalid =?base64?…?= value\");\n }\n if (decoded !== bodyName) {\n return headerMismatch(\n id,\n `Mcp-Name header value '${decoded}' does not match body value '${bodyName}'`,\n );\n }\n return undefined;\n}\n\n/**\n * A request with no modern envelope whose `MCP-Protocol-Version` header names a version the\n * handshake path does not serve. Without this the SDK would answer `400` with a bare `-32000`,\n * and a client that sent `2026-07-28` would be told that version is unsupported when only its\n * `_meta` is missing. `initialize` is left to the handshake, which negotiates on its own terms.\n */\nexport function checkLegacyHeader(headers: Headers, message: unknown): ModernRoute | undefined {\n if (!isObject(message) || message[\"method\"] === \"initialize\") return undefined;\n const header = headers.get(\"mcp-protocol-version\")?.trim();\n if (!header || LEGACY_PROTOCOL_VERSIONS.includes(header)) return undefined;\n const id = requestId(message[\"id\"]);\n if (MODERN_PROTOCOL_VERSIONS.includes(header)) {\n return {\n kind: \"reject\",\n id,\n status: 400,\n error: {\n code: INVALID_PARAMS,\n message: `Missing required _meta field ${MODERN_META.protocolVersion}: MCP-Protocol-Version says ${header}, which carries its version in each request's params._meta`,\n },\n };\n }\n return { kind: \"reject\", id, status: 400, error: unsupportedVersionError(header) };\n}\n\ninterface ServerInternals {\n _serverInfo?: Implementation;\n _instructions?: string;\n getCapabilities(): ServerCapabilities;\n}\n\n/** The SDK keeps identity and instructions private; they are what `initialize` answers with. */\nfunction internals(server: McpServer): ServerInternals {\n return server.server as unknown as ServerInternals;\n}\n\nexport function serverInfoOf(server: McpServer): Implementation {\n const info = internals(server)._serverInfo;\n return info ? { ...info } : { name: \"mcp-server\", version: \"0.0.0\" };\n}\n\n/**\n * Capabilities as a modern client may act on them: list-changed notifications and resource\n * subscriptions need `subscriptions/listen`, and tasks are an extension, none of which is served\n * here, so they are not advertised.\n */\nexport function modernCapabilities(capabilities: ServerCapabilities): ServerCapabilities {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(capabilities) as [string, unknown][]) {\n if (key === \"tasks\" || value === undefined) continue;\n if (isObject(value) && (key === \"tools\" || key === \"prompts\" || key === \"resources\")) {\n const { listChanged: _listChanged, subscribe: _subscribe, ...rest } = value;\n out[key] = rest;\n } else {\n out[key] = value;\n }\n }\n return out as ServerCapabilities;\n}\n\nfunction cacheHints(server: McpServer, method: string): { ttlMs: number; cacheScope: string } {\n const isStatic =\n hasStaticListing(server) && (method === \"server/discover\" || method === \"tools/list\");\n return isStatic\n ? { ttlMs: STATIC_TTL_MS, cacheScope: \"public\" }\n : { ttlMs: 0, cacheScope: \"private\" };\n}\n\n/** The `server/discover` result: every version served, capabilities, identity, instructions. */\nexport function discoverResult(server: McpServer): Record<string, unknown> {\n const instructions = internals(server)._instructions;\n return {\n resultType: \"complete\",\n supportedVersions: [...SERVED_PROTOCOL_VERSIONS],\n capabilities: modernCapabilities(internals(server).getCapabilities()),\n ...(instructions ? { instructions } : {}),\n ...cacheHints(server, \"server/discover\"),\n _meta: { [MODERN_META.serverInfo]: serverInfoOf(server) },\n };\n}\n\n/** Add what 2026-07-28 requires of a result: `resultType`, the server's identity, cache hints. */\nexport function decorateResult(\n server: McpServer,\n method: string,\n result: Record<string, unknown>,\n): Record<string, unknown> {\n const meta = isObject(result[\"_meta\"]) ? { ...result[\"_meta\"] } : {};\n if (meta[MODERN_META.serverInfo] === undefined) {\n meta[MODERN_META.serverInfo] = serverInfoOf(server);\n }\n const out: Record<string, unknown> = { resultType: \"complete\", ...result, _meta: meta };\n if (CACHEABLE.has(method)) {\n const hints = cacheHints(server, method);\n if (out[\"ttlMs\"] === undefined) out[\"ttlMs\"] = hints.ttlMs;\n if (out[\"cacheScope\"] === undefined) out[\"cacheScope\"] = hints.cacheScope;\n }\n return out;\n}\n\n/** 2026-07-28: no `notifications/message` unless the request asked, at or above its level. */\nfunction logAllowed(requested: string | undefined, level: unknown): boolean {\n if (requested === undefined) return false;\n const floor = LOG_LEVELS.indexOf(requested);\n const at = LOG_LEVELS.indexOf(String(level));\n return floor !== -1 && at !== -1 && at >= floor;\n}\n\nexport function errorMessage(id: RequestId | null, error: JsonRpcErrorBody): JSONRPCMessage {\n return { jsonrpc: \"2.0\", id, error } as unknown as JSONRPCMessage;\n}\n\ninterface ModernRequest {\n method: string;\n logLevel?: string;\n}\n\nfunction messageId(message: JSONRPCMessage): RequestId | undefined {\n const id = (message as { id?: unknown }).id;\n return typeof id === \"string\" || typeof id === \"number\" ? id : undefined;\n}\n\nfunction isResponse(message: JSONRPCMessage): boolean {\n return !(\"method\" in message) && (\"result\" in message || \"error\" in message);\n}\n\n/**\n * A transport wrapper that makes any SDK server dual-era: legacy messages pass straight through,\n * modern ones are routed by {@link routeModern}, `server/discover` is answered here, and on the\n * way out a modern request's result gains `resultType`, `serverInfo` and cache hints, its log\n * notifications are dropped unless it asked for them, and a server→client request made on its\n * behalf (sampling, elicitation — 2026-07-28 replaces these with multi round-trip results, which\n * are not served here) is refused back to the server instead of written to the client.\n *\n * Wraps the stdio transport directly; the HTTP handler wraps a one-request sink with it.\n */\nexport class DualEraTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: <T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void;\n\n private readonly modern = new Map<RequestId, ModernRequest>();\n\n constructor(\n private readonly inner: Transport,\n private readonly server: McpServer,\n ) {}\n\n get sessionId(): string | undefined {\n return this.inner.sessionId;\n }\n\n setProtocolVersion(version: string): void {\n this.inner.setProtocolVersion?.(version);\n }\n\n async start(): Promise<void> {\n this.inner.onmessage = (message, extra) => this.receive(message, extra);\n this.inner.onclose = () => this.onclose?.();\n this.inner.onerror = (error) => this.onerror?.(error);\n await this.inner.start();\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n private write(message: JSONRPCMessage): void {\n this.inner.send(message).catch((error: unknown) => {\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n });\n }\n\n private receive(message: JSONRPCMessage, extra?: MessageExtraInfo): void {\n const route = routeModern(message);\n switch (route.kind) {\n case \"legacy\":\n case \"notification\":\n this.onmessage?.(message, extra);\n return;\n case \"reject\":\n if (\"id\" in message) this.write(errorMessage(route.id, route.error));\n return;\n case \"discover\":\n this.write({\n jsonrpc: \"2.0\",\n id: route.id,\n result: discoverResult(this.server),\n } as JSONRPCMessage);\n return;\n case \"dispatch\":\n this.modern.set(route.id, {\n method: route.method,\n ...(route.logLevel !== undefined ? { logLevel: route.logLevel } : {}),\n });\n this.onmessage?.(message, extra);\n return;\n }\n }\n\n async send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void> {\n const id = messageId(message);\n if (id !== undefined && isResponse(message)) {\n const request = this.modern.get(id);\n if (request) {\n this.modern.delete(id);\n const result = (message as { result?: unknown }).result;\n if (isObject(result)) {\n message = {\n ...message,\n result: decorateResult(this.server, request.method, result),\n } as JSONRPCMessage;\n }\n }\n return this.inner.send(message, options);\n }\n\n const related =\n options?.relatedRequestId !== undefined\n ? this.modern.get(options.relatedRequestId)\n : undefined;\n if (related && \"method\" in message) {\n if (id !== undefined) {\n // A server→client request for a modern caller: 2026-07-28 forbids writing it. Answer it\n // locally so the tool that asked fails in-band rather than waiting forever.\n const refusal = errorMessage(id, {\n code: INTERNAL_ERROR,\n message: `${message.method} cannot reach a ${MODERN_PROTOCOL_VERSION} client from this server (multi round-trip requests are not served); call this tool from a 2025-era session (initialize) instead`,\n });\n queueMicrotask(() => this.onmessage?.(refusal));\n return;\n }\n if (message.method === \"notifications/message\") {\n const level = (message as { params?: { level?: unknown } }).params?.level;\n if (!logAllowed(related.logLevel, level)) return;\n }\n }\n return this.inner.send(message, options);\n }\n}\n","/**\n * `createMcpServer` — an SDK `McpServer` with every `ToolDef` registered, plus the manifest\n * helper used for `llms.txt` and docs.\n */\nimport { McpServer, type RegisteredTool } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type ServerCapabilities,\n type ServerNotification,\n type ServerRequest,\n type Tool,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { markStaticListing } from \"./modern.js\";\nimport type { ToolAnnotations, ToolContext, ToolDef } from \"./tool.js\";\n\nexport interface McpServerOptions {\n /** server name as shown to clients, e.g. `agentcheck` */\n name: string;\n version: string;\n title?: string;\n websiteUrl?: string;\n /** shown to the model at connect time: what the server is for and how to start */\n instructions?: string;\n tools: ToolDef[];\n /** extra capabilities (tools and logging are always declared) */\n capabilities?: ServerCapabilities;\n}\n\ntype Extra = RequestHandlerExtra<ServerRequest, ServerNotification>;\n\nfunction isZodObject(schema: unknown): schema is z.ZodObject {\n return schema instanceof z.ZodObject;\n}\n\n/** Build a `ToolContext` from the SDK's request `extra` (headers, ids, signal, notifications). */\nexport function contextFromExtra(extra: Extra): ToolContext {\n const headers = new Headers();\n const raw = extra.requestInfo?.headers;\n if (raw) {\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) for (const item of value) headers.append(key, item);\n else if (typeof value === \"string\") headers.append(key, value);\n }\n }\n const progressToken = extra._meta?.progressToken;\n return {\n headers,\n requestId: String(extra.requestId),\n signal: extra.signal,\n sessionId: extra.sessionId,\n meta: extra._meta,\n extra,\n log: async (level, data) => {\n await extra.sendNotification({ method: \"notifications/message\", params: { level, data } });\n },\n progress: async (progress, total, message) => {\n if (progressToken === undefined) return;\n await extra.sendNotification({\n method: \"notifications/progress\",\n params: { progressToken, progress, total, message },\n });\n },\n };\n}\n\n/**\n * Create an `McpServer` with all tools registered. Duplicate names throw.\n *\n * Tools are registered with the SDK (capabilities, enable/disable, list-changed notifications),\n * but `tools/list` and `tools/call` are served by the kit: the listing is exactly\n * `listToolManifest(tools)` (JSON Schema 2020-12, `additionalProperties: false`), and invalid\n * arguments or handler failures come back as in-band `{ code, cause, fix, retryable }` results\n * instead of bare JSON-RPC errors.\n */\nexport function createMcpServer(opts: McpServerOptions): McpServer {\n const byName = new Map<string, ToolDef>();\n for (const tool of opts.tools) {\n if (byName.has(tool.name)) throw new Error(`duplicate tool name: ${tool.name}`);\n byName.set(tool.name, tool);\n }\n\n const server = new McpServer(\n { name: opts.name, version: opts.version, title: opts.title, websiteUrl: opts.websiteUrl },\n { instructions: opts.instructions, capabilities: { logging: {}, ...opts.capabilities } },\n );\n\n const registered = new Map<string, RegisteredTool>();\n for (const tool of byName.values()) {\n const config: {\n title?: string;\n description: string;\n inputSchema: z.ZodObject;\n outputSchema?: z.ZodObject;\n annotations?: ToolAnnotations;\n } = {\n title: tool.title,\n description: tool.description,\n inputSchema: tool.input,\n annotations: tool.annotations,\n };\n if (isZodObject(tool.output)) config.outputSchema = tool.output;\n registered.set(\n tool.name,\n server.registerTool(tool.name, config, () => {\n throw new Error(\"unreachable: mcp-kit dispatches tools/call itself\");\n }),\n );\n }\n\n if (byName.size > 0) {\n server.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const enabled = [...byName.values()].filter(\n (tool) => registered.get(tool.name)?.enabled !== false,\n );\n return {\n tools: listToolManifest(enabled).map((entry) => ({\n ...entry,\n inputSchema: entry.inputSchema as Tool[\"inputSchema\"],\n outputSchema: entry.outputSchema as Tool[\"outputSchema\"],\n })),\n };\n });\n server.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {\n const name = request.params.name;\n const tool = byName.get(name);\n const entry = registered.get(name);\n if (!tool || !entry) throw new McpError(ErrorCode.InvalidParams, `Tool ${name} not found`);\n if (!entry.enabled) throw new McpError(ErrorCode.InvalidParams, `Tool ${name} disabled`);\n return tool.invoke(request.params.arguments ?? {}, contextFromExtra(extra));\n });\n }\n\n // The listing is `listToolManifest(tools)`, fixed here and the same for every caller, so a\n // 2026-07-28 client may cache `tools/list` and `server/discover` publicly.\n markStaticListing(server);\n return server;\n}\n\nexport interface ToolManifestEntry {\n name: string;\n title?: string;\n description: string;\n inputSchema: Record<string, unknown>;\n outputSchema?: Record<string, unknown>;\n annotations?: ToolAnnotations;\n}\n\n/**\n * JSON Schema (2020-12) for a zod schema, as advertised to clients. Plain `z.object`s strip\n * unknown keys at runtime, so they are advertised with `additionalProperties: false` (strict\n * schemas keep agents from inventing parameters); `z.looseObject` keeps them open.\n */\nexport function toJsonSchema(\n schema: z.ZodType,\n io: \"input\" | \"output\" = \"input\",\n): Record<string, unknown> {\n const json = z.toJSONSchema(schema, { io, target: \"draft-2020-12\" }) as Record<string, unknown>;\n if (\n isZodObject(schema) &&\n schema._zod.def.catchall === undefined &&\n json.additionalProperties === undefined\n ) {\n json.additionalProperties = false;\n }\n return json;\n}\n\n/** Plain JSON description of the tools — for `llms.txt`, docs pages and registries. */\nexport function listToolManifest(tools: readonly ToolDef[]): ToolManifestEntry[] {\n return tools.map((tool) => {\n const entry: ToolManifestEntry = {\n name: tool.name,\n description: tool.description,\n inputSchema: toJsonSchema(tool.input, \"input\"),\n };\n if (tool.title !== undefined) entry.title = tool.title;\n if (isZodObject(tool.output)) entry.outputSchema = toJsonSchema(tool.output, \"output\");\n if (tool.annotations !== undefined) entry.annotations = tool.annotations;\n return entry;\n });\n}\n","/**\n * Web-standard Streamable HTTP handler: `(Request) => Promise<Response>`. Runs unchanged in\n * Next.js route handlers, Vercel Functions and Cloudflare Workers.\n *\n * Stateless by default: a fresh server and transport per request, closed when the response\n * finishes. Opt into `sessions: true` for a long-lived process that needs server→client\n * requests (sampling, elicitation) or the standalone GET stream.\n *\n * Dual-era (./modern.ts): a POST whose body carries the 2026-07-28 `_meta` envelope is served\n * statelessly at 2026-07-28 — `server/discover`, the spec's header checks and error codes —\n * whatever the session setting; `initialize` and everything without the envelope goes to the\n * SDK's transport exactly as before.\n */\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage, MessageExtraInfo } from \"@modelcontextprotocol/sdk/types.js\";\nimport { normalizeError } from \"./errors.js\";\nimport {\n DualEraTransport,\n MODERN_PROTOCOL_VERSION,\n checkLegacyHeader,\n checkModernHeaders,\n errorMessage,\n modernClaim,\n routeModern,\n type ModernRoute,\n} from \"./modern.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\nexport interface CorsOptions {\n /** `Access-Control-Allow-Origin` (default `*`) */\n origin?: string;\n methods?: string;\n headers?: string;\n exposeHeaders?: string;\n maxAge?: number;\n}\n\nexport interface SessionOptions {\n /** idle sessions are closed after this long (default 30 minutes) */\n ttlMs?: number;\n}\n\nexport interface HttpTransportOptions {\n /** `true` for permissive defaults, or explicit values. Off by default. */\n cors?: boolean | CorsOptions;\n /**\n * `true`: each POST is answered with one JSON body — simplest for curl and serverless\n * (default when stateless). `false`: answer with an SSE stream so `ctx.log` / `ctx.progress`\n * notifications and server→client requests reach the client mid-call (default with sessions).\n */\n jsonResponse?: boolean;\n /**\n * `false` (default): stateless — no session ids, safe on serverless. `true` (or options):\n * sessions kept in this process's memory under `Mcp-Session-Id`; needed for sampling,\n * elicitation and the standalone GET stream. Single long-lived process only.\n */\n sessions?: boolean | SessionOptions;\n /** Host header allow-list (DNS-rebinding protection for localhost servers). */\n allowedHosts?: string[];\n allowedOrigins?: string[];\n enableDnsRebindingProtection?: boolean;\n}\n\nexport type HttpHandlerOptions = McpServerOptions & HttpTransportOptions;\nexport type HttpHandler = (request: Request) => Promise<Response>;\n\nconst DEFAULT_CORS: Required<CorsOptions> = {\n origin: \"*\",\n methods: \"GET, POST, DELETE, OPTIONS\",\n headers:\n \"Content-Type, Accept, Authorization, Mcp-Session-Id, Mcp-Protocol-Version, Mcp-Method, Mcp-Name, Last-Event-ID, PAYMENT, X-PAYMENT\",\n exposeHeaders:\n \"Mcp-Session-Id, Mcp-Protocol-Version, WWW-Authenticate, X-Payment-Requirements, PAYMENT-REQUIRED\",\n maxAge: 86_400,\n};\n\nconst DEFAULT_SESSION_TTL_MS = 30 * 60_000;\n\nfunction corsHeaders(cors: boolean | CorsOptions | undefined): Record<string, string> {\n if (!cors) return {};\n const c = { ...DEFAULT_CORS, ...(typeof cors === \"object\" ? cors : {}) };\n return {\n \"Access-Control-Allow-Origin\": c.origin,\n \"Access-Control-Allow-Methods\": c.methods,\n \"Access-Control-Allow-Headers\": c.headers,\n \"Access-Control-Expose-Headers\": c.exposeHeaders,\n \"Access-Control-Max-Age\": String(c.maxAge),\n };\n}\n\nfunction jsonResponse(\n body: unknown,\n status: number,\n headers: Record<string, string> = {},\n): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\", \"Cache-Control\": \"no-store\", ...headers },\n });\n}\n\nfunction methodNotAllowed(method: string, allow: string, cors: Record<string, string>): Response {\n return jsonResponse(\n {\n code: \"METHOD_NOT_ALLOWED\",\n cause: `${method} is not supported here without a session`,\n fix: `send JSON-RPC over POST with \\`Accept: application/json, text/event-stream\\`: at ${MODERN_PROTOCOL_VERSION}, any request with its version in params._meta (start with \\`server/discover\\`); on a 2025-era client, start with \\`initialize\\``,\n retryable: false,\n },\n 405,\n { Allow: allow, ...cors },\n );\n}\n\nfunction splitOptions(\n opts: HttpHandlerOptions | (() => McpServer),\n transport: HttpTransportOptions,\n): { factory: () => McpServer; transport: HttpTransportOptions } {\n if (typeof opts === \"function\") return { factory: opts, transport };\n const {\n cors,\n jsonResponse,\n sessions,\n allowedHosts,\n allowedOrigins,\n enableDnsRebindingProtection,\n ...server\n } = opts;\n return {\n factory: () => createMcpServer(server),\n transport: {\n cors,\n jsonResponse,\n sessions,\n allowedHosts,\n allowedOrigins,\n enableDnsRebindingProtection,\n ...transport,\n },\n };\n}\n\ninterface TransportBase {\n enableJsonResponse: boolean;\n allowedHosts?: string[];\n allowedOrigins?: string[];\n enableDnsRebindingProtection?: boolean;\n}\n\ninterface HandlerContext {\n factory: () => McpServer;\n cors: Record<string, string>;\n transportBase: TransportBase;\n}\n\nfunction withCors(response: Response, cors: Record<string, string>): Response {\n const keys = Object.keys(cors);\n if (keys.length === 0) return response;\n const headers = new Headers(response.headers);\n for (const key of keys) headers.set(key, cors[key] ?? \"\");\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\nfunction errorResponse(err: unknown, cors: Record<string, string>): Response {\n const error = normalizeError(err);\n return jsonResponse(error.toJSON(), error.httpStatus, cors);\n}\n\nfunction createStatelessHandler({ factory, cors, transportBase }: HandlerContext): HttpHandler {\n return async (request) => {\n if (request.method !== \"POST\") return methodNotAllowed(request.method, \"POST, OPTIONS\", cors);\n\n const server = factory();\n const transport = new WebStandardStreamableHTTPServerTransport({\n ...transportBase,\n sessionIdGenerator: undefined,\n });\n let closed = false;\n const cleanup = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n try {\n await server.close();\n } catch {\n // already closed\n }\n };\n\n try {\n await server.connect(transport);\n const response = withCors(await transport.handleRequest(request), cors);\n if (!response.body) {\n await cleanup();\n return response;\n }\n // Close server + transport once the body (JSON or SSE stream) has been fully written.\n request.signal?.addEventListener(\"abort\", () => void cleanup(), { once: true });\n const body = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({ flush: () => cleanup() }),\n );\n return new Response(body, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (err) {\n await cleanup();\n return errorResponse(err, cors);\n }\n };\n}\n\ninterface Session {\n server: McpServer;\n transport: WebStandardStreamableHTTPServerTransport;\n lastSeen: number;\n}\n\nfunction createStatefulHandler(\n { factory, cors, transportBase }: HandlerContext,\n options: SessionOptions,\n): HttpHandler {\n const ttlMs = options.ttlMs ?? DEFAULT_SESSION_TTL_MS;\n const sessions = new Map<string, Session>();\n\n const drop = (id: string): void => {\n const session = sessions.get(id);\n if (!session) return;\n sessions.delete(id);\n session.server.close().catch(() => undefined);\n };\n const sweep = (): void => {\n const now = Date.now();\n for (const [id, session] of sessions) if (now - session.lastSeen > ttlMs) drop(id);\n };\n\n return async (request) => {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (sessionId) {\n const session = sessions.get(sessionId);\n if (!session) {\n return jsonResponse(\n {\n code: \"NOT_FOUND\",\n cause: \"unknown or expired Mcp-Session-Id\",\n fix: `send \\`initialize\\` again without an Mcp-Session-Id header and use the id from the response, or drop the header and send the request at ${MODERN_PROTOCOL_VERSION} (version in params._meta), which needs no session`,\n retryable: true,\n },\n 404,\n cors,\n );\n }\n session.lastSeen = Date.now();\n try {\n return withCors(await session.transport.handleRequest(request), cors);\n } catch (err) {\n return errorResponse(err, cors);\n }\n }\n\n if (request.method !== \"POST\") return methodNotAllowed(request.method, \"POST, OPTIONS\", cors);\n sweep();\n\n const server = factory();\n const transport = new WebStandardStreamableHTTPServerTransport({\n ...transportBase,\n sessionIdGenerator: () => crypto.randomUUID(),\n onsessioninitialized: (id) => {\n sessions.set(id, { server, transport, lastSeen: Date.now() });\n },\n onsessionclosed: (id) => {\n sessions.delete(id);\n },\n });\n\n try {\n await server.connect(transport);\n const previousOnClose = transport.onclose;\n transport.onclose = () => {\n previousOnClose?.();\n if (transport.sessionId) sessions.delete(transport.sessionId);\n };\n const response = withCors(await transport.handleRequest(request), cors);\n // Anything but a successful `initialize` leaves no session behind: release the server.\n if (!transport.sessionId) server.close().catch(() => undefined);\n return response;\n } catch (err) {\n server.close().catch(() => undefined);\n return errorResponse(err, cors);\n }\n };\n}\n\nfunction rpcErrorResponse(\n route: Extract<ModernRoute, { kind: \"reject\" }>,\n cors: Record<string, string>,\n): Response {\n return jsonResponse(errorMessage(route.id, route.error), route.status, cors);\n}\n\n/**\n * The DNS-rebinding checks the SDK transport makes, for the modern path that does not go\n * through it: a Host outside `allowedHosts` or an Origin outside `allowedOrigins` is a 403.\n */\nfunction rebindingError(request: Request, base: TransportBase): string | undefined {\n if (!base.enableDnsRebindingProtection) return undefined;\n if (base.allowedHosts?.length) {\n const host = request.headers.get(\"host\");\n if (!host || !base.allowedHosts.includes(host)) return `Invalid Host header: ${host}`;\n }\n if (base.allowedOrigins?.length) {\n const origin = request.headers.get(\"origin\");\n if (origin && !base.allowedOrigins.includes(origin)) return `Invalid Origin header: ${origin}`;\n }\n return undefined;\n}\n\n/** What a POST body is, read from a clone so the SDK transport can still read the original. */\ntype Peeked =\n | { kind: \"legacy\" }\n | { kind: \"reject\"; route: Extract<ModernRoute, { kind: \"reject\" }> }\n | { kind: \"modern\"; message: Record<string, unknown>; route: ModernRoute };\n\nasync function peek(request: Request): Promise<Peeked> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(await request.clone().text()) as unknown;\n } catch {\n return { kind: \"legacy\" }; // the SDK answers the parse error, as before\n }\n if (Array.isArray(parsed)) {\n // 2026-07-28 has no batches; a 2025-03-26 client may still send one.\n if (!parsed.some((element) => modernClaim(element) !== undefined)) return { kind: \"legacy\" };\n return {\n kind: \"reject\",\n route: {\n kind: \"reject\",\n id: null,\n status: 400,\n error: { code: -32600, message: \"a JSON-RPC batch cannot carry 2026-07-28 requests\" },\n },\n };\n }\n const route = routeModern(parsed);\n if (route.kind === \"legacy\") {\n const refused = checkLegacyHeader(request.headers, parsed);\n return refused?.kind === \"reject\" ? { kind: \"reject\", route: refused } : { kind: \"legacy\" };\n }\n return { kind: \"modern\", message: parsed as Record<string, unknown>, route };\n}\n\n/** A transport that hands every outgoing message to one callback: one modern request's worth. */\nclass SinkTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: <T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void;\n\n constructor(private readonly out: (message: JSONRPCMessage) => void) {}\n\n async start(): Promise<void> {}\n\n async send(message: JSONRPCMessage): Promise<void> {\n this.out(message);\n }\n\n async close(): Promise<void> {\n this.onclose?.();\n }\n}\n\nconst encoder = new TextEncoder();\n\nfunction sseEvent(message: JSONRPCMessage): Uint8Array {\n return encoder.encode(`event: message\\ndata: ${JSON.stringify(message)}\\n\\n`);\n}\n\n/** `-32601` is a 404 at 2026-07-28; every other JSON-RPC answer is a 200. */\nfunction statusFor(message: JSONRPCMessage): number {\n return (message as { error?: { code?: unknown } }).error?.code === -32601 ? 404 : 200;\n}\n\n/**\n * Serve one 2026-07-28 request: always stateless, a fresh server from the factory, closed when\n * the answer is written. One JSON body, unless the handler streams (`jsonResponse: false`), the\n * client accepts SSE and the tool sends progress or a requested log first — then an SSE stream\n * scoped to this request, ending with the result.\n */\nasync function serveModern(\n request: Request,\n message: Record<string, unknown>,\n route: ModernRoute,\n { factory, cors, transportBase }: HandlerContext,\n): Promise<Response> {\n const rebinding = rebindingError(request, transportBase);\n if (rebinding) {\n return jsonResponse(errorMessage(null, { code: -32600, message: rebinding }), 403, cors);\n }\n if (route.kind === \"reject\") return rpcErrorResponse(route, cors);\n if (route.kind === \"notification\") return new Response(null, { status: 202, headers: cors });\n if (route.kind === \"legacy\") throw new Error(\"unreachable: legacy requests take the SDK path\");\n\n const headerError = checkModernHeaders(\n request.headers,\n { method: route.method, id: route.id, params: message[\"params\"] },\n route.version,\n );\n if (headerError?.kind === \"reject\") return rpcErrorResponse(headerError, cors);\n\n // `server/discover` goes through the same connected transport as any other request (where\n // `DualEraTransport` answers it), not straight off a fresh server: closing a server that was\n // never connected never fires its `onclose`, and a factory may rely on that to release what\n // it set up per server — the agentguard proxy detaches its downstream session there.\n const server = factory();\n const streams =\n !transportBase.enableJsonResponse &&\n (request.headers.get(\"accept\") ?? \"\").includes(\"text/event-stream\");\n let closed = false;\n const cleanup = async (): Promise<void> => {\n if (closed) return;\n closed = true;\n await server.close().catch(() => undefined);\n };\n\n type First = { kind: \"json\"; message: JSONRPCMessage } | { kind: \"sse\"; body: ReadableStream };\n let settle!: (first: First) => void;\n const first = new Promise<First>((resolve) => (settle = resolve));\n let settled = false;\n let controller: ReadableStreamDefaultController<Uint8Array> | undefined;\n let ended = false;\n\n const deliver = (out: JSONRPCMessage): void => {\n const final = !(\"method\" in out) && (out as { id?: unknown }).id === route.id;\n if (!settled) {\n if (final) {\n settled = true;\n settle({ kind: \"json\", message: out });\n return;\n }\n if (!streams) return; // a JSON answer has nowhere to put a notification\n settled = true;\n const body = new ReadableStream<Uint8Array>({\n start: (c) => {\n controller = c;\n },\n cancel: () => cleanup(),\n });\n controller?.enqueue(sseEvent(out));\n settle({ kind: \"sse\", body });\n return;\n }\n if (ended || !controller) return;\n controller.enqueue(sseEvent(out));\n if (final) {\n ended = true;\n controller.close();\n void cleanup();\n }\n };\n\n const sink = new SinkTransport(deliver);\n const era = new DualEraTransport(sink, server);\n request.signal?.addEventListener(\n \"abort\",\n () => {\n void cleanup();\n if (!settled) {\n settled = true;\n settle({\n kind: \"json\",\n message: errorMessage(route.id, { code: -32603, message: \"request aborted\" }),\n });\n }\n },\n { once: true },\n );\n\n try {\n await server.connect(era);\n const headers: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n headers[key] = value;\n });\n sink.onmessage?.(message as unknown as JSONRPCMessage, {\n requestInfo: { headers, url: new URL(request.url) },\n });\n const answer = await first;\n if (answer.kind === \"json\") {\n await cleanup();\n return jsonResponse(answer.message, statusFor(answer.message), cors);\n }\n return new Response(answer.body, {\n status: 200,\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n \"X-Accel-Buffering\": \"no\",\n ...cors,\n },\n });\n } catch (err) {\n await cleanup();\n return errorResponse(err, cors);\n }\n}\n\n/**\n * Create the request handler. Pass server options, or a factory returning a configured\n * `McpServer` (e.g. one with resources/prompts added) when you need more than tools.\n */\nexport function createHttpHandler(\n opts: HttpHandlerOptions | (() => McpServer),\n transportOptions: HttpTransportOptions = {},\n): HttpHandler {\n const { factory, transport: t } = splitOptions(opts, transportOptions);\n const cors = corsHeaders(t.cors);\n const sessions = t.sessions ? (typeof t.sessions === \"object\" ? t.sessions : {}) : undefined;\n const context: HandlerContext = {\n factory,\n cors,\n transportBase: {\n enableJsonResponse: t.jsonResponse ?? sessions === undefined,\n allowedHosts: t.allowedHosts,\n allowedOrigins: t.allowedOrigins,\n enableDnsRebindingProtection: t.enableDnsRebindingProtection,\n },\n };\n const handler = sessions\n ? createStatefulHandler(context, sessions)\n : createStatelessHandler(context);\n const allow = sessions ? \"GET, POST, DELETE, OPTIONS\" : \"POST, OPTIONS\";\n\n return async (request: Request): Promise<Response> => {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { status: 204, headers: { Allow: allow, ...cors } });\n }\n if (request.method === \"POST\") {\n const peeked = await peek(request);\n if (peeked.kind === \"reject\") return rpcErrorResponse(peeked.route, cors);\n if (peeked.kind === \"modern\") {\n return serveModern(request, peeked.message, peeked.route, context);\n }\n }\n return handler(request);\n };\n}\n\n/** Host header values a localhost server should accept (for `allowedHosts`). */\nexport function localhostHosts(port: number): string[] {\n const hosts = [\"localhost\", \"127.0.0.1\", \"[::1]\"];\n return [...hosts, ...hosts.map((h) => `${h}:${port}`)];\n}\n\nexport interface HealthInfo {\n name: string;\n version: string;\n /** tool count or the tool list */\n tools: number | readonly unknown[];\n}\n\n/** `GET /health` → `{ ok: true, name, version, tools }`. */\nexport function handleHealth(info: HealthInfo): Response {\n const tools = typeof info.tools === \"number\" ? info.tools : info.tools.length;\n return jsonResponse({ ok: true, name: info.name, version: info.version, tools }, 200);\n}\n","/**\n * Bridge a Web-standard `(Request) => Promise<Response>` handler onto `node:http` — for local\n * runs, tests and the conformance suite. Node-only; loaded lazily.\n */\nimport type { HttpHandler } from \"./http.js\";\n\nexport interface NodeHttpOptions {\n handler: HttpHandler;\n /** 0 picks a free port (default 8765) */\n port?: number;\n /** default 127.0.0.1 */\n host?: string;\n /** MCP endpoint path (default `/mcp`) */\n path?: string;\n /** optional `GET /health` responder */\n health?: () => Response;\n}\n\nexport interface NodeHttpServer {\n port: number;\n /** MCP endpoint URL, e.g. `http://127.0.0.1:8765/mcp` */\n url: string;\n close(): Promise<void>;\n}\n\n/** Start a `node:http` server that forwards `path` to the handler. */\nexport async function serveNodeHttp(opts: NodeHttpOptions): Promise<NodeHttpServer> {\n const http = await import(\"node:http\");\n const host = opts.host ?? \"127.0.0.1\";\n const path = opts.path ?? \"/mcp\";\n\n const server = http.createServer((req, res) => {\n void (async () => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? host}`);\n let response: Response;\n if (url.pathname === path) {\n const controller = new AbortController();\n res.on(\"close\", () => {\n if (!res.writableFinished) controller.abort();\n });\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (Array.isArray(value)) for (const item of value) headers.append(key, item);\n else if (typeof value === \"string\") headers.set(key, value);\n }\n const method = req.method ?? \"GET\";\n let body: Uint8Array<ArrayBuffer> | undefined;\n if (method !== \"GET\" && method !== \"HEAD\") {\n const chunks: Buffer[] = [];\n for await (const chunk of req) chunks.push(chunk as Buffer);\n body = new Uint8Array(Buffer.concat(chunks));\n }\n response = await opts.handler(\n new Request(url, { method, headers, body, signal: controller.signal }),\n );\n } else if (url.pathname === \"/health\" && opts.health) {\n response = opts.health();\n } else {\n response = new Response(\n JSON.stringify({\n code: \"NOT_FOUND\",\n cause: `no route for ${url.pathname}`,\n fix: `POST JSON-RPC to ${path}`,\n retryable: false,\n }),\n { status: 404, headers: { \"Content-Type\": \"application/json\" } },\n );\n }\n\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n outHeaders[key] = value;\n });\n res.writeHead(response.status, outHeaders);\n if (!response.body) {\n res.end();\n return;\n }\n const reader = response.body.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n res.write(value);\n }\n } catch {\n // client went away mid-stream\n }\n res.end();\n })().catch((err: unknown) => {\n if (!res.headersSent) res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n code: \"INTERNAL\",\n cause: err instanceof Error ? err.message : String(err),\n fix: \"retry; if it persists, report the request id\",\n retryable: false,\n }),\n );\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(opts.port ?? 8765, host, () => resolve());\n });\n const address = server.address();\n const port = typeof address === \"object\" && address ? address.port : (opts.port ?? 8765);\n return {\n port,\n url: `http://${host}:${port}${path}`,\n close: () =>\n new Promise<void>((resolve, reject) => {\n server.closeAllConnections();\n server.close((err) => (err ? reject(err) : resolve()));\n }),\n };\n}\n","/**\n * x402 verification and settlement through a facilitator.\n *\n * The facilitator is the only piece we do not run: it checks the buyer's signature and\n * submits the on-chain transfer. It never holds the money — USDC moves from the buyer\n * straight to `payTo`, an address we control — so this is not custody, and swapping\n * facilitators is changing one URL.\n *\n * PayAI (https://facilitator.payai.network) is the default because it needs no account,\n * no API key and no business relationship, which is the property that matters: an\n * account is a dependency that can be closed. Coinbase's CDP facilitator implements the\n * same two endpoints and can be dropped in by setting X402_FACILITATOR_URL.\n *\n * Verification is free and moves nothing. Settlement moves money, so it is deliberately\n * a separate call the caller makes only after the work succeeded — a failed call is then\n * never charged at all, which is better than charging and refunding.\n */\nimport type { PaymentRail, PaymentRequirement, PaymentVerifier, VerifyResult } from \"./index.js\";\n\nexport const PAYAI_FACILITATOR_URL = \"https://facilitator.payai.network\";\n\n/** Circle's native USDC on Base mainnet. */\nexport const USDC_BASE = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\";\n\n/** USDC is a 6-decimal token everywhere it is issued. */\nexport const USDC_DECIMALS = 6;\n\n/**\n * The EIP-712 domain of the asset being signed over. The facilitator needs it to reconstruct\n * the buyer's signature; without it, verification fails with\n * `invalid_exact_evm_missing_eip712_domain` and no payment can ever succeed.\n */\nexport const USDC_EIP712_DOMAIN = { name: \"USD Coin\", version: \"2\" };\n\n/**\n * CAIP-2 to the short network names the **v1** verify/settle envelope uses.\n *\n * Only the v1 path needs this. v2 carries CAIP-2 end to end, which is one of the reasons to\n * prefer it: no translation layer between what the 402 advertises and what the facilitator\n * is told.\n */\nconst SHORT_NETWORK: Record<string, string> = {\n \"eip155:8453\": \"base\",\n \"eip155:84532\": \"base-sepolia\",\n \"eip155:137\": \"polygon\",\n \"eip155:80002\": \"polygon-amoy\",\n \"eip155:42161\": \"arbitrum\",\n \"eip155:43114\": \"avalanche\",\n};\n\nexport function toShortNetwork(network: string): string {\n return SHORT_NETWORK[network] ?? network;\n}\n\n/**\n * The x402 `bazaar` extension — how a resource gets into a discovery catalog.\n *\n * There is no registration endpoint (the facilitator's OpenAPI description has only GETs\n * under /discovery). Settling a payment is necessary but **not** sufficient: the catalog is\n * built from this extension, which the resource server declares and the facilitator either\n * accepts or rejects. Without it a resource can be paid for indefinitely and never appear.\n *\n * The facilitator answers in an `EXTENSION-RESPONSES` header — base64 JSON keyed by\n * extension name, `{ bazaar: { status: \"success\" | \"processing\" | \"rejected\", … } }`. That\n * is the only direct feedback there is, so it is surfaced rather than discarded.\n */\nexport interface BazaarExtension {\n info: {\n input: Record<string, unknown>;\n output?: Record<string, unknown>;\n };\n /** JSON Schema (draft 2020-12) that validates `info`. Required by the extension. */\n schema: Record<string, unknown>;\n /** canonical route pattern for a parameterised path, e.g. `/v1/reserves/:symbol` */\n routeTemplate?: string;\n}\n\nexport interface BazaarStatus {\n status?: \"success\" | \"processing\" | \"rejected\";\n rejectedReason?: string;\n}\n\n/**\n * A `bazaar` extension for a plain GET endpoint that answers JSON.\n *\n * The schema is deliberately permissive: its job is to be a valid draft 2020-12 document\n * that `info` satisfies, not to constrain a shape only we produce.\n */\nexport function httpGetBazaar(options: {\n queryParams?: Record<string, string>;\n pathParams?: Record<string, string>;\n routeTemplate?: string;\n outputExample?: unknown;\n}): BazaarExtension {\n return {\n info: {\n input: {\n type: \"http\",\n method: \"GET\",\n ...(options.queryParams ? { queryParams: options.queryParams } : {}),\n ...(options.pathParams ? { pathParams: options.pathParams } : {}),\n },\n ...(options.outputExample !== undefined\n ? { output: { type: \"json\", example: options.outputExample } }\n : {}),\n },\n schema: {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n required: [\"input\"],\n properties: {\n input: { type: \"object\", required: [\"type\"], properties: { type: { type: \"string\" } } },\n output: { type: \"object\" },\n },\n },\n ...(options.routeTemplate ? { routeTemplate: options.routeTemplate } : {}),\n };\n}\n\nexport interface FacilitatorVerifierOptions {\n /** the address USDC is paid to — ours, self-custody */\n payTo: string;\n /** CAIP-2 chain, e.g. eip155:8453 */\n network: string;\n /** token contract; defaults to native USDC on Base */\n asset?: string;\n /** defaults to PayAI */\n facilitatorUrl?: string;\n /** optional bearer token; PayAI works without one, some facilitators require it */\n apiKey?: string;\n /** EIP-712 domain of the asset; defaults to USDC's. Required by the facilitator. */\n assetDomain?: { name: string; version: string };\n /**\n * Decimals of that asset. Defaults to USDC's six.\n *\n * Set it whenever `asset` is set. The price is signed in atomic units, so the wrong decimals\n * do not fail loudly — they authorise a transfer for the wrong amount, off by a factor of a\n * thousand or a million in whichever direction hurts.\n */\n assetDecimals?: number;\n /**\n * Envelope to speak to the facilitator. Defaults to 2.\n *\n * Both settle money identically — the buyer's signature is the same either way — but only\n * v2 settlements appear in the Bazaar discovery catalog, so v1 is a rail that works and\n * cannot be found. Set it to 1 only for a facilitator that rejects v2.\n */\n protocolVersion?: 1 | 2;\n /**\n * Discovery metadata for this resource. Without it the resource is payable but not\n * listable — see BazaarExtension. Ignored on the v1 path, which has no extensions.\n */\n bazaar?: BazaarExtension;\n fetchImpl?: typeof fetch;\n log?: (message: string, data?: Record<string, unknown>) => void;\n}\n\nexport interface SettleResult {\n ok: boolean;\n /** on-chain transaction hash when the transfer landed */\n transaction?: string;\n payer?: string;\n reason?: string;\n /** whether the facilitator catalogued the resource, when it said so */\n bazaar?: BazaarStatus;\n}\n\n/** What the buyer base64s into the X-PAYMENT header; forwarded to the facilitator verbatim. */\ninterface PaymentPayload {\n x402Version?: number;\n scheme?: string;\n network?: string;\n payload?: unknown;\n /** the client's echo of the server's extensions; its presence is what enables them */\n extensions?: Record<string, unknown>;\n}\n\ninterface VerifyResponse {\n isValid?: boolean;\n invalidReason?: string;\n invalidMessage?: string;\n payer?: string;\n}\n\ninterface SettleResponse {\n success?: boolean;\n errorReason?: string;\n errorMessage?: string;\n transaction?: string;\n network?: string;\n payer?: string;\n}\n\n/**\n * Decimal USD string to the token's atomic units.\n *\n * Done on the string rather than via floating point: 0.07 * 1e6 is 70000.00000000001, and\n * a price that rounds wrong is a payment the facilitator rejects for the wrong amount.\n */\nexport function toAtomicUnits(amountUsd: string, decimals = USDC_DECIMALS): string {\n const trimmed = amountUsd.trim();\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) throw new Error(`not a decimal amount: ${amountUsd}`);\n const [whole = \"0\", fraction = \"\"] = trimmed.split(\".\");\n if (fraction.length > decimals) {\n throw new Error(`${amountUsd} has more than ${decimals} decimal places`);\n }\n return `${whole}${fraction.padEnd(decimals, \"0\")}`.replace(/^0+(?=\\d)/, \"\");\n}\n\n/** The buyer's payment, or undefined when the request carries none. */\nfunction readPaymentHeader(request: Request): PaymentPayload | undefined {\n const raw = request.headers.get(\"X-PAYMENT\") ?? request.headers.get(\"PAYMENT\");\n if (!raw) return undefined;\n try {\n // base64 JSON per the spec; tolerate a bare JSON body from a hand-rolled client\n const text = raw.trim().startsWith(\"{\") ? raw : new TextDecoder().decode(base64ToBytes(raw));\n return JSON.parse(text) as PaymentPayload;\n } catch {\n return undefined;\n }\n}\n\nfunction base64ToBytes(b64: string): Uint8Array {\n const binary = atob(b64.trim());\n const out = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);\n return out;\n}\n\nexport interface FacilitatorVerifier extends PaymentVerifier {\n settle(verified: VerifyResult): Promise<SettleResult>;\n}\n\nexport function createFacilitatorVerifier(\n options: FacilitatorVerifierOptions,\n): FacilitatorVerifier {\n const base = (options.facilitatorUrl ?? PAYAI_FACILITATOR_URL).replace(/\\/+$/, \"\");\n const asset = options.asset ?? USDC_BASE;\n const doFetch = options.fetchImpl ?? fetch;\n const log = options.log ?? (() => undefined);\n const version = options.protocolVersion ?? 2;\n\n function requirementsFor(requirement: PaymentRequirement): Record<string, unknown> {\n // Without `extra` the facilitator cannot rebuild the signature and refuses every payment\n // with invalid_exact_evm_missing_eip712_domain.\n const extra = options.assetDomain ?? USDC_EIP712_DOMAIN;\n const amount = toAtomicUnits(requirement.amountUsd, options.assetDecimals);\n const maxTimeoutSeconds = requirement.maxTimeoutSeconds ?? 300;\n\n if (version === 2) {\n // v2 renamed maxAmountRequired to amount and carries CAIP-2 networks unchanged.\n //\n // `resource` is not in the v2 schema and the facilitator does not require it, but it is\n // the only thing that ties a settlement to a URL — a discovery catalog of resources\n // cannot list a payment that names no resource. It is accepted, so send it.\n return {\n scheme: \"exact\",\n network: options.network,\n amount,\n asset,\n payTo: options.payTo,\n maxTimeoutSeconds,\n resource: requirement.resource,\n description: requirement.description ?? \"\",\n mimeType: \"application/json\",\n extra,\n };\n }\n return {\n scheme: \"exact\",\n network: toShortNetwork(options.network),\n maxAmountRequired: amount,\n resource: requirement.resource,\n description: requirement.description ?? \"\",\n mimeType: \"application/json\",\n payTo: options.payTo,\n maxTimeoutSeconds,\n asset,\n extra,\n };\n }\n\n /**\n * The buyer's payload, restated in the envelope the facilitator accepts.\n *\n * v2 nests the terms the buyer agreed to as `accepted` *inside* the payload — that nesting\n * is the whole difference, and getting it wrong returns `invalid_payment_requirements:\n * \": Invalid input\"`, which names no field. v1 instead flattens scheme and network next to\n * the payload.\n */\n function payloadFor(\n payment: PaymentPayload,\n accepted: Record<string, unknown>,\n ): Record<string, unknown> {\n if (version === 2) {\n return {\n x402Version: 2,\n // Not required alongside `accepted`, but the facilitator's own OpenAPI description\n // lists scheme and network as required on a payment payload, and the discovery\n // catalog records a network per resource. Sending them costs nothing.\n scheme: payment.scheme ?? \"exact\",\n network: options.network,\n // A payload-level `resource` OBJECT — a string here is rejected. Every catalogued\n // entry carries url, type, method, description and mimeType, which is exactly this\n // shape, so this is the most likely thing the catalog is built from.\n resource: {\n url: accepted[\"resource\"],\n type: \"http\",\n method: \"GET\",\n description: accepted[\"description\"],\n mimeType: accepted[\"mimeType\"],\n },\n accepted,\n payload: payment.payload,\n // the client's echo, verbatim: the facilitator compares it against serverExtensions\n ...(payment.extensions ? { extensions: payment.extensions } : {}),\n };\n }\n return {\n x402Version: 1,\n scheme: payment.scheme ?? \"exact\",\n network: toShortNetwork(payment.network ?? options.network),\n payload: payment.payload,\n };\n }\n\n /**\n * v2 only: extensions the resource server declares.\n *\n * Sent **only when the client echoed one back**. Declaring an extension the client did not\n * echo is refused outright — `403 Extension validation failed: client must echo server\n * extensions` — so sending it unconditionally would turn every payment from an older client\n * into a refusal. Discovery is worth having; it is not worth failing a sale for.\n */\n function serverExtensions(payment: PaymentPayload, declared: unknown): Record<string, unknown> {\n const bazaar = declared ?? options.bazaar;\n if (version !== 2 || !bazaar) return {};\n if (!payment.extensions?.[\"bazaar\"]) return {};\n return { serverExtensions: { bazaar } };\n }\n\n type Call<T> =\n { reached: true; body: T; bazaar?: BazaarStatus } | { reached: false; error: string };\n\n /** `EXTENSION-RESPONSES`: base64 JSON keyed by extension name. Absent on the v1 path. */\n function readBazaarStatus(headers: Headers): BazaarStatus | undefined {\n const raw = headers.get(\"extension-responses\");\n if (!raw) return undefined;\n try {\n const text = new TextDecoder().decode(base64ToBytes(raw));\n return (JSON.parse(text) as Record<string, BazaarStatus>)[\"bazaar\"];\n } catch {\n return undefined;\n }\n }\n\n async function call<T>(path: string, body: unknown): Promise<Call<T>> {\n try {\n const res = await doFetch(`${base}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(options.apiKey ? { authorization: `Bearer ${options.apiKey}` } : {}),\n },\n body: JSON.stringify(body),\n });\n // Check the status before the body. A facilitator answering 500 or 403 can still return\n // JSON carrying `isValid` or `success`, and reading it regardless means an error page\n // decides whether we were paid. This rail must fail closed.\n if (!res.ok && res.status >= 500) {\n return { reached: false, error: `facilitator returned HTTP ${res.status}` };\n }\n const bazaar = readBazaarStatus(res.headers);\n // A rejected declaration is silent otherwise: payments keep working and the resource\n // simply never appears in the catalog, which is the failure that took longest to see.\n if (bazaar?.status === \"rejected\") {\n log(\"x402 bazaar listing rejected\", { reason: bazaar.rejectedReason });\n }\n return { reached: true, body: (await res.json()) as T, ...(bazaar ? { bazaar } : {}) };\n } catch (err) {\n return { reached: false, error: err instanceof Error ? err.message : String(err) };\n }\n }\n\n return {\n /**\n * Checks the buyer's signature. Free, and moves nothing — call `settle` once the work\n * has actually succeeded.\n */\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const payment = readPaymentHeader(request);\n if (!payment) {\n return { ok: false, rail: \"x402\", reason: \"no payment header present\" };\n }\n const paymentRequirements = requirementsFor(requirement);\n const call1 = await call<VerifyResponse>(\"/verify\", {\n x402Version: version,\n paymentPayload: payloadFor(payment, paymentRequirements),\n // v2 keeps this alongside the payload as well as inside it. PayAI rejects the body\n // outright without it, so it is not the redundancy it looks like.\n paymentRequirements,\n ...serverExtensions(payment, requirement.bazaar),\n });\n if (!call1.reached) {\n // Fail closed: an unreachable facilitator must never be read as a valid payment.\n log(\"x402 facilitator unreachable\", { error: call1.error });\n return { ok: false, rail: \"x402\", reason: \"payment facilitator unreachable\" };\n }\n const verified = call1.body;\n if (!verified.isValid) {\n return {\n ok: false,\n rail: \"x402\",\n reason: verified.invalidReason\n ? `${verified.invalidReason}${verified.invalidMessage ? `: ${verified.invalidMessage}` : \"\"}`\n : \"payment refused by the facilitator\",\n };\n }\n return {\n ok: true,\n rail: \"x402\",\n // everything settle() needs, so it does not have to re-read the request\n receipt: {\n payment,\n paymentRequirements,\n payer: verified.payer,\n // settle() never sees the requirement again, so carry the declaration with it\n ...(requirement.bazaar ? { bazaar: requirement.bazaar } : {}),\n },\n };\n },\n\n /** Submits the transfer. Only call this once the paid work has succeeded. */\n async settle(verified: VerifyResult): Promise<SettleResult> {\n const receipt = verified.receipt as\n | {\n payment: PaymentPayload;\n paymentRequirements: Record<string, unknown>;\n bazaar?: unknown;\n }\n | undefined;\n if (!receipt?.payment) return { ok: false, reason: \"nothing to settle\" };\n const call2 = await call<SettleResponse>(\"/settle\", {\n x402Version: version,\n paymentPayload: payloadFor(receipt.payment, receipt.paymentRequirements),\n paymentRequirements: receipt.paymentRequirements,\n ...serverExtensions(receipt.payment, receipt.bazaar),\n });\n if (!call2.reached) {\n log(\"x402 settlement failed to reach the facilitator\", { error: call2.error });\n return { ok: false, reason: call2.error };\n }\n const result = call2.body;\n if (!result.success) {\n // The buyer already has the resource. Worth logging loudly: it is lost revenue,\n // not a failed request, and the caller should not turn it into an error.\n log(\"x402 settlement refused after the work was served\", {\n reason: result.errorReason,\n message: result.errorMessage,\n });\n return {\n ok: false,\n reason: result.errorReason ?? \"settlement refused\",\n ...(result.payer ? { payer: result.payer } : {}),\n };\n }\n if (call2.bazaar) log(\"x402 bazaar listing\", { ...call2.bazaar });\n // A settlement we cannot name cannot be made idempotent: the caller keys the credit on\n // this hash, and without one it would invent a fresh key per attempt and credit the same\n // authorisation again on every retry. Treat it as unsettled rather than as money.\n if (!result.transaction) {\n log(\"x402 settlement reported success with no transaction\", { payer: result.payer });\n return {\n ok: false,\n reason:\n \"the facilitator reported success but named no transaction, so the payment cannot be confirmed\",\n ...(result.payer ? { payer: result.payer } : {}),\n };\n }\n return {\n ok: true,\n transaction: result.transaction,\n ...(result.payer ? { payer: result.payer } : {}),\n ...(call2.bazaar ? { bazaar: call2.bazaar } : {}),\n };\n },\n };\n}\n\n/**\n * One verifier over several rails: try each in turn, first acceptance wins.\n *\n * A caller presents whatever it has — a USDC payment header or a prepaid key — and should\n * not have to be told which rail the server prefers. Refusals are reported from the rail\n * that got furthest: \"insufficient credit\" is useful, \"no payment header present\" from a\n * rail the caller never intended to use is noise.\n *\n * `settle` dispatches on the rail that accepted, so a rail that already took its money\n * during verification is never asked to take it twice.\n */\nexport function createAnyVerifier(verifiers: readonly PaymentVerifier[]): PaymentVerifier {\n return {\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const refusals: VerifyResult[] = [];\n for (const verifier of verifiers) {\n const result = await verifier.verify(request, requirement);\n if (result.ok) return result;\n refusals.push(result);\n }\n const informative = refusals.find(\n (r) => r.reason && !/no payment header|no API key/i.test(r.reason),\n );\n return informative ?? refusals[0] ?? { ok: false, reason: \"no payment presented\" };\n },\n async settle(verified: VerifyResult) {\n const owner = verifiers.find(\n (v) => v.settle && verified.rail !== undefined && railOf(v) === verified.rail,\n );\n const settled = await owner?.settle?.(verified);\n if (settled) return settled;\n // No verifier owns this rail's settlement. That is correct for a rail which already took\n // its money during verification (prepaid credits), and a bug for anything else — so say\n // which, rather than reporting a success nobody performed.\n if (verified.rail === \"prepaid_credits\") return { ok: true };\n return {\n ok: false,\n reason: `nothing settles the ${verified.rail ?? \"unknown\"} rail on this deployment`,\n };\n },\n };\n}\n\n/** Which rail a verifier settles. Only the facilitator verifier settles anything today. */\nfunction railOf(verifier: PaymentVerifier): PaymentRail | undefined {\n return \"settle\" in verifier && typeof verifier.settle === \"function\" ? \"x402\" : undefined;\n}\n","/**\n * @agentwares/x402 — 402 Payment Required helper + verifier interface.\n *\n * The 402 body advertises both rails. Both settle; only one of them settles without a person:\n *\n * - **prepaid_credits (card, via Stripe)** — live. `payTo` is a self-serve endpoint that mints a\n * prepaid key and hands back a Stripe Checkout URL, so an agent can go from a 402 to\n * a paid call without a human. The verifier lives in `@agentwares/billing`\n * (`createCreditsVerifier`), which is where the database and the Stripe client are.\n * - **x402 (USDC on Base)** — live, and the only rail an unattended agent can complete.\n * `createFacilitatorVerifier` checks the buyer's EIP-3009 signature with the PayAI\n * facilitator and settles after the work succeeds. `StubVerifier` remains for a\n * deployment with no receiving address, where it refuses rather than pretending.\n *\n * Nothing here holds funds.\n */\n\n/**\n * `prepaid_credits` is deliberately not called `mpp`. MPP is the Machine Payments Protocol\n * (Stripe + Tempo, March 2026): pre-authorised spending sessions an agent settles on its own.\n * This rail is a Stripe Checkout page that funds a balance — a different thing, needing a\n * person. An agent that knows MPP and sees `mpp` will attempt MPP semantics and fail, so the\n * name stays free for a real implementation.\n */\nimport { USDC_BASE, USDC_EIP712_DOMAIN, toAtomicUnits } from \"./facilitator.js\";\n\nexport type PaymentRail = \"x402\" | \"prepaid_credits\";\n\nexport interface PaymentRequirement {\n rail: PaymentRail;\n /** decimal USD string, e.g. \"0.05\" */\n amountUsd: string;\n /** resource being paid for, usually the request URL or tool name */\n resource: string;\n description?: string;\n /** x402: network + asset; mpp: currency */\n network?: string;\n /**\n * x402: the token's **contract address**, not its symbol.\n *\n * It used to be the string \"USDC\", which no client can act on — a buyer needs the address to\n * build the EIP-3009 signature. Every catalogued resource in the Bazaar carries an address\n * here; ours carried a ticker, and that alone made our 402s unpayable by anything but our\n * own script.\n */\n asset?: string;\n currency?: string;\n /**\n * x402: the settlement scheme. `exact` is the only one defined today, and a client that\n * does not see it cannot tell which signature to produce.\n */\n scheme?: string;\n /** x402: the price in the token's atomic units, which is what gets signed. */\n amount?: string;\n /**\n * x402: the EIP-712 domain of the asset. Without it a buyer cannot build the typed data and\n * the facilitator rejects the payment with `invalid_exact_evm_missing_eip712_domain`.\n */\n extra?: Record<string, unknown>;\n /** x402: the media type of what payment buys. */\n mimeType?: string;\n /** where to pay; absent while payments are not live */\n payTo?: string;\n /** seconds the quote is valid */\n maxTimeoutSeconds?: number;\n /**\n * True when settling this rail needs a person — today, a hosted Stripe Checkout card form.\n * An autonomous caller should pick a requirement without this flag; one that has it is\n * offered so an agent working alongside a human can hand the URL over rather than fail.\n */\n humanRequired?: boolean;\n /**\n * Discovery metadata for the x402 `bazaar` extension, when this resource declares one.\n * Carried per requirement rather than per verifier so a product with several priced routes\n * can describe each one; see BazaarExtension in ./facilitator.ts.\n */\n bazaar?: Record<string, unknown>;\n}\n\n/** Everything an agent needs to buy a key and fund it without a human. */\nexport interface SelfServe {\n /** POST here with no auth to get a key with a zero balance + a Checkout URL. */\n keysUrl: string;\n /** GET with the key to read the balance; POST to create another top-up. */\n creditsUrl?: string;\n /**\n * POST here with the key to fund it in USDC over x402 — the only top-up an unattended\n * agent can finish. `creditsUrl` ends at a hosted card page.\n */\n creditsX402Url?: string;\n /** credit pack sizes in USD */\n packsUsd: number[];\n /** header that makes a retried paid call charge only once */\n idempotencyHeader: \"Idempotency-Key\";\n}\n\nexport interface PaymentRequiredBody {\n code: \"PAYMENT_REQUIRED\";\n cause: string;\n fix: string;\n retryable: true;\n priceUsd: number;\n accepts: PaymentRequirement[];\n /** true while neither rail can actually be settled */\n comingSoon: boolean;\n /** how to pay today: API key + prepaid credits */\n alternatives: string[];\n /** present once the card rail is live: the whole no-human purchase path */\n selfServe?: SelfServe;\n /**\n * x402 v2 extensions. `bazaar` is discovery metadata a client is expected to echo back in\n * its payment payload; without that echo the facilitator will not catalog the resource, so\n * a resource that omits this is payable but permanently unlistable.\n */\n extensions?: Record<string, unknown>;\n}\n\nexport interface PaymentRequiredResponse {\n status: 402;\n headers: Record<string, string>;\n body: PaymentRequiredBody;\n}\n\nexport interface BuildPaymentRequiredOptions {\n resource: string;\n priceUsd: number;\n description?: string;\n /** set once a rail can actually be settled (drops `comingSoon`) */\n live?: boolean;\n /** x402 rail: the USDC address payment is sent to. Unset = the rail is not advertised. */\n payTo?: string;\n /** CAIP-2 chain for the x402 rail; Base mainnet unless the receive address lives elsewhere. */\n network?: string;\n /** x402 token contract address. Defaults to USDC on Base; set it when the chain differs. */\n asset?: string;\n /** EIP-712 domain of that token. Must match the asset or the facilitator rejects the payment. */\n assetDomain?: Record<string, unknown>;\n /**\n * Decimals of that token. Defaults to USDC's six.\n *\n * Set it whenever `asset` is set, and set the same value on the verifier. The price is signed\n * in atomic units, so the wrong decimals do not fail loudly — the 402 quotes an amount off by\n * a factor of a thousand or a million, and a buyer signs for exactly that.\n */\n assetDecimals?: number;\n /** prepaid_credits rail: the URL that takes a card and funds a balance. */\n creditsPayTo?: string;\n signupUrl?: string;\n /** the no-human purchase path; included in the body when the card rail is live */\n selfServe?: SelfServe;\n /**\n * Discovery metadata for the x402 `bazaar` extension. Advertised in the 402 so a client\n * can echo it; see BazaarExtension in ./facilitator.ts for why that echo is the whole\n * mechanism.\n */\n bazaar?: Record<string, unknown>;\n /**\n * True when this resource really does answer `sample=true` free and keyless.\n *\n * The 402's `fix` prose used to promise one unconditionally, which was a lie on every\n * product without sample mode and absurd on a credit top-up. An agent that believes it\n * spends a call finding out.\n */\n sampleMode?: boolean;\n}\n\n/** Base mainnet. The CDP facilitator also settles Polygon, Arbitrum, World and Solana. */\nexport const DEFAULT_X402_NETWORK = \"eip155:8453\";\n\nexport const X402_HEADER = \"X-Payment-Requirements\";\nexport const X402_REQUIRED_HEADER = \"PAYMENT-REQUIRED\";\n\nfunction toAmount(priceUsd: number): string {\n if (!Number.isFinite(priceUsd) || priceUsd < 0)\n throw new Error(\"priceUsd must be a non-negative number\");\n return priceUsd.toFixed(6).replace(/0+$/, \"\").replace(/\\.$/, \".0\");\n}\n\n/** Build the 402 response (status, headers, JSON body) for a paid resource. */\nexport function buildPaymentRequired(opts: BuildPaymentRequiredOptions): PaymentRequiredResponse {\n const amountUsd = toAmount(opts.priceUsd);\n // `accepts` is a promise that the rail can be settled, so a rail with nowhere to send the\n // money is left out entirely. The x402 entry used to be advertised with `payTo: undefined`\n // while no CDP account existed: an agent that picked it had no address to pay and burned a\n // retry on a method we could never have honoured.\n const creditsPayTo = opts.creditsPayTo ?? opts.selfServe?.keysUrl;\n const accepts: PaymentRequirement[] = [];\n if (opts.payTo) {\n // The fields a standard x402 client needs to construct a payment, in the shape every\n // catalogued resource in the Bazaar actually serves: `scheme`, the price in atomic units,\n // the token's contract address and its EIP-712 domain.\n //\n // These were missing. The entry carried `amountUsd: \"0.02\"` and `asset: \"USDC\"`, which is\n // readable by a person and unusable by a buyer: no scheme to pick, no atomic amount to\n // sign, and a ticker where the signature needs an address. Our own bootstrap script filled\n // the gaps from local knowledge, which is why payments settled in testing and never once\n // from outside. `rail` and `amountUsd` stay because they are useful and harmless.\n accepts.push({\n rail: \"x402\",\n scheme: \"exact\",\n amountUsd,\n amount: toAtomicUnits(amountUsd, opts.assetDecimals),\n resource: opts.resource,\n description: opts.description,\n mimeType: \"application/json\",\n network: opts.network ?? DEFAULT_X402_NETWORK,\n asset: opts.asset ?? USDC_BASE,\n extra: opts.assetDomain ?? USDC_EIP712_DOMAIN,\n payTo: opts.payTo,\n maxTimeoutSeconds: 300,\n ...(opts.bazaar ? { bazaar: opts.bazaar } : {}),\n });\n }\n if (creditsPayTo) {\n accepts.push({\n rail: \"prepaid_credits\",\n amountUsd,\n resource: opts.resource,\n description: opts.description,\n currency: \"usd\",\n payTo: creditsPayTo,\n maxTimeoutSeconds: 300,\n // funding a balance ends at a hosted Stripe Checkout page, which an agent cannot fill in\n humanRequired: true,\n });\n }\n const live = opts.live === true;\n const selfServe = opts.selfServe;\n // Say plainly which step a machine can do and which one it cannot. An agent that reads\n // \"pay the card form\" as an instruction to itself will loop: the Checkout URL is a hosted\n // web page.\n //\n // Order matters more than it looks. Many agents act on `fix` prose rather than parsing\n // `accepts`, so whatever is named first is what gets attempted. This text used to describe\n // only the card rail — the one that needs a person — while the USDC rail settled fine and\n // went unmentioned, which told every unattended caller to give up in front of a working\n // checkout. Lead with the rail that needs nobody.\n const x402Rail = accepts.find((a) => a.rail === \"x402\" && a.payTo);\n const usdcFix = x402Rail\n ? `Pay in USDC with no account and no human: take the \\`accepts\\` entry with ` +\n `\\`rail: \"x402\"\\`, sign an EIP-3009 transferWithAuthorization for ${x402Rail.amountUsd} ` +\n `USDC to ${x402Rail.payTo} on ${x402Rail.network}, and retry with it base64 in the ` +\n `X-PAYMENT header. The facilitator submits the transfer, so you need USDC and no gas. `\n : \"\";\n // Only when there is one. This was unconditional, so every 402 in the portfolio promised a\n // free sample — including products that have none, and including the credit top-up endpoint,\n // where it read as an offer of free credit.\n const sampleFix = opts.sampleMode\n ? \"Free first: retry with sample=true — no key, no payment. \"\n : \"\";\n const cardFix = selfServe\n ? `Or pay by card: POST ${selfServe.keysUrl} (no auth, no signup) returns a key and a Stripe ` +\n `Checkout URL. Funding that key needs a person at a browser; if you are running unattended, ` +\n `surface the URL to your operator rather than retrying, or use the USDC rail above. Once ` +\n `funded, send Authorization: Bearer <key>, plus Idempotency-Key so a repeated call is ` +\n `charged once.`\n : \"\";\n const liveFix =\n usdcFix || cardFix\n ? `${sampleFix}${usdcFix}${cardFix}`.trim()\n : \"Retry with a PAYMENT header satisfying one of `accepts`, or send an API key with credit balance.\";\n const body: PaymentRequiredBody = {\n code: \"PAYMENT_REQUIRED\",\n cause: live\n ? `This call costs $${amountUsd}. No valid payment or credit was presented.`\n : `This call costs $${amountUsd}. Pay-per-call (x402 / Stripe MPP) is coming soon; use an API key with prepaid credits.`,\n fix: live\n ? liveFix\n : `Create an API key${opts.signupUrl ? ` at ${opts.signupUrl}` : \"\"} and retry with Authorization: Bearer <key>. Try the free sample mode first.`,\n retryable: true,\n priceUsd: opts.priceUsd,\n accepts,\n comingSoon: !live,\n alternatives: [\n ...(creditsPayTo ? [\"api_key_credits\"] : []),\n ...(opts.sampleMode ? [\"sample_mode\"] : []),\n ],\n ...(selfServe ? { selfServe } : {}),\n ...(opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}),\n };\n // The machine-readable header carries the extension too: a client that reads only the\n // header, which the spec allows, still sees what it has to echo.\n const encoded = JSON.stringify({\n x402Version: 2,\n accepts,\n resource: opts.resource,\n ...(opts.bazaar ? { extensions: { bazaar: opts.bazaar } } : {}),\n });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": `Payment realm=\"agentwares\", methods=\"x402 prepaid_credits\", price=\"${amountUsd} USD\"`,\n [X402_HEADER]: encoded,\n [X402_REQUIRED_HEADER]: btoa(encoded),\n \"Cache-Control\": \"no-store\",\n };\n return { status: 402, headers, body };\n}\n\nexport interface VerifyResult {\n ok: boolean;\n rail?: PaymentRail;\n receipt?: unknown;\n reason?: string;\n}\n\n/** Given a request, decide whether it carries a valid payment. */\nexport interface PaymentVerifier {\n verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult>;\n /**\n * Optional second step for rails where verifying and taking the money are separate acts.\n * x402 works this way: checking a signature is free, submitting the transfer is not, so\n * settlement happens only after the paid work succeeded and a failed call is never\n * charged. Rails that debit during `verify` (prepaid credits) leave this unimplemented\n * and refund through `onPaidFailure` instead.\n */\n settle?(verified: VerifyResult): Promise<{ ok: boolean; reason?: string }>;\n}\n\n/**\n * Never accepts a payment, never touches funds. Still the verifier for the x402/USDC rail\n * (no CDP account yet); the card rail uses `createCreditsVerifier` from @agentwares/billing.\n */\nexport class StubVerifier implements PaymentVerifier {\n async verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult> {\n const hasHeader = request.headers.has(\"PAYMENT\") || request.headers.has(\"X-PAYMENT\");\n return {\n ok: false,\n rail: requirement.rail,\n reason: hasHeader\n ? \"payments are not live yet (phase 2: wallet). Use an API key with credits.\"\n : \"no payment header present\",\n };\n }\n}\n\n/** Convenience: a Web-standard Response for the 402. */\nexport function paymentRequiredResponse(opts: BuildPaymentRequiredOptions): Response {\n const r = buildPaymentRequired(opts);\n return new Response(JSON.stringify(r.body), { status: r.status, headers: r.headers });\n}\n\nexport * from \"./facilitator.js\";\n","/**\n * Reading every page of a cursor-paginated MCP list (`tools/list`, `resources/list`,\n * `prompts/list`, …), bounded, and never a silent partial list.\n *\n * MCP paginates these with an opaque `nextCursor`; the last page omits it. A reader that stops\n * after one page, or at a fixed page count without saying so, hides whatever comes after — a\n * proxy cannot reach those tools, and a monitor reads them as removed. A reader with no bound\n * loops forever on a server that hands back the cursor it was given.\n *\n * {@link readAllPages} follows the cursor until it is absent or empty, stops at a cursor it has\n * already followed, and stops at a ceiling with `truncated` set, so the caller decides what a\n * partial list is worth: an error, the last good list, or the partial list with a warning. It\n * takes the page fetch as a callback, so it works over the SDK client, a raw JSON-RPC POST, or\n * anything else, and uses only Web-standard JavaScript (Node, Workers, browsers).\n *\n * Same semantics as agentcheck's `McpClient.listTools()` (BUG-2).\n */\n\n/** Pages read before a list counts as truncated (what mcpcheck and mcp-liveness follow). */\nexport const LIST_MAX_PAGES = 20;\n/**\n * Items read before a list counts as truncated. Above the largest tool catalog in\n * mcp-liveness's October 2026 census of the MCP registry (1,408 tools; 128 of 13,235 answering\n * servers list more than 100).\n */\nexport const LIST_MAX_ITEMS = 2_000;\n\nexport interface ListPage<T> {\n items: readonly T[];\n /** the page's `nextCursor`, as the server sent it; anything but a non-empty string ends the list */\n nextCursor?: unknown;\n}\n\nexport interface ReadAllPagesOptions {\n /** default {@link LIST_MAX_PAGES} */\n maxPages?: number;\n /** default {@link LIST_MAX_ITEMS} */\n maxItems?: number;\n /** the method, for the truncation reason (default `\"tools/list\"`) */\n method?: string;\n}\n\nexport interface ListTruncation {\n ceiling: \"pages\" | \"items\";\n /** one sentence a log line, a status field or a cell summary can carry as it is */\n reason: string;\n}\n\nexport interface ReadAllPagesResult<T> {\n /** every item read, in page order; when `truncated` is set, only the pages read */\n items: T[];\n pages: number;\n /** set when a ceiling stopped the read: `items` is then NOT the whole list */\n truncated?: ListTruncation;\n /**\n * true when the read ended at a cursor it had already followed. Not a truncation: following\n * it again could only return pages already read, so `items` is everything the server serves.\n */\n repeatedCursor?: true;\n}\n\n/**\n * Read every page. `fetchPage(cursor, page)` gets `undefined` for the first page (send no\n * cursor) and each `nextCursor` after that; `page` counts from 1. Errors from `fetchPage`\n * propagate unchanged.\n */\nexport async function readAllPages<T>(\n fetchPage: (cursor: string | undefined, page: number) => Promise<ListPage<T>>,\n opts: ReadAllPagesOptions = {},\n): Promise<ReadAllPagesResult<T>> {\n const maxPages = opts.maxPages ?? LIST_MAX_PAGES;\n const maxItems = opts.maxItems ?? LIST_MAX_ITEMS;\n const method = opts.method ?? \"tools/list\";\n const items: T[] = [];\n const followed = new Set<string>();\n let cursor: string | undefined;\n for (let page = 1; ; page++) {\n const res = await fetchPage(cursor, page);\n if (Array.isArray(res.items)) items.push(...res.items);\n const next = res.nextCursor;\n const more = typeof next === \"string\" && next !== \"\";\n if (items.length > maxItems) {\n return {\n items,\n pages: page,\n truncated: {\n ceiling: \"items\",\n reason: `${method} listed more than ${maxItems} items in ${page} page${page === 1 ? \"\" : \"s\"}${more ? \" and had more\" : \"\"}; at most ${maxItems} are read`,\n },\n };\n }\n if (!more) return { items, pages: page };\n if (followed.has(next)) return { items, pages: page, repeatedCursor: true };\n if (page >= maxPages) {\n return {\n items,\n pages: page,\n truncated: {\n ceiling: \"pages\",\n reason: `${method} had more than ${maxPages} pages (${items.length} items read); at most ${maxPages} pages are read`,\n },\n };\n }\n followed.add(next);\n cursor = next;\n }\n}\n","/**\n * `serveStdio` — the same tools over stdio (Claude Desktop, Cursor, `npx` launchers).\n * The only module in the kit that touches Node APIs; loaded lazily so Web-standard bundles\n * never pull it in.\n *\n * Dual-era: the 2026-07-28 stdio binding has no headers, so a request carrying the modern\n * `_meta` envelope is recognised by its body alone (./modern.ts). `server/discover` — the probe\n * a dual-era client sends first on stdio — is answered; `initialize` opens a 2025-era session as\n * before. Both can be served by the same process.\n */\nimport type { Readable, Writable } from \"node:stream\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { DualEraTransport } from \"./modern.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\nexport interface StdioStreams {\n /** default `process.stdin` */\n stdin?: Readable;\n /** default `process.stdout` */\n stdout?: Writable;\n}\n\n/** Connect over stdio. Resolves when the transport closes (stdin ends). */\nexport async function serveStdio(\n serverOrOpts: McpServer | McpServerOptions,\n streams: StdioStreams = {},\n): Promise<void> {\n const server = serverOrOpts instanceof McpServer ? serverOrOpts : createMcpServer(serverOrOpts);\n const { StdioServerTransport } = await import(\"@modelcontextprotocol/sdk/server/stdio.js\");\n const transport = new DualEraTransport(\n new StdioServerTransport(streams.stdin, streams.stdout),\n server,\n );\n await server.connect(transport);\n await new Promise<void>((resolve) => {\n const previous = transport.onclose;\n transport.onclose = () => {\n previous?.();\n resolve();\n };\n });\n}\n","/**\n * Official MCP registry: `server.json` generator and the GitHub Actions workflow that publishes\n * it on tag via `mcp-publisher` with GitHub OIDC (no secrets).\n *\n * Field names follow the 2025-12-11 server.json schema\n * (https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json).\n */\n\nexport const SERVER_JSON_SCHEMA_URL =\n \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\";\n\n/** `^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$` — reverse-DNS namespace, one slash, server name. */\nexport const SERVER_NAME_PATTERN = /^[a-zA-Z0-9.-]+\\/[a-zA-Z0-9._-]+$/;\nconst MAX_DESCRIPTION_LENGTH = 100;\n\nexport interface ServerJsonRepository {\n url: string;\n source: \"github\";\n /** path inside a monorepo, e.g. `shelf/deal-memo` */\n subfolder?: string;\n}\n\nexport interface ServerJsonKeyValueInput {\n name: string;\n description?: string;\n isRequired?: boolean;\n isSecret?: boolean;\n default?: string;\n format?: \"string\" | \"number\" | \"boolean\" | \"filepath\";\n}\n\nexport interface ServerJsonNpmPackage {\n /** npm package name, e.g. `@agentwares/deal-memo-mcp` */\n identifier: string;\n version: string;\n /** default `npx` */\n runtimeHint?: string;\n environmentVariables?: ServerJsonKeyValueInput[];\n}\n\nexport interface GenerateServerJsonOptions {\n /** reverse-DNS, e.g. `io.github.agentwares/deal-memo` (OIDC publishing needs `io.github.<owner>/`) */\n name: string;\n /** ≤ 100 chars, capabilities not implementation */\n description: string;\n version: string;\n title?: string;\n repository: ServerJsonRepository;\n websiteUrl?: string;\n /** stdio package published to npm (package.json must carry `mcpName: <name>`) */\n npmPackage?: ServerJsonNpmPackage;\n /** hosted Streamable HTTP endpoint, e.g. `https://deal-memo.agentwares.dev/mcp` */\n remoteUrl?: string;\n /** headers the client must send to the remote (e.g. an API key input) */\n remoteHeaders?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJsonPackage {\n registryType: \"npm\";\n registryBaseUrl: string;\n identifier: string;\n version: string;\n runtimeHint?: string;\n transport: { type: \"stdio\" };\n environmentVariables?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJsonRemote {\n type: \"streamable-http\";\n url: string;\n headers?: ServerJsonKeyValueInput[];\n}\n\nexport interface ServerJson {\n $schema: string;\n name: string;\n description: string;\n title?: string;\n version: string;\n websiteUrl?: string;\n repository: ServerJsonRepository;\n packages?: ServerJsonPackage[];\n remotes?: ServerJsonRemote[];\n}\n\n/** Build a `server.json` object for the official MCP registry. Validates the fields it can. */\nexport function generateServerJson(opts: GenerateServerJsonOptions): ServerJson {\n if (!SERVER_NAME_PATTERN.test(opts.name)) {\n throw new Error(\n `server.json name must be reverse-DNS with exactly one slash (e.g. io.github.acme/my-server), got ${JSON.stringify(opts.name)}`,\n );\n }\n const description = opts.description.trim();\n if (description.length === 0 || description.length > MAX_DESCRIPTION_LENGTH) {\n throw new Error(\n `server.json description must be 1-${MAX_DESCRIPTION_LENGTH} characters, got ${description.length}`,\n );\n }\n if (!opts.version.trim()) throw new Error(\"server.json version is required\");\n if (!opts.npmPackage && !opts.remoteUrl) {\n throw new Error(\n \"server.json needs at least one of npmPackage (stdio) or remoteUrl (streamable-http)\",\n );\n }\n if (opts.remoteUrl !== undefined && !/^https?:\\/\\/\\S+$/.test(opts.remoteUrl)) {\n throw new Error(`remoteUrl must be an http(s) URL, got ${JSON.stringify(opts.remoteUrl)}`);\n }\n\n const json: ServerJson = {\n $schema: SERVER_JSON_SCHEMA_URL,\n name: opts.name,\n description,\n version: opts.version,\n repository: { ...opts.repository },\n };\n if (opts.title !== undefined) json.title = opts.title;\n if (opts.websiteUrl !== undefined) json.websiteUrl = opts.websiteUrl;\n if (opts.npmPackage) {\n const pkg: ServerJsonPackage = {\n registryType: \"npm\",\n registryBaseUrl: \"https://registry.npmjs.org\",\n identifier: opts.npmPackage.identifier,\n version: opts.npmPackage.version,\n runtimeHint: opts.npmPackage.runtimeHint ?? \"npx\",\n transport: { type: \"stdio\" },\n };\n if (opts.npmPackage.environmentVariables?.length) {\n pkg.environmentVariables = opts.npmPackage.environmentVariables;\n }\n json.packages = [pkg];\n }\n if (opts.remoteUrl !== undefined) {\n const remote: ServerJsonRemote = { type: \"streamable-http\", url: opts.remoteUrl };\n if (opts.remoteHeaders?.length) remote.headers = opts.remoteHeaders;\n json.remotes = [remote];\n }\n return json;\n}\n\nexport interface RegistryPublishWorkflowOptions {\n /** repo-relative path, e.g. `shelf/deal-memo/server.json` */\n serverJsonPath: string;\n /** tag glob that triggers publishing (default `mcp-*`) */\n tagPattern?: string;\n /** workflow display name */\n workflowName?: string;\n /** commands to run before publishing (e.g. build + npm publish); each becomes a step */\n beforePublish?: { name: string; run: string }[];\n /** pin the mcp-publisher release (default: latest) */\n publisherVersion?: string;\n}\n\nfunction yamlString(value: string): string {\n return JSON.stringify(value);\n}\n\n/**\n * GitHub Actions workflow (YAML) that publishes `server.json` to the official MCP registry\n * on tags matching `tagPattern`, authenticating with GitHub OIDC (`permissions.id-token: write`).\n * Steps follow the registry's github-actions guide: install mcp-publisher from GitHub releases,\n * `mcp-publisher login github-oidc`, `mcp-publisher publish`.\n */\nexport function registryPublishWorkflow(opts: RegistryPublishWorkflowOptions): string {\n const tagPattern = opts.tagPattern ?? \"mcp-*\";\n const name = opts.workflowName ?? \"Publish to MCP Registry\";\n const releasePath = opts.publisherVersion\n ? `download/${opts.publisherVersion}`\n : \"latest/download\";\n const before = (opts.beforePublish ?? [])\n .map(\n (step) =>\n ` - name: ${yamlString(step.name)}\\n run: |\\n${step.run\n .split(\"\\n\")\n .map((line) => ` ${line}`)\n .join(\"\\n\")}\\n\\n`,\n )\n .join(\"\");\n\n return `name: ${yamlString(name)}\n\non:\n push:\n tags: [${yamlString(tagPattern)}]\n\njobs:\n publish:\n runs-on: ubuntu-latest\n permissions:\n id-token: write\n contents: read\n env:\n SERVER_JSON: ${yamlString(opts.serverJsonPath)}\n\n steps:\n - name: Checkout code\n uses: actions/checkout@v5\n\n${before} - name: Install mcp-publisher\n run: |\n curl -L \"https://github.com/modelcontextprotocol/registry/releases/${releasePath}/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz\" | tar xz mcp-publisher\n\n - name: Authenticate to MCP Registry (GitHub OIDC)\n run: ./mcp-publisher login github-oidc\n\n - name: Publish server.json to MCP Registry\n run: |\n dir=\"$(dirname \"$SERVER_JSON\")\"\n if [ \"$(basename \"$SERVER_JSON\")\" != \"server.json\" ]; then cp \"$SERVER_JSON\" \"$dir/server.json\"; fi\n cd \"$dir\" && \"$GITHUB_WORKSPACE/mcp-publisher\" publish\n`;\n}\n","/**\n * Machine-readable docs every product ships: `llms.txt` and `pricing.json`.\n */\nimport { listToolManifest } from \"./server.js\";\nimport type { ToolDef } from \"./tool.js\";\n\nexport interface LlmsTxtLink {\n title: string;\n url: string;\n note?: string;\n}\n\nexport interface LlmsTxtSection {\n title: string;\n links: LlmsTxtLink[];\n}\n\nexport interface RenderLlmsTxtOptions {\n /** product name — becomes the H1 */\n name: string;\n /** one-line summary — becomes the blockquote */\n summary: string;\n /** optional paragraphs after the summary */\n description?: string;\n /** primary links (docs, MCP endpoint, pricing.json, openapi) */\n links: LlmsTxtLink[];\n /** extra sections, e.g. \"Optional\" */\n sections?: LlmsTxtSection[];\n /** when given, an \"MCP tools\" section lists name, description and input fields */\n tools?: readonly ToolDef[];\n}\n\nfunction renderLink(link: LlmsTxtLink): string {\n return `- [${link.title}](${link.url})${link.note ? `: ${link.note}` : \"\"}`;\n}\n\n/** Render an llms.txt document (https://llmstxt.org): H1, blockquote summary, link sections. */\nexport function renderLlmsTxt(opts: RenderLlmsTxtOptions): string {\n const lines: string[] = [`# ${opts.name.trim()}`, \"\", `> ${opts.summary.trim()}`, \"\"];\n if (opts.description) lines.push(opts.description.trim(), \"\");\n lines.push(\"## Links\", \"\", ...opts.links.map(renderLink), \"\");\n for (const section of opts.sections ?? []) {\n lines.push(`## ${section.title}`, \"\", ...section.links.map(renderLink), \"\");\n }\n if (opts.tools && opts.tools.length > 0) {\n lines.push(\"## MCP tools\", \"\");\n for (const entry of listToolManifest(opts.tools)) {\n const properties = entry.inputSchema.properties;\n const required = new Set(\n Array.isArray(entry.inputSchema.required) ? (entry.inputSchema.required as string[]) : [],\n );\n const fields =\n properties && typeof properties === \"object\"\n ? Object.keys(properties as Record<string, unknown>).map((key) =>\n required.has(key) ? key : `${key}?`,\n )\n : [];\n lines.push(\n `- \\`${entry.name}\\`${fields.length ? ` (${fields.join(\", \")})` : \"\"}: ${entry.description.trim()}`,\n );\n }\n lines.push(\"\");\n }\n return lines.join(\"\\n\");\n}\n\nexport interface PricingTier {\n /** stable id used in checkout, e.g. `starter` */\n id: string;\n name: string;\n /** 0 for free tiers */\n priceUsdMonthly: number;\n /** quotas, e.g. `{ monitors: 5, checks_per_day: 288 }` */\n limits: Record<string, number | string | boolean | null>;\n features: string[];\n checkoutUrl?: string;\n}\n\nexport interface PricingMeter {\n /** Stripe billing meter event name, e.g. `agentcheck_docs_eval_run` */\n eventName: string;\n unitPriceUsd: number;\n /** what one unit is, e.g. `run` */\n unit: string;\n description?: string;\n}\n\nexport interface PricingJsonOptions {\n product: string;\n currency: \"usd\";\n tiers: PricingTier[];\n meters?: PricingMeter[];\n checkoutUrl?: string;\n portalUrl?: string;\n updatedAt: string | Date;\n /**\n * Present when this product is parked or retired. The endpoints keep serving — see\n * `packages/config/src/lifecycle.ts` — but an agent reads this file as a commitment, and it\n * deserves to know nobody is maintaining this before it builds on it.\n */\n lifecycle?: {\n stage: string;\n since: string;\n reason: string;\n insteadUrl?: string;\n };\n}\n\nexport interface PricingJson {\n schema: \"agentwares.pricing/v1\";\n product: string;\n currency: \"usd\";\n tiers: PricingTier[];\n meters: PricingMeter[];\n checkoutUrl?: string;\n portalUrl?: string;\n /** absent while a product is active; see PricingJsonOptions */\n lifecycle?: { stage: string; since: string; reason: string; insteadUrl?: string };\n /** ISO 8601 */\n updatedAt: string;\n}\n\n/** Build the `pricing.json` object served next to every pricing page. */\nexport function pricingJson(opts: PricingJsonOptions): PricingJson {\n if (opts.tiers.length === 0) throw new Error(\"pricing.json needs at least one tier\");\n const ids = new Set<string>();\n for (const tier of opts.tiers) {\n if (ids.has(tier.id)) throw new Error(`pricing.json: duplicate tier id ${tier.id}`);\n ids.add(tier.id);\n if (!Number.isFinite(tier.priceUsdMonthly) || tier.priceUsdMonthly < 0) {\n throw new Error(`pricing.json: tier ${tier.id} has an invalid priceUsdMonthly`);\n }\n }\n const updatedAt = new Date(opts.updatedAt);\n if (Number.isNaN(updatedAt.getTime())) throw new Error(\"pricing.json: updatedAt is not a date\");\n\n const json: PricingJson = {\n schema: \"agentwares.pricing/v1\",\n product: opts.product,\n currency: opts.currency,\n tiers: opts.tiers,\n meters: opts.meters ?? [],\n updatedAt: updatedAt.toISOString(),\n };\n if (opts.checkoutUrl !== undefined) json.checkoutUrl = opts.checkoutUrl;\n if (opts.portalUrl !== undefined) json.portalUrl = opts.portalUrl;\n if (opts.lifecycle !== undefined) json.lifecycle = opts.lifecycle;\n return json;\n}\n","/**\n * The documents an agent or a registry fetches before it decides whether to use you.\n *\n * Checked against the primary sources on 10 September 2026, because the summaries are wrong\n * about this in ways that matter. Two paths that get recommended everywhere are not served\n * here on purpose:\n *\n * - `/.well-known/mcp.json` — no specification defines it. Six live examples were compared\n * and no two share a schema (`servers[]`, `mcpServers{}`, `{name,description,endpoint}`,\n * a registry `server.json`, …). A client that guesses wrong attempts a connection and\n * fails, rather than skipping gracefully, so publishing a seventh shape is worse than\n * publishing nothing.\n * - `/.well-known/mcp/server-card.json` — the MCP extension's own discovery document lists\n * this under \"alternatives considered, not recommended\". A server card is application\n * metadata, not site metadata, so it belongs at the MCP endpoint. `serverCardResponse`\n * serves it at `<mcp-url>/server-card`, which is the reserved location GitHub and\n * Hugging Face already use in production.\n *\n * Nothing here is invented. `ai-catalog.json` follows the AI Catalog specification, which is\n * what GitHub, Vercel, Hugging Face, Supabase, Apify and Zapier serve today and what\n * Hugging Face's `hf discover` reads. `security.txt` is RFC 9116. The server card follows the\n * MCP `ext-server-card` schema, which is still experimental and may change — the shape is\n * additive and inert, so a client that does not know it ignores it.\n *\n * One failure mode is worth more than the rest: **a 200 with the wrong body is worse than a\n * 404.** A framework catch-all that answers every unknown path with an HTML page will serve\n * HTML at `/.well-known/anything`, and a crawler trusting the status code parses it as JSON.\n * Every helper here returns an explicit content type, and anything not served must genuinely\n * 404.\n */\n\n/** RFC 9116 §2.5.3: `Expires` should be under a year out, and a stale file is worse than none. */\nexport interface SecurityTxtOptions {\n /** at least one; mailto: or https: */\n contact: string[];\n /** ISO 8601 instant this file stops being trustworthy */\n expires: string;\n policyUrl?: string;\n acknowledgmentsUrl?: string;\n preferredLanguages?: string;\n /** where this file canonically lives; helps a reader spot a copy served from elsewhere */\n canonicalUrl?: string;\n}\n\nexport function securityTxt(options: SecurityTxtOptions): string {\n const lines: string[] = [];\n for (const contact of options.contact) lines.push(`Contact: ${contact}`);\n lines.push(`Expires: ${options.expires}`);\n if (options.policyUrl) lines.push(`Policy: ${options.policyUrl}`);\n if (options.acknowledgmentsUrl) lines.push(`Acknowledgments: ${options.acknowledgmentsUrl}`);\n if (options.preferredLanguages) lines.push(`Preferred-Languages: ${options.preferredLanguages}`);\n if (options.canonicalUrl) lines.push(`Canonical: ${options.canonicalUrl}`);\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nexport function securityTxtResponse(options: SecurityTxtOptions): Response {\n return new Response(securityTxt(options), {\n headers: {\n \"content-type\": \"text/plain; charset=utf-8\",\n \"cache-control\": \"public, max-age=86400\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n\n/**\n * One thing an agent can use, listed in the catalog.\n *\n * `type` is a media type, and it is how a reader decides whether it can consume the entry at\n * all — `application/mcp-server-card+json` for an MCP server, `application/json` for a REST\n * API with an OpenAPI description. Exactly one of `url` or `data` is allowed.\n */\nexport interface AiCatalogEntry {\n identifier: string;\n type: string;\n url?: string;\n data?: unknown;\n displayName?: string;\n description?: string;\n tags?: string[];\n /**\n * Two to five things somebody would actually ask, in their words. This is what makes an\n * entry findable rather than merely present, and it is the field most publishers skip.\n */\n representativeQueries?: string[];\n}\n\nexport interface AiCatalogOptions {\n /** the publisher's own domain; `identifier` values are namespaced under it */\n host: { displayName: string; identifier: string; documentationUrl?: string };\n entries: AiCatalogEntry[];\n}\n\n/** `urn:air:{publisher}:{namespace}:{name}` — the publisher must be a domain you control. */\nexport function airUrn(publisher: string, namespace: string, name: string): string {\n return `urn:air:${publisher}:${namespace}:${name}`;\n}\n\nexport function aiCatalog(options: AiCatalogOptions): Record<string, unknown> {\n return {\n specVersion: \"1.0\",\n host: options.host,\n entries: options.entries.map((e) => ({\n identifier: e.identifier,\n ...(e.displayName ? { displayName: e.displayName } : {}),\n type: e.type,\n ...(e.url ? { url: e.url } : {}),\n ...(e.data !== undefined ? { data: e.data } : {}),\n ...(e.description ? { description: e.description } : {}),\n ...(e.tags?.length ? { tags: e.tags } : {}),\n ...(e.representativeQueries?.length\n ? { representativeQueries: e.representativeQueries }\n : {}),\n })),\n };\n}\n\nexport function aiCatalogResponse(options: AiCatalogOptions): Response {\n return new Response(`${JSON.stringify(aiCatalog(options), null, 2)}\\n`, {\n headers: {\n // the spec's media type; unregistered with IANA, but it is what every live publisher sends\n \"content-type\": \"application/ai-catalog+json\",\n \"cache-control\": \"public, max-age=3600\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n\n/**\n * An MCP server card, served at `<streamable-http-url>/server-card`.\n *\n * `description` is capped at 100 characters by the schema, which is easy to violate and\n * awkward to debug, so it is enforced here instead of at whatever reads it.\n */\nexport interface ServerCardOptions {\n /** reverse-DNS with exactly one slash, e.g. `io.github.agentwares/stablecoin-attestations` */\n name: string;\n version: string;\n /** at most 100 characters */\n description: string;\n title?: string;\n websiteUrl?: string;\n repository?: { url: string; source?: string; id?: string };\n /** where the server actually answers */\n remotes?: { type: \"streamable-http\" | \"sse\"; url: string }[];\n}\n\nconst SERVER_CARD_NAME = /^[a-zA-Z0-9.-]+\\/[a-zA-Z0-9._-]+$/;\n\nexport function serverCard(options: ServerCardOptions): Record<string, unknown> {\n if (!SERVER_CARD_NAME.test(options.name)) {\n throw new Error(\n `server card name must be reverse-DNS with one slash, got ${JSON.stringify(options.name)}`,\n );\n }\n if (options.description.length > 100) {\n throw new Error(\n `server card description is capped at 100 characters, got ${options.description.length}`,\n );\n }\n return {\n // The schema pattern-requires this exact string. It 404s today, so publish the literal\n // and do not try to fetch it at runtime.\n $schema: \"https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json\",\n name: options.name,\n version: options.version,\n description: options.description,\n ...(options.title ? { title: options.title } : {}),\n ...(options.websiteUrl ? { websiteUrl: options.websiteUrl } : {}),\n ...(options.repository ? { repository: options.repository } : {}),\n ...(options.remotes?.length ? { remotes: options.remotes } : {}),\n };\n}\n\nexport function serverCardResponse(options: ServerCardOptions): Response {\n return new Response(`${JSON.stringify(serverCard(options), null, 2)}\\n`, {\n headers: {\n \"content-type\": \"application/mcp-server-card+json\",\n \"cache-control\": \"public, max-age=3600\",\n \"access-control-allow-origin\": \"*\",\n },\n });\n}\n"],"mappings":"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","names":["z","z","z","z","jsonResponse","McpServer"]}
|