@agentwares/agentguard 0.1.1 → 0.1.3
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/LICENSE +21 -0
- package/README.md +38 -20
- package/dist/cli.js +303 -150
- package/dist/cli.js.map +1 -1
- package/dist/fixtures/crm-server.js +53 -24
- package/dist/fixtures/crm-server.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +202 -49
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/server.json +2 -2
|
@@ -1 +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/server.ts","../../../../packages/mcp-kit/src/http.ts","../../../../packages/mcp-kit/src/node-http.ts","../../../../packages/x402/src/index.ts","../../../../packages/mcp-kit/src/stdio.ts","../../../../packages/mcp-kit/src/registry.ts","../../../../packages/mcp-kit/src/docs.ts","../../src/fixtures/crm-server.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 /** 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 paymentRequiredResponse,\n type PaymentRequiredBody,\n type PaymentVerifier,\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 payTo?: string;\n signupUrl?: string;\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 = opts.verifier ?? new StubVerifier();\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 const required = buildPaymentRequired({\n resource: tool.name,\n priceUsd: opts.priceUsd,\n live: opts.live,\n description: opts.description,\n payTo: opts.payTo,\n signupUrl: opts.signupUrl,\n });\n const requirement = required.body.accepts[0];\n if (requirement) {\n const verified = await verifier.verify(\n new Request(`https://mcp.local/${tool.name}`, { headers: ctx.headers }),\n requirement,\n );\n if (verified.ok) return tool.handler(record, ctx);\n reason = reason ?? verified.reason;\n }\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 };\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 * `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 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 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 */\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport { normalizeError } from \"./errors.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, 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` (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\",\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\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 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 * @agentwares/x402 — 402 Payment Required helper + verifier interface.\n *\n * Wave 0 ships the *interface* and a stub: endpoints can already answer 402\n * with machine-readable payment requirements for both rails (x402 on Base\n * via the CDP facilitator, and Stripe MPP), but no payment is verified or\n * settled yet. WAL (Wave 3) replaces `StubVerifier` with the live one and\n * wires the prepaid wallet. Nothing here holds funds.\n */\n\nexport type PaymentRail = \"x402\" | \"mpp\";\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 asset?: string;\n currency?: 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\nexport interface PaymentRequiredBody {\n code: \"PAYMENT_REQUIRED\";\n cause: string;\n fix: string;\n retryable: true;\n priceUsd: number;\n accepts: PaymentRequirement[];\n /** true until WAL ships */\n comingSoon: boolean;\n /** how to pay today: API key + prepaid credits */\n alternatives: string[];\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 WAL is live */\n live?: boolean;\n payTo?: string;\n signupUrl?: string;\n}\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 const accepts: PaymentRequirement[] = [\n {\n rail: \"x402\",\n amountUsd,\n resource: opts.resource,\n description: opts.description,\n network: \"eip155:8453\",\n asset: \"USDC\",\n payTo: opts.payTo,\n maxTimeoutSeconds: 300,\n },\n {\n rail: \"mpp\",\n amountUsd,\n resource: opts.resource,\n description: opts.description,\n currency: \"usd\",\n payTo: opts.payTo,\n maxTimeoutSeconds: 300,\n },\n ];\n const live = opts.live === true;\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 ? \"Retry with a PAYMENT header satisfying one of `accepts`, or send an API key with credit balance.\"\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: [\"api_key_credits\", \"sample_mode\"],\n };\n const encoded = JSON.stringify({ x402Version: 2, accepts, resource: opts.resource });\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"WWW-Authenticate\": `Payment realm=\"agentwares\", methods=\"x402 mpp\", 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/** Implemented for real by WAL. Given a request, decide whether it carries a valid payment. */\nexport interface PaymentVerifier {\n verify(request: Request, requirement: PaymentRequirement): Promise<VerifyResult>;\n}\n\n/** Phase-2 placeholder: never accepts a payment, never touches funds. */\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","/**\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 */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\n/** Connect over stdio. Resolves when the transport closes (stdin ends). */\nexport async function serveStdio(serverOrOpts: McpServer | McpServerOptions): 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 StdioServerTransport();\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\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 /** 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 return json;\n}\n","#!/usr/bin/env node\n/**\n * Fake CRM MCP server used by the tests, the demo agent and the README walkthrough. In-memory\n * contacts; every mutation is recorded so tests can assert what really happened upstream.\n *\n * node dist/fixtures/crm-server.js # stdio\n * node dist/fixtures/crm-server.js --http # Streamable HTTP on 127.0.0.1:<port> (prints the URL)\n */\nimport {\n createHttpHandler,\n createMcpServer,\n defineTool,\n handleHealth,\n localhostHosts,\n serveNodeHttp,\n serveStdio,\n toolError,\n type ToolDef,\n} from \"@agentwares/mcp-kit\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nexport interface Contact {\n id: string;\n name: string;\n email: string;\n updated_at: string;\n}\n\nexport interface CrmState {\n contacts: Map<string, Contact>;\n mutations: { tool: string; args: unknown }[];\n emails: { to: string; subject: string }[];\n charges: { customer_id: string; amount_usd: number }[];\n}\n\nexport function seedState(): CrmState {\n const contacts = new Map<string, Contact>();\n for (const [id, name, email] of [\n [\"c_1\", \"Ada Lovelace\", \"ada@example.com\"],\n [\"c_2\", \"Grace Hopper\", \"grace@example.com\"],\n [\"c_3\", \"Linus Torvalds\", \"linus@example.com\"],\n ] as const) {\n contacts.set(id, { id, name, email, updated_at: \"2026-01-01T00:00:00.000Z\" });\n }\n return { contacts, mutations: [], emails: [], charges: [] };\n}\n\nlet counter = 0;\nconst nextId = (prefix: string): string => `${prefix}_${(++counter).toString(36).padStart(4, \"0\")}`;\n\nexport function crmTools(state: CrmState): ToolDef[] {\n const contactSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n updated_at: z.string(),\n });\n return [\n defineTool({\n name: \"crm_list_contacts\",\n description:\n \"List every contact in the CRM. Read-only; returns id, name, email and updated_at.\",\n input: z.object({ limit: z.number().int().min(1).max(500).default(100) }),\n output: z.object({ contacts: z.array(contactSchema), total: z.number() }),\n annotations: { readOnlyHint: true },\n handler: ({ limit }) => ({\n contacts: [...state.contacts.values()].slice(0, limit),\n total: state.contacts.size,\n }),\n }),\n defineTool({\n name: \"crm_get_contact\",\n description: \"Fetch one contact by id. Read-only; NOT_FOUND when the id does not exist.\",\n input: z.object({ id: z.string() }),\n output: contactSchema,\n annotations: { readOnlyHint: true },\n handler: ({ id }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n return c;\n },\n }),\n defineTool({\n name: \"crm_search\",\n description:\n \"Search contacts by name or email substring. Returns matching contacts (no annotations on purpose).\",\n input: z.object({ query: z.string() }),\n handler: ({ query }) => ({\n contacts: [...state.contacts.values()].filter((c) =>\n `${c.name} ${c.email}`.toLowerCase().includes(query.toLowerCase()),\n ),\n }),\n }),\n defineTool({\n name: \"crm_create_contact\",\n description: \"Create a contact. Returns the new id and created_at timestamp.\",\n input: z.object({ name: z.string(), email: z.string() }),\n output: z.object({ id: z.string(), created_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false },\n handler: ({ name, email }) => {\n const id = nextId(\"c\");\n const now = new Date().toISOString();\n state.contacts.set(id, { id, name, email, updated_at: now });\n state.mutations.push({ tool: \"crm_create_contact\", args: { name, email } });\n return { id, created_at: now };\n },\n }),\n defineTool({\n name: \"crm_update_contact\",\n description:\n \"Update fields on a contact. Returns the id and updated_at; NOT_FOUND for unknown ids.\",\n input: z.object({\n id: z.string(),\n fields: z.object({ name: z.string().optional(), email: z.string().optional() }),\n }),\n output: z.object({ id: z.string(), updated_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n handler: ({ id, fields }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n Object.assign(c, fields, { updated_at: new Date().toISOString() });\n state.mutations.push({ tool: \"crm_update_contact\", args: { id, fields } });\n return { id, updated_at: c.updated_at };\n },\n }),\n defineTool({\n name: \"crm_delete_contact\",\n description: \"Permanently delete a contact. Irreversible. Returns { deleted, id }.\",\n input: z.object({ id: z.string() }),\n output: z.object({ deleted: z.boolean(), id: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: true },\n handler: ({ id }) => {\n const existed = state.contacts.delete(id);\n state.mutations.push({ tool: \"crm_delete_contact\", args: { id } });\n return { deleted: existed, id };\n },\n }),\n defineTool({\n name: \"crm_send_email\",\n description:\n \"Send an email to a contact through the CRM. Returns the message id and sent_at.\",\n input: z.object({ to: z.string(), subject: z.string(), body: z.string() }),\n output: z.object({ message_id: z.string(), sent_at: z.string() }),\n handler: ({ to, subject }) => {\n state.emails.push({ to, subject });\n state.mutations.push({ tool: \"crm_send_email\", args: { to, subject } });\n return { message_id: nextId(\"msg\"), sent_at: new Date().toISOString() };\n },\n }),\n defineTool({\n name: \"crm_charge_card\",\n description:\n \"Charge a customer's card on file (amount in cents). Returns the charge id and amount_usd.\",\n input: z.object({\n customer_id: z.string(),\n amount_cents: z.number().int().positive(),\n currency: z.string().default(\"usd\"),\n }),\n output: z.object({ charge_id: z.string(), amount_usd: z.number() }),\n handler: ({ customer_id, amount_cents }) => {\n const amount_usd = amount_cents / 100;\n state.charges.push({ customer_id, amount_usd });\n state.mutations.push({ tool: \"crm_charge_card\", args: { customer_id, amount_usd } });\n return { charge_id: nextId(\"ch\"), amount_usd };\n },\n }),\n defineTool({\n name: \"crm_frobnicate\",\n description:\n \"A tool with no annotations and no recognizable verb — exists to test `unknown` handling.\",\n input: z.object({}),\n handler: () => {\n state.mutations.push({ tool: \"crm_frobnicate\", args: {} });\n return { frobnicated: true };\n },\n }),\n defineTool({\n name: \"crm_fail\",\n description: \"Always returns a structured UPSTREAM_ERROR result, for error-path tests.\",\n input: z.object({}),\n annotations: { readOnlyHint: true },\n handler: () => {\n throw toolError(\"UPSTREAM_ERROR\", \"the CRM is having a bad day\", \"retry in a minute\", {\n retryable: true,\n });\n },\n }),\n ];\n}\n\nexport function createCrmMcpServer(state: CrmState = seedState()): McpServer {\n return createMcpServer({\n name: \"fake-crm\",\n version: \"0.1.0\",\n instructions: \"A fake CRM for agentguard tests. Nothing here is real.\",\n tools: crmTools(state),\n });\n}\n\nconst isMain = process.argv[1] !== undefined && /crm-server\\.[cm]?[jt]s$/.test(process.argv[1]);\nif (isMain) {\n const state = seedState();\n if (process.argv.includes(\"--http\")) {\n const portArg = process.argv.find((a) => a.startsWith(\"--port=\"));\n const port = portArg ? Number(portArg.slice(\"--port=\".length)) : 0;\n const handler = createHttpHandler(() => createCrmMcpServer(state), {\n sessions: true,\n jsonResponse: false,\n allowedHosts: port ? localhostHosts(port) : undefined,\n });\n const server = await serveNodeHttp({\n handler,\n port,\n health: () =>\n handleHealth({ name: \"fake-crm\", version: \"0.1.0\", tools: crmTools(state).length }),\n });\n console.log(`fake-crm listening at ${server.url}`);\n } else {\n // The proxy stops us with SIGTERM; exit on it so Node does not warn about the unsettled\n // top-level await into the parent's stderr at the end of the demo.\n for (const signal of [\"SIGTERM\", \"SIGINT\"] as const) process.on(signal, () => process.exit(0));\n await serveStdio(createCrmMcpServer(state));\n }\n}\n"],"mappings":"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","names":["z","z","z","z","jsonResponse","McpServer","z"]}
|
|
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/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/stdio.ts","../../../../packages/mcp-kit/src/registry.ts","../../../../packages/mcp-kit/src/docs.ts","../../src/fixtures/crm-server.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 /** 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 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 const required = buildPaymentRequired({\n resource: tool.name,\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 });\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: tool.name,\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 * `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 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 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 */\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { WebStandardStreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js\";\nimport { normalizeError } from \"./errors.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, 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` (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\",\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\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 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\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 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}\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}\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\n function requirementsFor(requirement: PaymentRequirement): Record<string, unknown> {\n return {\n scheme: \"exact\",\n network: options.network,\n maxAmountRequired: toAtomicUnits(requirement.amountUsd),\n resource: requirement.resource,\n description: requirement.description ?? \"\",\n mimeType: \"application/json\",\n payTo: options.payTo,\n maxTimeoutSeconds: requirement.maxTimeoutSeconds ?? 300,\n asset,\n };\n }\n\n type Call<T> = { reached: true; body: T } | { reached: false; error: string };\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 return { reached: true, body: (await res.json()) as T };\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: payment.x402Version ?? 2,\n paymentPayload: payment,\n paymentRequirements,\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: { payment, paymentRequirements, payer: verified.payer },\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 { payment: PaymentPayload; paymentRequirements: Record<string, unknown> } | undefined;\n if (!receipt?.payment) return { ok: false, reason: \"nothing to settle\" };\n const call2 = await call<SettleResponse>(\"/settle\", {\n x402Version: receipt.payment.x402Version ?? 2,\n paymentPayload: receipt.payment,\n paymentRequirements: receipt.paymentRequirements,\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 return {\n ok: true,\n ...(result.transaction ? { transaction: result.transaction } : {}),\n ...(result.payer ? { payer: result.payer } : {}),\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 return (await owner?.settle?.(verified)) ?? { ok: true };\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. Only one of them is live:\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 via the CDP facilitator)** — advertised, not yet verifiable:\n * it needs a Coinbase CDP account that does not exist yet. `StubVerifier` is what\n * that rail still uses; switching it on is implementing `PaymentVerifier` again.\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 */\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 asset?: string;\n currency?: 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\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 /** 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\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 /** 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\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 accepts.push({\n rail: \"x402\",\n amountUsd,\n resource: opts.resource,\n description: opts.description,\n network: opts.network ?? DEFAULT_X402_NETWORK,\n asset: \"USDC\",\n payTo: opts.payTo,\n maxTimeoutSeconds: 300,\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. Sample mode goes first because it is the one thing that works with no payment\n // and no key at all.\n const liveFix = selfServe\n ? `Free first: retry with sample=true — no key, no payment. To pay: POST ${selfServe.keysUrl} ` +\n `(no auth, no signup) returns a key and a Stripe Checkout URL. Funding that key needs a person ` +\n `to complete the Checkout page in a browser; if you are running unattended, surface the URL to ` +\n `your operator rather than retrying. Once funded, send Authorization: Bearer <key>, plus ` +\n `Idempotency-Key so a repeated call is charged once.`\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: [\"api_key_credits\", \"sample_mode\"],\n ...(selfServe ? { selfServe } : {}),\n };\n const encoded = JSON.stringify({ x402Version: 2, accepts, resource: opts.resource });\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 * `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 */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { createMcpServer, type McpServerOptions } from \"./server.js\";\n\n/** Connect over stdio. Resolves when the transport closes (stdin ends). */\nexport async function serveStdio(serverOrOpts: McpServer | McpServerOptions): 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 StdioServerTransport();\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\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 /** 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 return json;\n}\n","#!/usr/bin/env node\n/**\n * Fake CRM MCP server used by the tests, the demo agent and the README walkthrough. In-memory\n * contacts; every mutation is recorded so tests can assert what really happened upstream.\n *\n * node dist/fixtures/crm-server.js # stdio\n * node dist/fixtures/crm-server.js --http # Streamable HTTP on 127.0.0.1:<port> (prints the URL)\n */\nimport {\n createHttpHandler,\n createMcpServer,\n defineTool,\n handleHealth,\n localhostHosts,\n serveNodeHttp,\n serveStdio,\n toolError,\n type ToolDef,\n} from \"@agentwares/mcp-kit\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\nexport interface Contact {\n id: string;\n name: string;\n email: string;\n updated_at: string;\n}\n\nexport interface CrmState {\n contacts: Map<string, Contact>;\n mutations: { tool: string; args: unknown }[];\n emails: { to: string; subject: string }[];\n charges: { customer_id: string; amount_usd: number }[];\n}\n\nexport function seedState(): CrmState {\n const contacts = new Map<string, Contact>();\n for (const [id, name, email] of [\n [\"c_1\", \"Ada Lovelace\", \"ada@example.com\"],\n [\"c_2\", \"Grace Hopper\", \"grace@example.com\"],\n [\"c_3\", \"Linus Torvalds\", \"linus@example.com\"],\n ] as const) {\n contacts.set(id, { id, name, email, updated_at: \"2026-01-01T00:00:00.000Z\" });\n }\n return { contacts, mutations: [], emails: [], charges: [] };\n}\n\nlet counter = 0;\nconst nextId = (prefix: string): string => `${prefix}_${(++counter).toString(36).padStart(4, \"0\")}`;\n\nexport function crmTools(state: CrmState): ToolDef[] {\n const contactSchema = z.object({\n id: z.string(),\n name: z.string(),\n email: z.string(),\n updated_at: z.string(),\n });\n return [\n defineTool({\n name: \"crm_list_contacts\",\n description:\n \"List every contact in the CRM. Read-only; returns id, name, email and updated_at.\",\n input: z.object({ limit: z.number().int().min(1).max(500).default(100) }),\n output: z.object({ contacts: z.array(contactSchema), total: z.number() }),\n annotations: { readOnlyHint: true },\n handler: ({ limit }) => ({\n contacts: [...state.contacts.values()].slice(0, limit),\n total: state.contacts.size,\n }),\n }),\n defineTool({\n name: \"crm_get_contact\",\n description: \"Fetch one contact by id. Read-only; NOT_FOUND when the id does not exist.\",\n input: z.object({ id: z.string() }),\n output: contactSchema,\n annotations: { readOnlyHint: true },\n handler: ({ id }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n return c;\n },\n }),\n defineTool({\n name: \"crm_search\",\n description:\n \"Search contacts by name or email substring. Returns matching contacts (no annotations on purpose).\",\n input: z.object({ query: z.string() }),\n handler: ({ query }) => ({\n contacts: [...state.contacts.values()].filter((c) =>\n `${c.name} ${c.email}`.toLowerCase().includes(query.toLowerCase()),\n ),\n }),\n }),\n defineTool({\n name: \"crm_create_contact\",\n description: \"Create a contact. Returns the new id and created_at timestamp.\",\n input: z.object({ name: z.string(), email: z.string() }),\n output: z.object({ id: z.string(), created_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false },\n handler: ({ name, email }) => {\n const id = nextId(\"c\");\n const now = new Date().toISOString();\n state.contacts.set(id, { id, name, email, updated_at: now });\n state.mutations.push({ tool: \"crm_create_contact\", args: { name, email } });\n return { id, created_at: now };\n },\n }),\n defineTool({\n name: \"crm_update_contact\",\n description:\n \"Update fields on a contact. Returns the id and updated_at; NOT_FOUND for unknown ids.\",\n input: z.object({\n id: z.string(),\n fields: z.object({ name: z.string().optional(), email: z.string().optional() }),\n }),\n output: z.object({ id: z.string(), updated_at: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n handler: ({ id, fields }) => {\n const c = state.contacts.get(id);\n if (!c)\n throw toolError(\n \"NOT_FOUND\",\n `no contact ${id}`,\n \"call crm_list_contacts and use an existing id\",\n );\n Object.assign(c, fields, { updated_at: new Date().toISOString() });\n state.mutations.push({ tool: \"crm_update_contact\", args: { id, fields } });\n return { id, updated_at: c.updated_at };\n },\n }),\n defineTool({\n name: \"crm_delete_contact\",\n description: \"Permanently delete a contact. Irreversible. Returns { deleted, id }.\",\n input: z.object({ id: z.string() }),\n output: z.object({ deleted: z.boolean(), id: z.string() }),\n annotations: { readOnlyHint: false, destructiveHint: true },\n handler: ({ id }) => {\n const existed = state.contacts.delete(id);\n state.mutations.push({ tool: \"crm_delete_contact\", args: { id } });\n return { deleted: existed, id };\n },\n }),\n defineTool({\n name: \"crm_send_email\",\n description:\n \"Send an email to a contact through the CRM. Returns the message id and sent_at.\",\n input: z.object({ to: z.string(), subject: z.string(), body: z.string() }),\n output: z.object({ message_id: z.string(), sent_at: z.string() }),\n handler: ({ to, subject }) => {\n state.emails.push({ to, subject });\n state.mutations.push({ tool: \"crm_send_email\", args: { to, subject } });\n return { message_id: nextId(\"msg\"), sent_at: new Date().toISOString() };\n },\n }),\n defineTool({\n name: \"crm_charge_card\",\n description:\n \"Charge a customer's card on file (amount in cents). Returns the charge id and amount_usd.\",\n input: z.object({\n customer_id: z.string(),\n amount_cents: z.number().int().positive(),\n currency: z.string().default(\"usd\"),\n }),\n output: z.object({ charge_id: z.string(), amount_usd: z.number() }),\n handler: ({ customer_id, amount_cents }) => {\n const amount_usd = amount_cents / 100;\n state.charges.push({ customer_id, amount_usd });\n state.mutations.push({ tool: \"crm_charge_card\", args: { customer_id, amount_usd } });\n return { charge_id: nextId(\"ch\"), amount_usd };\n },\n }),\n defineTool({\n name: \"crm_frobnicate\",\n description:\n \"A tool with no annotations and no recognizable verb — exists to test `unknown` handling.\",\n input: z.object({}),\n handler: () => {\n state.mutations.push({ tool: \"crm_frobnicate\", args: {} });\n return { frobnicated: true };\n },\n }),\n defineTool({\n name: \"crm_fail\",\n description: \"Always returns a structured UPSTREAM_ERROR result, for error-path tests.\",\n input: z.object({}),\n annotations: { readOnlyHint: true },\n handler: () => {\n throw toolError(\"UPSTREAM_ERROR\", \"the CRM is having a bad day\", \"retry in a minute\", {\n retryable: true,\n });\n },\n }),\n ];\n}\n\nexport function createCrmMcpServer(state: CrmState = seedState()): McpServer {\n return createMcpServer({\n name: \"fake-crm\",\n version: \"0.1.0\",\n instructions: \"A fake CRM for agentguard tests. Nothing here is real.\",\n tools: crmTools(state),\n });\n}\n\nconst isMain = process.argv[1] !== undefined && /crm-server\\.[cm]?[jt]s$/.test(process.argv[1]);\nif (isMain) {\n const state = seedState();\n if (process.argv.includes(\"--http\")) {\n const portArg = process.argv.find((a) => a.startsWith(\"--port=\"));\n const port = portArg ? Number(portArg.slice(\"--port=\".length)) : 0;\n const handler = createHttpHandler(() => createCrmMcpServer(state), {\n sessions: true,\n jsonResponse: false,\n allowedHosts: port ? localhostHosts(port) : undefined,\n });\n const server = await serveNodeHttp({\n handler,\n port,\n health: () =>\n handleHealth({ name: \"fake-crm\", version: \"0.1.0\", tools: crmTools(state).length }),\n });\n console.log(`fake-crm listening at ${server.url}`);\n } else {\n // The proxy stops us with SIGTERM; exit on it so Node does not warn about the unsettled\n // top-level await into the parent's stderr at the end of the demo.\n for (const signal of [\"SIGTERM\", \"SIGINT\"] as const) process.on(signal, () => process.exit(0));\n await serveStdio(createCrmMcpServer(state));\n }\n}\n"],"mappings":"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","names":["z","z","z","z","jsonResponse","McpServer","z"]}
|