@fitzzero/quickdraw-core 5.1.2 → 5.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.
Files changed (124) hide show
  1. package/README.md +793 -57
  2. package/dist/{admin-DWWrT1h6.d.ts → admin-CS7JB_UH.d.ts} +2 -2
  3. package/dist/{adminSchemas-D4bFKsrb.d.ts → adminSchemas-29cGgrg5.d.ts} +1 -1
  4. package/dist/{auth-DXiSJZaf.d.ts → auth-DtdYjrZ9.d.ts} +11 -7
  5. package/dist/{caller-BT-Mv4bD.d.ts → caller-BTwGl7vm.d.ts} +183 -15
  6. package/dist/chunk-2FDSKLBO.js +82 -0
  7. package/dist/chunk-2FDSKLBO.js.map +1 -0
  8. package/dist/{chunk-GSIPUNJL.js → chunk-64I6MYBC.js} +139 -792
  9. package/dist/chunk-64I6MYBC.js.map +1 -0
  10. package/dist/chunk-7473HK24.js +17 -0
  11. package/dist/chunk-7473HK24.js.map +1 -0
  12. package/dist/chunk-7Y5ROPXL.js +33 -0
  13. package/dist/chunk-7Y5ROPXL.js.map +1 -0
  14. package/dist/chunk-A2RBQD66.js +7 -0
  15. package/dist/chunk-A2RBQD66.js.map +1 -0
  16. package/dist/chunk-ASAMUGHG.js +651 -0
  17. package/dist/chunk-ASAMUGHG.js.map +1 -0
  18. package/dist/{chunk-B2P7AZ25.js → chunk-CYE4UBOB.js} +6 -4
  19. package/dist/chunk-CYE4UBOB.js.map +1 -0
  20. package/dist/chunk-DNP65TD5.js +832 -0
  21. package/dist/chunk-DNP65TD5.js.map +1 -0
  22. package/dist/{chunk-5CGO426C.js → chunk-GYLWEJHW.js} +5 -1
  23. package/dist/chunk-GYLWEJHW.js.map +1 -0
  24. package/dist/{chunk-AONAFOYU.js → chunk-I3JCFS7H.js} +25 -13
  25. package/dist/chunk-I3JCFS7H.js.map +1 -0
  26. package/dist/{chunk-X5CWPX7H.js → chunk-IIQ3WMJK.js} +13 -2
  27. package/dist/chunk-IIQ3WMJK.js.map +1 -0
  28. package/dist/{chunk-6K5BY47X.js → chunk-JVTONQFI.js} +1277 -277
  29. package/dist/chunk-JVTONQFI.js.map +1 -0
  30. package/dist/{chunk-RL4VKLBX.js → chunk-KKQANRLG.js} +2 -2
  31. package/dist/{chunk-RL4VKLBX.js.map → chunk-KKQANRLG.js.map} +1 -1
  32. package/dist/{chunk-GKH3LJ7N.js → chunk-MPQAT55F.js} +38 -205
  33. package/dist/chunk-MPQAT55F.js.map +1 -0
  34. package/dist/chunk-NX2V6SIL.js +202 -0
  35. package/dist/chunk-NX2V6SIL.js.map +1 -0
  36. package/dist/{chunk-7QCUX4TK.js → chunk-NZHA4TZD.js} +72 -175
  37. package/dist/chunk-NZHA4TZD.js.map +1 -0
  38. package/dist/{chunk-MBH6IDSM.js → chunk-OCZJ4EYV.js} +40 -17
  39. package/dist/chunk-OCZJ4EYV.js.map +1 -0
  40. package/dist/{chunk-RJ5I2VO3.js → chunk-PHCURHC7.js} +6 -6
  41. package/dist/chunk-PHCURHC7.js.map +1 -0
  42. package/dist/{chunk-4YO5H5ON.js → chunk-Q4OGQM5I.js} +4 -10
  43. package/dist/chunk-Q4OGQM5I.js.map +1 -0
  44. package/dist/chunk-QSU47XEX.js +13 -0
  45. package/dist/chunk-QSU47XEX.js.map +1 -0
  46. package/dist/{chunk-LCC7HNFP.js → chunk-RZXJTDH5.js} +2 -2
  47. package/dist/{chunk-Z2LZ7IZ7.js → chunk-SN3OZVEQ.js} +5 -31
  48. package/dist/chunk-SN3OZVEQ.js.map +1 -0
  49. package/dist/{chunk-Z5ILULF2.js → chunk-SQ5VUG77.js} +4 -3
  50. package/dist/{chunk-Z5ILULF2.js.map → chunk-SQ5VUG77.js.map} +1 -1
  51. package/dist/chunk-STH5DLQP.js +1192 -0
  52. package/dist/chunk-STH5DLQP.js.map +1 -0
  53. package/dist/{chunk-NMXYENH4.js → chunk-VZFJTKIW.js} +6 -6
  54. package/dist/{chunk-753VJIUP.js → chunk-X4ZU4QH5.js} +43 -9
  55. package/dist/chunk-X4ZU4QH5.js.map +1 -0
  56. package/dist/chunk-XD7SRDUY.js +188 -0
  57. package/dist/chunk-XD7SRDUY.js.map +1 -0
  58. package/dist/chunk-Z7I6SONO.js +825 -0
  59. package/dist/chunk-Z7I6SONO.js.map +1 -0
  60. package/dist/cli/quickdraw-docs.js +131 -113
  61. package/dist/cli/quickdraw-docs.js.map +1 -1
  62. package/dist/client/core.d.ts +387 -0
  63. package/dist/client/core.js +109 -0
  64. package/dist/client/core.js.map +1 -0
  65. package/dist/client/index.d.ts +30 -193
  66. package/dist/client/index.js +56 -217
  67. package/dist/client/index.js.map +1 -1
  68. package/dist/{clientTypes-hWcPUVS9.d.ts → clientTypes-CUUNJwWs.d.ts} +3 -3
  69. package/dist/{connection-CgijdGpT.d.ts → connection-2EeQ_Et0.d.ts} +16 -9
  70. package/dist/{createServer-Cp-Wk500.d.ts → createServer-Bx5HOcYK.d.ts} +37 -9
  71. package/dist/{createTestApp-BB_PkqQ7.d.ts → createTestApp-DAMANT79.d.ts} +36 -9
  72. package/dist/{envelope-DzWyIXjj.d.ts → envelope-BMBaxppV.d.ts} +200 -8
  73. package/dist/{http-DotQ5bj8.d.ts → http-YzLAar3w.d.ts} +15 -50
  74. package/dist/index.d.ts +7 -6
  75. package/dist/index.js +61 -28
  76. package/dist/index.js.map +1 -1
  77. package/dist/{infer-BmoZsL9a.d.ts → infer-Br62cnyW.d.ts} +39 -1
  78. package/dist/{metrics-DW80Exve.d.ts → metrics-CTVpw0gu.d.ts} +2 -2
  79. package/dist/parser.js +2 -1
  80. package/dist/prisma/index.d.ts +13 -6
  81. package/dist/prisma/index.js +155 -9
  82. package/dist/prisma/index.js.map +1 -1
  83. package/dist/remote-N7OUAGOW.js +15 -0
  84. package/dist/remote-N7OUAGOW.js.map +1 -0
  85. package/dist/server/auth/index.d.ts +3 -3
  86. package/dist/server/auth/index.js +5 -3
  87. package/dist/server/auth/index.js.map +1 -1
  88. package/dist/server/index.d.ts +140 -36
  89. package/dist/server/index.js +162 -55
  90. package/dist/server/index.js.map +1 -1
  91. package/dist/server/mcp/index.d.ts +34 -18
  92. package/dist/server/mcp/index.js +29 -12
  93. package/dist/server/mcp/index.js.map +1 -1
  94. package/dist/server/otel.d.ts +3 -3
  95. package/dist/{sharing-UDLn1049.d.ts → sharing-BrsmlDv_.d.ts} +3 -3
  96. package/dist/testing/client.d.ts +13 -13
  97. package/dist/testing/client.js +17 -10
  98. package/dist/testing/client.js.map +1 -1
  99. package/dist/testing/index.d.ts +49 -12
  100. package/dist/testing/index.js +102 -19
  101. package/dist/testing/index.js.map +1 -1
  102. package/dist/testing/mock.d.ts +5 -5
  103. package/dist/testing/mock.js +15 -9
  104. package/dist/tracked-BR5b2O-U.d.ts +43 -0
  105. package/dist/{types-CYliTP65.d.ts → types-CLRCQGnO.d.ts} +4 -3
  106. package/dist/types-tMagHbjy.d.ts +151 -0
  107. package/dist/utils/index.d.ts +16 -4
  108. package/dist/utils/index.js +6 -3
  109. package/package.json +5 -1
  110. package/dist/chunk-4YO5H5ON.js.map +0 -1
  111. package/dist/chunk-5CGO426C.js.map +0 -1
  112. package/dist/chunk-6K5BY47X.js.map +0 -1
  113. package/dist/chunk-753VJIUP.js.map +0 -1
  114. package/dist/chunk-7QCUX4TK.js.map +0 -1
  115. package/dist/chunk-AONAFOYU.js.map +0 -1
  116. package/dist/chunk-B2P7AZ25.js.map +0 -1
  117. package/dist/chunk-GKH3LJ7N.js.map +0 -1
  118. package/dist/chunk-GSIPUNJL.js.map +0 -1
  119. package/dist/chunk-MBH6IDSM.js.map +0 -1
  120. package/dist/chunk-RJ5I2VO3.js.map +0 -1
  121. package/dist/chunk-X5CWPX7H.js.map +0 -1
  122. package/dist/chunk-Z2LZ7IZ7.js.map +0 -1
  123. /package/dist/{chunk-LCC7HNFP.js.map → chunk-RZXJTDH5.js.map} +0 -0
  124. /package/dist/{chunk-NMXYENH4.js.map → chunk-VZFJTKIW.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/mcp/tools.ts","../../../src/server/mcp/lanes.ts","../../../src/server/mcp/session.ts","../../../src/server/mcp/custom.ts","../../../src/server/mcp/registry.ts","../../../src/server/mcp/result.ts","../../../src/server/mcp/stdio.ts","../../../src/server/mcp/stderr.ts","../../../src/server/mcp/bootstrap.ts","../../../src/server/mcp/httpRequest.ts","../../../src/server/mcp/http.ts"],"sourcesContent":["// Tools from contracts (RFC 0003 section 10): one tool per method, made when\n// the registry is built, from what the contract already holds: the input\n// schema, the kind and the `describe` text. 4.1 wrote tool metadata ahead of\n// time by parsing service source files with regular expressions\n// (4.1 `src/server/mcp/generateToolMetadata.ts:255`); nothing is generated\n// ahead of time here.\n//\n// A tool's `inputSchema` is the method input's Standard JSON Schema (Zod 4.2\n// or later), drafted as JSON Schema draft-07, the dialect MCP clients of the\n// 2024-11-05 protocol read. MCP tool arguments are always an object, so:\n//\n// - an object input is the arguments themselves;\n// - an input with no JSON Schema form that accepts `undefined`\n// (`z.undefined()`, `z.void()`) is a tool without arguments;\n// - any other input (a string, a union) is the `input` argument.\n//\n// An input whose JSON Schema is a `$ref` to an object (a Zod schema with\n// `.meta({ id })`) counts as that object: its definition is inlined at the\n// root. A wrapped input keeps its `definitions` at the root of the tool's\n// schema, where its `$ref`s resolve for the client.\n//\n// A registry's `bind` names arguments it fills from the principal: they are\n// left out of the `inputSchema` of each object input that has them, and may\n// not appear anywhere else in an input, behind a `$ref` or in any `anyOf`,\n// `oneOf` or `allOf` branch (`inputKeys`), where they could not be filled.\n\nimport type { MethodKind } from \"../../contract/methods\";\nimport { defaultToolName } from \"../../contract/toolName\";\nimport {\n hasJsonSchema,\n type StandardSchemaV1,\n type StandardSchemaWithJSON,\n} from \"../../contract/standardSchema\";\nimport { inputKeys, pointerToken, referenced } from \"../emit/projection\";\nimport type { AnyService } from \"../service\";\nimport type { DescribeToolsOptions, McpInputSchema, McpTool } from \"./types\";\n\n/** How a tool's arguments become its input. */\nexport type ArgumentsMode = \"object\" | \"wrapped\" | \"none\";\n\n/** A tool's argument schema, and how its arguments become the input. */\nexport interface ToolInput {\n readonly schema: McpInputSchema;\n readonly mode: ArgumentsMode;\n}\n\n/** A method's tool, with the method it calls. */\nexport interface MethodTool extends ToolInput {\n readonly tool: McpTool;\n readonly service: string;\n readonly method: string;\n /** The arguments the registry's `bind` fills, which `tool.inputSchema` leaves out. */\n readonly bound: readonly string[];\n}\n\ntype Fail = (message: string) => never;\n\nconst JSON_SCHEMA_TARGET = \"draft-07\";\n\nconst NO_ARGUMENTS: McpInputSchema = Object.freeze({\n type: \"object\",\n properties: Object.freeze({}),\n});\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** True when the schema accepts `undefined` without awaiting anything. */\nfunction acceptsUndefined(schema: StandardSchemaV1): boolean {\n try {\n const result: unknown = schema[\"~standard\"].validate(undefined);\n return isRecord(result) && typeof result.then !== \"function\" && result.issues === undefined;\n } catch {\n return false;\n }\n}\n\n/** The JSON Schema of a schema's input, or why the schema could not write one. */\nfunction draftJsonSchema(schema: StandardSchemaWithJSON): Record<string, unknown> | Error {\n try {\n const json: unknown = schema[\"~standard\"].jsonSchema.input({ target: JSON_SCHEMA_TARGET });\n return isRecord(json) ? json : new Error(\"the schema did not return an object\");\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n}\n\n/**\n * The argument schema of a tool whose input is `schema`, and how its\n * arguments become that input. Fails when the schema cannot describe itself\n * as JSON Schema, naming `label` (what the tool calls) and the fix; `instead`\n * is the other way out. A method can be left out with `exclude`.\n */\nexport function toolInputOf(\n label: string,\n schema: StandardSchemaV1,\n fail: Fail,\n instead = `leave ${label} out with exclude`,\n): ToolInput {\n if (!hasJsonSchema(schema)) {\n fail(\n `the input schema of ${label} cannot describe itself as JSON Schema, which an MCP tool needs: use Zod 4.2 or later for that schema, or ${instead}`,\n );\n }\n const json = draftJsonSchema(schema);\n if (json instanceof Error) {\n if (acceptsUndefined(schema)) {\n return { schema: NO_ARGUMENTS, mode: \"none\" };\n }\n fail(\n `the input schema of ${label} cannot be written as JSON Schema (${json.message}): change that schema, or ${instead}`,\n );\n }\n const described = referenced(json, json);\n if (described?.type === \"object\") {\n return { schema: inlined(json, described) as McpInputSchema, mode: \"object\" };\n }\n const { $schema: dialect, definitions, $defs, ...input } = json;\n return {\n schema: {\n ...(dialect === undefined ? {} : { $schema: dialect }),\n type: \"object\",\n properties: { input: rerooted(input) },\n ...(acceptsUndefined(schema) ? {} : { required: [\"input\"] }),\n ...(definitions === undefined ? {} : { definitions: rerooted(definitions) }),\n ...($defs === undefined ? {} : { $defs: rerooted($defs) }),\n },\n mode: \"wrapped\",\n };\n}\n\n/** Where a wrapped input sits in its tool's schema. */\nconst WRAPPED_INPUT = \"#/properties/input\";\n\n/**\n * `value` with every `$ref` into the input's root, but its definitions,\n * pointed where the wrapped input sits: a recursive input refers to itself\n * as `#`, which is the tool's schema once the input is wrapped. The\n * definitions stay at the root, so their references hold.\n */\nfunction rerooted(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(rerooted);\n }\n if (!isRecord(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => {\n const intoRoot =\n key === \"$ref\" &&\n typeof item === \"string\" &&\n (item === \"#\" || (item.startsWith(\"#/\") && !/^#\\/(?:definitions|\\$defs)\\//u.test(item)));\n return [key, intoRoot ? `${WRAPPED_INPUT}${item.slice(1)}` : rerooted(item)];\n }),\n );\n}\n\n/** True when `value` holds a `$ref` to `ref` anywhere inside it. */\nfunction refersTo(value: unknown, ref: string): boolean {\n if (Array.isArray(value)) {\n return value.some((item) => refersTo(item, ref));\n }\n if (!isRecord(value)) {\n return false;\n }\n return value.$ref === ref || Object.values(value).some((item) => refersTo(item, ref));\n}\n\n/**\n * The object schema a root `$ref` names, inlined at the root (Zod writes an\n * id'd schema as `{ $schema, $ref: \"#/definitions/<id>\", definitions }`):\n * the root's dialect and definitions beside the target's keywords, without\n * the target's own definition unless something still refers to it.\n */\nfunction inlined(\n json: Readonly<Record<string, unknown>>,\n target: Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> {\n if (target === json) {\n return json;\n }\n const ref = String(json.$ref);\n const { $schema: dialect } = json;\n const schema: Record<string, unknown> = {\n ...(dialect === undefined ? {} : { $schema: dialect }),\n ...target,\n };\n for (const keyword of [\"definitions\", \"$defs\"]) {\n const defs = json[keyword];\n if (!isRecord(defs)) {\n continue;\n }\n const others = Object.fromEntries(\n Object.entries(defs).filter(([name]) => `#/${keyword}/${pointerToken(name)}` !== ref),\n );\n // The target's own entry stays only for a schema that still refers to it (a recursive one).\n const kept = refersTo({ ...schema, [keyword]: others }, ref) ? defs : others;\n if (Object.keys(kept).length > 0) {\n schema[keyword] = kept;\n }\n }\n return schema;\n}\n\n/** The input a call passes to a tool's handler or method, from the tool's arguments. */\nexport function inputOf(mode: ArgumentsMode, args: unknown): unknown {\n if (mode === \"object\") {\n return args ?? {};\n }\n return mode === \"wrapped\" && isRecord(args) ? args.input : undefined;\n}\n\n/** Whether a method is selected by `include` and `exclude`, after checking every reference names one. */\nfunction selector(\n services: readonly AnyService[],\n options: DescribeToolsOptions,\n fail: Fail,\n): (service: string, method: string) => boolean {\n const known = new Set<string>();\n for (const service of services) {\n known.add(service.name);\n for (const method of Object.keys(service.contract.methods)) {\n known.add(`${service.name}.${method}`);\n }\n }\n const refs = (key: \"include\" | \"exclude\"): ReadonlySet<string> | undefined => {\n const list: unknown = options[key];\n if (list === undefined) {\n return undefined;\n }\n if (!Array.isArray(list) || !list.every((ref) => typeof ref === \"string\")) {\n fail(`${key} must be a list of \"service\" and \"service.method\" names`);\n }\n const unknownRef = list.find((ref) => !known.has(ref));\n if (unknownRef !== undefined) {\n fail(`${key} names \"${unknownRef}\", which is not a service or method being served`);\n }\n return new Set(list);\n };\n const include = refs(\"include\");\n const exclude = refs(\"exclude\");\n const names = (set: ReadonlySet<string>, service: string, method: string): boolean =>\n set.has(service) || set.has(`${service}.${method}`);\n return (service, method) =>\n (include === undefined || names(include, service, method)) &&\n (exclude === undefined || !names(exclude, service, method));\n}\n\n/** The function that names a method's tool: the `name` option, checked, or `{service}_{method}`. */\nfunction toolNamer(\n options: DescribeToolsOptions,\n fail: Fail,\n): (service: string, method: string) => string {\n const { name } = options;\n if (name !== undefined && typeof name !== \"function\") {\n fail(\"name must be a function of (service, method)\");\n }\n return (service, method) => {\n const named: unknown =\n name === undefined ? defaultToolName(service, method) : name(service, method);\n if (typeof named !== \"string\" || named === \"\") {\n const shown = typeof named === \"string\" ? `\"\"` : String(named);\n fail(`name returned ${shown} for ${service}.${method}; a tool name is a non-empty string`);\n }\n return named;\n };\n}\n\nfunction describeMethod(service: string, method: string, kind: MethodKind, text: unknown): string {\n return typeof text === \"string\" && text !== \"\" ? text : `${service}.${method} (${kind})`;\n}\n\nfunction propertiesOf(schema: unknown): string[] {\n return isRecord(schema) && isRecord(schema.properties) ? Object.keys(schema.properties) : [];\n}\n\n/**\n * The arguments of `bind` that are properties of the object input of\n * `label`. Fails when one of them is a key the input `schema` may have\n * anywhere else (`inputKeys`: behind a `$ref`, in an `anyOf`, `oneOf` or\n * `allOf` branch, or the input is not an object), where it cannot be\n * filled. An input without arguments has none.\n */\nfunction boundArguments(\n label: string,\n input: ToolInput,\n schema: StandardSchemaV1,\n bind: readonly string[],\n fail: Fail,\n): string[] {\n if (bind.length === 0) {\n return [];\n }\n const bindable = input.mode === \"object\" ? propertiesOf(input.schema) : [];\n const keys = inputKeys(schema) ?? [];\n const misplaced = bind.find((key) => keys.includes(key) && !bindable.includes(key));\n if (misplaced !== undefined) {\n fail(\n `bind.${misplaced} names a property of the input of ${label}, which is not an object: bind fills properties of object inputs only (an object schema, or one with .meta({ id }); not a union, an intersection, or a schema made from an object, as .optional() or .refine() make); leave ${label} out with exclude, or make its input an object`,\n );\n }\n return bind.filter((key) => bindable.includes(key));\n}\n\n/** An object input's schema without the bound arguments, as the tool lists it. */\nfunction withoutArguments(schema: McpInputSchema, bound: readonly string[]): McpInputSchema {\n const kept = (key: string) => !bound.includes(key);\n const { properties = {}, required, ...rest } = schema;\n const stillRequired = required?.filter(kept) ?? [];\n return {\n ...rest,\n properties: Object.fromEntries(Object.entries(properties).filter(([key]) => kept(key))),\n ...(stillRequired.length === 0 ? {} : { required: stillRequired }),\n };\n}\n\n/**\n * The method tools of `services`, in service order and then contract order,\n * with what each calls. Fails on a reference, name or schema that cannot\n * make a tool; `fail` prefixes the message with the caller's name. `bind`\n * names the arguments a registry fills from the principal.\n */\nexport function planMethodTools(\n services: readonly AnyService[],\n options: DescribeToolsOptions,\n fail: Fail,\n bind: readonly string[] = [],\n): MethodTool[] {\n const given: unknown = services;\n if (!Array.isArray(given)) {\n fail(\"services must be an array of services from qd.defineService\");\n }\n const selected = selector(services, options, fail);\n const toolName = toolNamer(options, fail);\n const planned: MethodTool[] = [];\n for (const service of services) {\n for (const [method, def] of Object.entries(service.contract.methods)) {\n if (!selected(service.name, method)) {\n continue;\n }\n const label = `${service.name}.${method}`;\n const input = toolInputOf(label, def.input, fail);\n const bound = boundArguments(label, input, def.input, bind, fail);\n const tool: McpTool = {\n name: toolName(service.name, method),\n description: describeMethod(service.name, method, def.kind, def.describe),\n inputSchema: bound.length === 0 ? input.schema : withoutArguments(input.schema, bound),\n ...(def.kind === \"query\" ? { annotations: { readOnlyHint: true } } : {}),\n };\n planned.push({ ...input, tool: Object.freeze(tool), service: service.name, method, bound });\n }\n }\n return planned;\n}\n\n/** Fails when two tools share a name. `owners` names what each tool comes from, for the message. */\nexport function checkUniqueNames(\n tools: readonly { readonly tool: McpTool; readonly owner: string }[],\n fail: Fail,\n): void {\n const seen = new Map<string, string>();\n for (const { tool, owner } of tools) {\n const first = seen.get(tool.name);\n if (first !== undefined) {\n fail(`two tools are named \"${tool.name}\": ${first} and ${owner}`);\n }\n seen.set(tool.name, owner);\n }\n}\n\n/**\n * The MCP tools of `services`: one per contract method, named\n * `{service}_{method}` unless `name` says otherwise, described by the\n * method's `describe` text, with the input schema's JSON Schema as\n * `inputSchema` and `readOnlyHint` on every query. Throws when a method's\n * input schema cannot describe itself as JSON Schema (use Zod 4.2 or later),\n * when `include` or `exclude` names something that is not served, and when\n * two tools would share a name.\n *\n * @example\n * describeTools([taskService], { exclude: [\"taskService.purge\"] });\n */\nexport function describeTools<const S extends readonly AnyService[]>(\n services: S,\n options: DescribeToolsOptions<S> = {},\n): McpTool[] {\n const fail: Fail = (message) => {\n throw new TypeError(`describeTools: ${message}`);\n };\n const planned = planMethodTools(services, options as DescribeToolsOptions, fail);\n checkUniqueNames(\n planned.map((entry) => ({ tool: entry.tool, owner: `${entry.service}.${entry.method}` })),\n fail,\n );\n return planned.map((entry) => entry.tool);\n}\n","// The concurrency lane of an MCP call: the connection id its queries count\n// against (RFC 0003 section 9, step 2), as a socket's queries count against\n// their socket. A stdio session is one lane. Each HTTP request is a session\n// of its own, so its lane is its caller's (the 5.1 audit's MCP-4):\n//\n// - with a bearer token, the token's, by a hash (never the token itself). A\n// `principal` hook that authenticates by anything else (a cookie, an API\n// key header) must refuse a request whose bearer token it does not\n// verify: otherwise a caller makes a lane per made-up token;\n// - for a principal without a token, its user's;\n// - when anonymous, its address's: Express's `req.ip`, which follows the\n// app's `trust proxy` (behind a proxy without it, every anonymous caller\n// shares the proxy's lane), else the socket's. An IPv4-mapped IPv6\n// address counts as its IPv4 address, and an IPv6 address by its /56,\n// since one host commonly holds a /64 or more (as express-rate-limit\n// keys them).\n\nimport { createHash } from \"node:crypto\";\nimport { isIPv6 } from \"node:net\";\nimport type { Principal } from \"../types\";\nimport type { McpRequest } from \"./types\";\n\n/** The eight 16-bit groups of a valid IPv6 address. */\nfunction groupsOf(address: string): number[] {\n // The URL parser writes an embedded IPv4 address as two groups, and compresses one run of zeros.\n const written = new URL(`http://[${address}]/`).hostname.slice(1, -1);\n const [head = \"\", tail = \"\"] = written.split(\"::\");\n const parse = (part: string): number[] =>\n part === \"\" ? [] : part.split(\":\").map((group) => Number.parseInt(group, 16));\n const before = parse(head);\n const after = parse(tail);\n return [...before, ...new Array<number>(8 - before.length - after.length).fill(0), ...after];\n}\n\n/**\n * The address an anonymous caller's lane is named by: an IPv4 address as it\n * is, an IPv4-mapped IPv6 address as its IPv4 address, another IPv6 address\n * as its /56 network, and anything else as it is.\n */\nexport function addressLane(ip: string): string {\n const address = ip.split(\"%\", 1)[0] ?? ip;\n if (!isIPv6(address)) {\n return ip;\n }\n const [a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0] = groupsOf(address);\n if (a === 0 && b === 0 && c === 0 && d === 0 && e === 0 && f === 0xffff) {\n return [g >> 8, g & 0xff, h >> 8, h & 0xff].join(\".\");\n }\n // The first 56 bits: three groups, and the high byte of the fourth.\n return `${[a, b, c, d & 0xff00].map((group) => group.toString(16)).join(\":\")}::/56`;\n}\n\n/** The address an HTTP request came from: Express's `req.ip` (which honors trust proxy), or the socket's. */\nfunction addressOf(request: McpRequest & { readonly transport: \"http\" }): string {\n const { ip } = request.req as { readonly ip?: unknown };\n return typeof ip === \"string\" && ip !== \"\"\n ? ip\n : (request.req.socket?.remoteAddress ?? \"unknown\");\n}\n\n/** The lane a call's queries share: its stdio session's, or its HTTP caller's. */\nexport function laneOf(request: McpRequest, principal: Principal | null): string {\n if (request.transport === \"stdio\") {\n return `mcp:${request.sessionId}`;\n }\n if (principal === null) {\n return `mcp:http:address:${addressLane(addressOf(request))}`;\n }\n if (request.token === null) {\n return `mcp:http:user:${principal.userId}`;\n }\n const hash = createHash(\"sha256\").update(request.token).digest(\"base64url\").slice(0, 22);\n return `mcp:http:token:${hash}`;\n}\n","// What a tool call runs as: the principal the registry's `principal` hook\n// maps the session or token to, the `ctx.mcp` fields its `context` hook adds,\n// and a synthetic connection id: the concurrency lane its queries share (RFC\n// 0003 section 9, step 2), as a socket's queries do. A stdio session is one\n// lane; an HTTP request's lane is its caller's (`lanes.ts`; the 5.1 audit's\n// MCP-4): its bearer token's, its user's without a token, or its address's\n// when anonymous. A hook's refusal (`QuickdrawError` `UNAUTHENTICATED` or\n// `FORBIDDEN`) is logged at debug.\n\nimport type { Logger } from \"../../contract/logger\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { lazyMembers, type CallOptions } from \"../caller\";\nimport { toQuickdrawError } from \"../pipeline/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport type { DispatchRequest, DispatchResult } from \"../pipeline/request\";\nimport { isForbiddenCredential, isRefusal, toPrincipal } from \"../transports/auth\";\nimport type { McpContext, Principal } from \"../types\";\nimport { laneOf } from \"./lanes\";\nimport type { McpCallOptions, McpCallResult, McpRequest } from \"./types\";\n\n/** Who a tool call acts for, what it adds to `ctx.mcp`, and the connection it counts against. */\nexport interface McpSession {\n readonly principal: Principal | null;\n readonly mcp: McpContext | undefined;\n readonly connectionId: string;\n}\n\n/** The registry's `principal` option, as the bridge calls it. */\nexport type PrincipalHook = (request: McpRequest) => unknown;\n\n/** The registry's `context` option, as the bridge calls it. */\nexport type ContextHook = (request: McpRequest, principal: Principal | null) => unknown;\n\n/** What resolving sessions and making calls in them needs. */\nexport interface SessionSettings {\n readonly dispatcher: { call(request: DispatchRequest): Promise<DispatchResult> };\n readonly principal: PrincipalHook | undefined;\n readonly context: ContextHook | undefined;\n readonly logger: Logger;\n}\n\nconst CATEGORY = \"quickdraw.mcp\";\n\nasync function principalOf(\n settings: SessionSettings,\n request: McpRequest,\n): Promise<Principal | null> {\n if (settings.principal === undefined) {\n return null;\n }\n try {\n return toPrincipal(await settings.principal(request));\n } catch (error) {\n // A refusal the hook made on purpose is the caller's doing; a hook that broke is the app's.\n const refused = isRefusal(error) || isForbiddenCredential(error);\n settings.logger[refused ? \"debug\" : \"error\"](\"MCP authentication failed\", {\n category: CATEGORY,\n transport: request.transport,\n error: describeError(error),\n });\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication failed\");\n }\n}\n\nasync function contextOf(\n settings: SessionSettings,\n request: McpRequest,\n principal: Principal | null,\n): Promise<McpContext | undefined> {\n if (settings.context === undefined) {\n return undefined;\n }\n const fields: unknown = await settings.context(request, principal);\n if (fields === undefined) {\n return undefined;\n }\n if (typeof fields !== \"object\" || fields === null) {\n throw new TypeError(\"createMcpRegistry: context must return an object, the fields of ctx.mcp\");\n }\n return fields as McpContext;\n}\n\n/**\n * Resolves who a call on `request` acts for and its `ctx.mcp` fields. Rejects\n * with `UNAUTHENTICATED` when the `principal` hook fails; a failing `context`\n * hook rejects with its own error.\n */\nexport async function openSession(\n settings: SessionSettings,\n request: McpRequest,\n): Promise<McpSession> {\n const principal = await principalOf(settings, request);\n const mcp = await contextOf(settings, request, principal);\n return { principal, mcp, connectionId: laneOf(request, principal) };\n}\n\n/** A failed call's result. An `INTERNAL` failure is logged with what was thrown. */\nexport function failure(settings: SessionSettings, error: unknown, tool: string): McpCallResult {\n const converted = toQuickdrawError(error);\n if (converted.code === \"INTERNAL\") {\n settings.logger.error(`The MCP tool \"${tool}\" failed`, {\n category: CATEGORY,\n tool,\n error: describeError(converted),\n });\n }\n return { ok: false, error: converted };\n}\n\n/**\n * Hands `result` to the transport's `respond`, when it gave one, and returns\n * it. An error `respond` throws is logged and does not change the result.\n */\nexport function settle(\n settings: SessionSettings,\n options: McpCallOptions,\n result: McpCallResult,\n): McpCallResult {\n try {\n options.respond?.(result);\n } catch (error) {\n settings.logger.error(\"An MCP transport failed to send a reply\", {\n category: CATEGORY,\n error: describeError(error),\n });\n }\n return result;\n}\n\n/** A dispatcher result as a tool call's result. MCP calls never send a version, so never \"not modified\". */\nexport function fromDispatch(result: DispatchResult): McpCallResult {\n if (!result.ok) {\n return { ok: false, error: result.error };\n }\n return { ok: true, data: result.notModified === true ? undefined : result.data };\n}\n\n/** The dispatcher request of one method call made in `session`. */\nexport function sessionRequest(\n session: McpSession,\n call: Pick<DispatchRequest, \"service\" | \"method\" | \"input\" | \"signal\" | \"respond\">,\n): DispatchRequest {\n return {\n ...call,\n principal: session.principal,\n transport: \"mcp\",\n connectionId: session.connectionId,\n mcp: session.mcp,\n };\n}\n\ntype MethodFunction = (input?: unknown, options?: CallOptions) => Promise<unknown>;\n\n/**\n * An in-process caller acting in `session`: each call goes through the\n * dispatcher as an MCP call, with the session's principal, connection and\n * `ctx.mcp`, so a custom tool cannot reach past what the agent may do.\n */\nexport function sessionCaller(\n settings: SessionSettings,\n session: McpSession,\n signal: AbortSignal,\n): object {\n return lazyMembers((service) =>\n lazyMembers<MethodFunction>((method) => async (input, options) => {\n const request = sessionRequest(session, {\n service,\n method,\n input,\n signal: options?.signal ?? signal,\n });\n const result = await settings.dispatcher.call(request);\n if (!result.ok) {\n throw result.error;\n }\n return result.notModified === true ? undefined : result.data;\n }),\n );\n}\n","// Custom tools (RFC 0003 section 10): an app's own tools, served beside the\n// ones generated from contracts. 4.1's registry had no hook for them\n// (4.1 `src/server/mcp/McpRegistry.ts:13`), so apps that needed one ran a\n// bridge of their own. A custom tool fails closed like a method: unless it\n// declares `access: \"public\"`, an anonymous caller is refused before anything\n// runs, and a principal of a kind the tool does not admit (its `kinds`,\n// within the app's `initQuickdraw({ kinds })`, which it admits by default)\n// is refused too (`FORBIDDEN`, the 5.1 audit's MCP-6). A custom tool that\n// gives a Standard Schema has its arguments validated before its handler\n// runs, as a method's input is, and every handler gets a caller that acts in\n// the same session.\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"../../contract/standardSchema\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { checkKind, narrowKinds } from \"../access/kinds\";\nimport { NEVER_ABORTED } from \"../context\";\nimport { parseInput } from \"../pipeline/validation\";\nimport { runtimeOf, type AnyService } from \"../service\";\nimport { failure, sessionCaller, type McpSession, type SessionSettings } from \"./session\";\nimport { inputOf, toolInputOf, type ArgumentsMode, type ToolInput } from \"./tools\";\nimport type {\n McpCallOptions,\n McpCallResult,\n McpInputSchema,\n McpTool,\n McpToolAccess,\n McpToolCall,\n} from \"./types\";\n\n/** A checked custom tool. */\nexport interface CustomTool {\n readonly tool: McpTool;\n /** Who may call it; `\"authenticated\"` unless the tool said otherwise. */\n readonly access: McpToolAccess;\n /** The kinds of principal that may call it: its own, or the app's; `undefined` admits every kind. */\n readonly kinds: readonly string[] | undefined;\n readonly mode: ArgumentsMode;\n /** The schema that validates the arguments, when the tool gave a Standard Schema. */\n readonly schema: StandardSchemaV1 | undefined;\n readonly handler: (call: McpToolCall) => unknown;\n}\n\ntype Fail = (message: string) => never;\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction argumentsOf(owner: string, inputSchema: unknown, fail: Fail): ToolInput {\n if (isStandardSchema(inputSchema)) {\n return toolInputOf(owner, inputSchema, fail, \"give the tool a JSON Schema object instead\");\n }\n if (isRecord(inputSchema) && inputSchema.type === \"object\") {\n return { schema: inputSchema as McpInputSchema, mode: \"object\" };\n }\n return fail(\n `${owner}: inputSchema must be a Standard Schema, or a JSON Schema whose type is \"object\"`,\n );\n}\n\nfunction accessOf(owner: string, access: unknown, fail: Fail): McpToolAccess {\n if (access === undefined) {\n return \"authenticated\";\n }\n if (access !== \"public\" && access !== \"authenticated\") {\n fail(`${owner}: access must be \"public\" or \"authenticated\"`);\n }\n return access;\n}\n\n/**\n * The kinds every one of `services` admits: what their apps'\n * `initQuickdraw({ kinds })` admit, in common; `undefined` admits every kind.\n */\nfunction appKindsOf(services: readonly AnyService[]): readonly string[] | undefined {\n let kinds: readonly string[] | undefined;\n for (const service of services) {\n const own = runtimeOf(service)?.kinds;\n if (own !== undefined) {\n kinds = kinds === undefined ? own : kinds.filter((kind) => own.includes(kind));\n }\n }\n return kinds;\n}\n\nfunction kindsOf(\n owner: string,\n value: Readonly<Record<string, unknown>>,\n access: McpToolAccess,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): readonly string[] | undefined {\n if (value.kinds !== undefined && access === \"public\") {\n fail(\n `${owner}: a \"public\" tool takes no kinds of its own, since a caller of a refused kind could call it signed out; give it access \"authenticated\"`,\n );\n }\n const above = appKinds === undefined ? undefined : { kinds: appKinds, by: \"initQuickdraw\" };\n return narrowKinds(value.kinds, above, (message) => fail(`${owner}: ${message}`));\n}\n\nfunction checkCustomTool(\n value: unknown,\n index: number,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): CustomTool {\n if (!isRecord(value)) {\n fail(`customTools[${index}] must be { name, description, inputSchema, handler }`);\n }\n const { name, description, inputSchema, annotations, handler } = value;\n if (typeof name !== \"string\" || name === \"\") {\n fail(`customTools[${index}] needs a name, a non-empty string`);\n }\n const owner = `custom tool \"${name}\"`;\n if (typeof description !== \"string\" || description === \"\") {\n fail(`${owner} needs a description, a non-empty string`);\n }\n if (typeof handler !== \"function\") {\n fail(`${owner} needs a handler function`);\n }\n if (annotations !== undefined && !isRecord(annotations)) {\n fail(`${owner}: annotations must be an object of hints`);\n }\n const access = accessOf(owner, value.access, fail);\n const kinds = kindsOf(owner, value, access, appKinds, fail);\n const input = argumentsOf(owner, inputSchema, fail);\n const tool: McpTool = {\n name,\n description,\n inputSchema: input.schema,\n ...(annotations === undefined ? {} : { annotations }),\n };\n return {\n tool: Object.freeze(tool),\n access,\n kinds,\n mode: input.mode,\n schema: isStandardSchema(inputSchema) ? inputSchema : undefined,\n handler: handler as CustomTool[\"handler\"],\n };\n}\n\n/** Checks the registry's `customTools` option, served beside `services`, whose apps' kinds they narrow. */\nexport function checkCustomTools(\n value: unknown,\n fail: Fail,\n services: readonly AnyService[] = [],\n): CustomTool[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value)) {\n fail(\"customTools must be an array of { name, description, inputSchema, handler }\");\n }\n const appKinds = appKindsOf(services);\n if (appKinds?.length === 0 && value.length > 0) {\n fail(\n \"customTools: the served services' apps admit no kind in common (initQuickdraw({ kinds })), so no principal could call a custom tool: serve custom tools beside the services of one app, or of apps that admit a kind in common\",\n );\n }\n return value.map((tool: unknown, index) => checkCustomTool(tool, index, appKinds, fail));\n}\n\n/**\n * Runs a custom tool with the arguments `args` in `session`: refuses an\n * anonymous caller unless the tool's access is `\"public\"`\n * (`UNAUTHENTICATED`) and a principal of a kind it does not admit\n * (`FORBIDDEN`), validates the arguments when the tool gave a Standard\n * Schema (`VALIDATION` with the issues otherwise), then runs the handler.\n * Never rejects.\n */\nexport async function runCustomTool(\n settings: SessionSettings,\n custom: CustomTool,\n args: unknown,\n session: McpSession,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const { name } = custom.tool;\n const signal = options.signal ?? NEVER_ABORTED;\n try {\n if (custom.access === \"authenticated\" && session.principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n checkKind(custom.kinds, session.principal, `The tool \"${name}\"`);\n const input = inputOf(custom.mode, args);\n const parsed =\n custom.schema === undefined\n ? input\n : await parseInput(custom.schema, input, `the tool \"${name}\"`);\n const data: unknown = await custom.handler({\n arguments: parsed,\n principal: session.principal,\n mcp: session.mcp,\n caller: sessionCaller(settings, session, signal) as McpToolCall[\"caller\"],\n signal,\n request: options.request,\n });\n return { ok: true, data };\n } catch (error) {\n return failure(settings, error, name);\n }\n}\n","// `createMcpRegistry` (RFC 0003 section 10): the tools of an app's services,\n// generated from their contracts, plus the app's own, and one `call` every\n// MCP transport uses. It replaces 4.1's `McpRegistry`\n// (4.1 `src/server/mcp/McpRegistry.ts:13`), which validated input, checked\n// access and ran handlers itself, as whatever user the tool's `userId`\n// argument named. Here a method's tool call goes through the dispatcher with\n// transport `\"mcp\"`, so validation and access checks apply as for a socket\n// call, and its queries share a concurrency lane per caller (`session.ts`);\n// the transport says who is calling through `principal`, and `context` adds\n// the session's own fields to the handler's `ctx.mcp`. `bind` fills chosen\n// arguments from that principal instead of the agent, so an agent bound to\n// one task cannot name another in its calls, and a call that sends a bound\n// argument its tool does not fill is refused (`FORBIDDEN`).\n\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport type { Dispatcher, PrincipalOfServices } from \"../dispatcher\";\nimport type { AnyService } from \"../service\";\nimport type { AuthenticateResult } from \"../transports/auth\";\nimport type { MaybePromise } from \"../types\";\nimport { checkCustomTools, runCustomTool, type CustomTool } from \"./custom\";\nimport {\n failure,\n fromDispatch,\n openSession,\n sessionRequest,\n settle,\n type McpSession,\n type SessionSettings,\n} from \"./session\";\nimport { checkUniqueNames, inputOf, planMethodTools, type MethodTool } from \"./tools\";\nimport type {\n DescribeToolsOptions,\n McpBindCall,\n McpBinder,\n McpCallOptions,\n McpCallResult,\n McpContextOfServices,\n McpCustomTool,\n McpRequest,\n McpTool,\n McpToolInputSchema,\n} from \"./types\";\n\n/**\n * Options of {@link createMcpRegistry}. `Tools` are the custom tools' input\n * schema types, one per tool, which type each handler's `arguments`.\n */\nexport interface McpRegistryOptions<\n S extends readonly AnyService[],\n Tools extends readonly McpToolInputSchema[] = readonly McpToolInputSchema[],\n> extends DescribeToolsOptions<S> {\n /** The services whose methods become tools. The dispatcher must serve each of them. */\n readonly services: S;\n /** The dispatcher every method's tool calls through, with transport `\"mcp\"`. */\n readonly dispatcher: Pick<Dispatcher, \"call\" | \"registry\">;\n /**\n * Says who an MCP session or request acts for: a principal, a user id when\n * a bare `{ userId }` is a principal of the app's type, or nothing for an\n * anonymous caller, who may call `\"public\"` methods and `\"public\"` custom\n * tools only. A stdio server usually reads a token from its environment;\n * an HTTP request carries one as a bearer token. Throwing fails the call\n * with `UNAUTHENTICATED`: throw `QuickdrawError(\"UNAUTHENTICATED\")` (or\n * `FORBIDDEN`) to refuse a token, which is logged at debug, and never put\n * the token in a message; anything else thrown is logged as an error.\n * Without it every call is anonymous. An HTTP request's queries share the\n * lane of its bearer token: a hook that authenticates by anything else (a\n * cookie, an API key header) must refuse a request whose bearer token it\n * does not verify, or a caller makes a lane per made-up token.\n */\n readonly principal?: (\n request: McpRequest,\n ) => MaybePromise<AuthenticateResult<PrincipalOfServices<S>>>;\n /**\n * The fields handlers see as `ctx.mcp` on calls from this registry, typed\n * by the app's `QuickdrawTypes[\"mcp\"]`: the scopes of the agent's token,\n * for example. Runs per call, after `principal`.\n */\n readonly context?: (\n request: McpRequest,\n principal: PrincipalOfServices<S> | null,\n ) => MaybePromise<McpContextOfServices<S>>;\n /**\n * Arguments filled from who is calling instead of by the agent, by name:\n * `{ taskId: ({ principal }) => principal.claims?.taskId }`. Each one is\n * left out of the `inputSchema` of every method's tool whose object input\n * has it, and each call of such a tool, by `call` or `callMethod`, gets the\n * binder's value before its input is validated. The call is refused\n * before the method runs when the caller is anonymous (`UNAUTHENTICATED`),\n * or when the binder returns `undefined` or `null` or the caller sent the\n * argument with another value (`FORBIDDEN`); a binder that throws fails it\n * with `INTERNAL`, or with the code of a `QuickdrawError`. A call of any\n * other method's tool that sends a bound argument is refused (`FORBIDDEN`).\n * An input that is a `$ref` to an object counts as that object, and a\n * bound key anywhere else in an input (in a union's or an intersection's\n * branch, or an input that is no object) fails when the registry is built.\n * Only top-level arguments are bound. Custom tools are never bound.\n * Binding is not access control: the same principal reaches the method\n * over a socket or HTTP with nothing bound, so the method's access must\n * still confine it.\n */\n readonly bind?: Readonly<Record<string, McpBinder<S>>>;\n /** The app's own tools, listed after the generated ones. */\n readonly customTools?: { readonly [K in keyof Tools]: McpCustomTool<S, Tools[K]> };\n /** Receives tool failures and authentication errors. Default: the console. */\n readonly logger?: Logger;\n}\n\n/** The tools an MCP transport serves, and the one way to call them. */\nexport interface McpRegistry {\n /**\n * Every tool, generated ones first, as `tools/list` and `GET /mcp/tools`\n * return them: the same list for every caller, never filtered by the\n * principal, so an agent may see tools whose calls are refused. A\n * registry's `include`/`exclude` decide the list; serve agents of\n * different reach from separate registries.\n */\n readonly tools: readonly McpTool[];\n /** True when a tool has this name. */\n has(name: string): boolean;\n /**\n * Calls the tool `name` with the client's `args` in the session of\n * `options.request`. Resolves with the tool's value or its failure (an\n * unknown name is `NOT_FOUND`), after `options.respond` was given it.\n * Never rejects.\n */\n call(name: string, args: unknown, options: McpCallOptions): Promise<McpCallResult>;\n /**\n * Calls a method's tool by its service and method name with the method's\n * `input` as it is, without the tool's argument mapping: the shape 4.1's\n * HTTP route took. Bound arguments are filled as for `call`. A method that\n * is not a tool is `NOT_FOUND`.\n */\n callMethod(\n service: string,\n method: string,\n input: unknown,\n options: McpCallOptions,\n ): Promise<McpCallResult>;\n}\n\ntype Entry =\n | ({ readonly kind: \"method\" } & MethodTool)\n | ({ readonly kind: \"custom\" } & CustomTool);\n\n/** A function of the registry's `bind` option, as the bridge calls it. */\ntype BindHook = (call: McpBindCall) => unknown;\n\ninterface RegistrySettings extends SessionSettings {\n /** Every tool by name, in listing order. */\n readonly entries: ReadonlyMap<string, Entry>;\n /** The method tools by {@link methodKey}. */\n readonly methods: ReadonlyMap<string, MethodTool>;\n /** The `bind` option's functions by the argument each fills. */\n readonly binders: ReadonlyMap<string, BindHook>;\n}\n\ntype Fail = (message: string) => never;\n\n/** A method's key, unambiguous whatever characters its names hold. */\nfunction methodKey(service: string, method: string): string {\n return `${service}\\u0000${method}`;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction checkHook(name: string, hook: unknown, fail: Fail): void {\n if (hook !== undefined && typeof hook !== \"function\") {\n fail(`${name} must be a function of the MCP request`);\n }\n}\n\n/** Fails unless `dispatcher` serves every one of `services`, as the very same service objects. */\nfunction checkDispatcher(dispatcher: unknown, services: unknown, fail: Fail): void {\n if (\n !isRecord(dispatcher) ||\n typeof dispatcher.call !== \"function\" ||\n !isRecord(dispatcher.registry) ||\n !(dispatcher.registry.services instanceof Map)\n ) {\n fail(\"dispatcher must be a dispatcher from createDispatcher or qd.createServer\");\n }\n if (!Array.isArray(services)) {\n fail(\"services must be an array of services from qd.defineService\");\n }\n const served = dispatcher.registry.services as ReadonlyMap<string, unknown>;\n for (const service of services) {\n const name: unknown = isRecord(service) ? service.name : undefined;\n if (typeof name !== \"string\" || served.get(name) !== service) {\n fail(\n `the dispatcher does not serve ${typeof name === \"string\" ? name : \"one of the services\"}; pass services the dispatcher was created with`,\n );\n }\n }\n}\n\n/** Checks the registry's `bind` option: an object of functions, one per argument. */\nfunction checkBinders(bind: unknown, fail: Fail): ReadonlyMap<string, BindHook> {\n if (bind === undefined) {\n return new Map();\n }\n if (!isRecord(bind) || Array.isArray(bind)) {\n fail(\"bind must be an object of functions, one per argument it fills\");\n }\n const binders = new Map<string, BindHook>();\n for (const [key, binder] of Object.entries(bind)) {\n if (typeof binder !== \"function\") {\n fail(`bind.${key} must be a function of the call, returning the argument's value`);\n }\n binders.set(key, binder as BindHook);\n }\n return binders;\n}\n\n/** Fails when an argument of `bind` is in no tool's object input: a misspelled name would bind nothing. */\nfunction checkBound(\n binders: ReadonlyMap<string, BindHook>,\n methodTools: readonly MethodTool[],\n fail: Fail,\n): void {\n for (const key of binders.keys()) {\n if (!methodTools.some((tool) => tool.bound.includes(key))) {\n fail(\n `bind.${key} fills nothing: no method served as a tool has \"${key}\" in its object input`,\n );\n }\n }\n}\n\nfunction resolveRegistry(options: McpRegistryOptions<readonly AnyService[]>): RegistrySettings {\n const fail: Fail = (message) => {\n throw new TypeError(`createMcpRegistry: ${message}`);\n };\n if (!isRecord(options)) {\n fail(\"options must be an object with services and dispatcher\");\n }\n checkDispatcher(options.dispatcher, options.services, fail);\n checkHook(\"principal\", options.principal, fail);\n checkHook(\"context\", options.context, fail);\n const binders = checkBinders(options.bind, fail);\n const methodTools = planMethodTools(options.services, options, fail, [...binders.keys()]);\n checkBound(binders, methodTools, fail);\n const customTools = checkCustomTools(options.customTools, fail, options.services);\n const entries: Entry[] = [\n ...methodTools.map((tool) => ({ kind: \"method\" as const, ...tool })),\n ...customTools.map((tool) => ({ kind: \"custom\" as const, ...tool })),\n ];\n checkUniqueNames(\n entries.map((entry) => ({\n tool: entry.tool,\n owner: entry.kind === \"method\" ? `${entry.service}.${entry.method}` : \"a custom tool\",\n })),\n fail,\n );\n return {\n dispatcher: options.dispatcher,\n principal: options.principal,\n context: options.context as SessionSettings[\"context\"],\n logger: options.logger ?? consoleLogger,\n entries: new Map(entries.map((entry) => [entry.tool.name, entry])),\n methods: new Map(methodTools.map((tool) => [methodKey(tool.service, tool.method), tool])),\n binders,\n };\n}\n\n/** Runs `run` in the session of `options.request`, or fails the call when the session cannot open. */\nasync function inSession(\n settings: RegistrySettings,\n name: string,\n options: McpCallOptions,\n run: (session: McpSession) => Promise<McpCallResult>,\n): Promise<McpCallResult> {\n let session: McpSession;\n try {\n session = await openSession(settings, options.request);\n } catch (error) {\n return settle(settings, options, failure(settings, error, name));\n }\n return run(session);\n}\n\n/**\n * The input of a call of a tool with bound arguments: `input` with each of\n * them filled by its binder. Rejects with `UNAUTHENTICATED` for an anonymous\n * caller, `VALIDATION` when the arguments are not an object, and `FORBIDDEN`\n * when a binder has no value or the caller sent another one.\n */\nasync function bindInput(\n settings: RegistrySettings,\n tool: MethodTool,\n input: unknown,\n session: McpSession,\n request: McpRequest,\n): Promise<unknown> {\n const { principal } = session;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const given: unknown = input ?? {};\n if (!isRecord(given) || Array.isArray(given)) {\n throw new QuickdrawError(\"VALIDATION\", `Invalid input for ${tool.service}.${tool.method}`, {\n issues: [{ path: [], message: \"Expected an object\" }],\n });\n }\n const call: McpBindCall = {\n principal,\n mcp: session.mcp,\n request,\n service: tool.service,\n method: tool.method,\n };\n const filled: [string, unknown][] = [];\n for (const [key, binder] of settings.binders) {\n if (!tool.bound.includes(key)) {\n continue;\n }\n const value = await binder(call);\n if (value === undefined || value === null) {\n throw new QuickdrawError(\"FORBIDDEN\", `\"${key}\" is bound to the caller, who has none`);\n }\n // The binder's value replaces what the caller sent. Another value is\n // refused rather than replaced in silence, so an agent never believes it\n // called with the value it named.\n const sent = Object.hasOwn(given, key) ? given[key] : undefined;\n if (sent !== undefined && JSON.stringify(sent) !== JSON.stringify(value)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${key}\" is bound to the caller and cannot be set to another value`,\n );\n }\n filled.push([key, value]);\n }\n return { ...given, ...Object.fromEntries(filled) };\n}\n\n/** Calls a method through the dispatcher, which hands the result to `respond` before it flushes. */\nasync function dispatchMethod(\n settings: RegistrySettings,\n tool: MethodTool,\n input: unknown,\n session: McpSession,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n // A bound argument the tool does not fill is never the agent's to send (MCP-1): refused, not passed on.\n const stray =\n settings.binders.size === 0 || !isRecord(input) || Array.isArray(input)\n ? undefined\n : [...settings.binders.keys()].find(\n (key) => !tool.bound.includes(key) && Object.hasOwn(input, key),\n );\n if (stray !== undefined) {\n const error = new QuickdrawError(\n \"FORBIDDEN\",\n `\"${stray}\" is bound to the caller; ${tool.service}.${tool.method} does not take it from the agent`,\n );\n return settle(settings, options, failure(settings, error, tool.tool.name));\n }\n let bound = input;\n if (tool.bound.length > 0) {\n try {\n bound = await bindInput(settings, tool, input, session, options.request);\n } catch (error) {\n return settle(settings, options, failure(settings, error, tool.tool.name));\n }\n }\n const { respond } = options;\n const request = sessionRequest(session, {\n service: tool.service,\n method: tool.method,\n input: bound,\n signal: options.signal,\n respond: respond === undefined ? undefined : (result) => respond(fromDispatch(result)),\n });\n return fromDispatch(await settings.dispatcher.call(request));\n}\n\nfunction callTool(\n settings: RegistrySettings,\n name: string,\n args: unknown,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const entry = settings.entries.get(name);\n if (entry === undefined) {\n const error = new QuickdrawError(\"NOT_FOUND\", `Unknown tool \"${name}\"`);\n return Promise.resolve(settle(settings, options, { ok: false, error }));\n }\n if (entry.kind === \"method\") {\n const input = inputOf(entry.mode, args);\n return inSession(settings, name, options, (session) =>\n dispatchMethod(settings, entry, input, session, options),\n );\n }\n return inSession(settings, name, options, async (session) =>\n settle(settings, options, await runCustomTool(settings, entry, args, session, options)),\n );\n}\n\nfunction callMethodTool(\n settings: RegistrySettings,\n service: string,\n method: string,\n input: unknown,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const tool = settings.methods.get(methodKey(service, method));\n if (tool === undefined) {\n const error = new QuickdrawError(\"NOT_FOUND\", `${service}.${method} is not an MCP tool`);\n return Promise.resolve(settle(settings, options, { ok: false, error }));\n }\n return inSession(settings, tool.tool.name, options, (session) =>\n dispatchMethod(settings, tool, input, session, options),\n );\n}\n\n/**\n * Builds the MCP tools of `services` (see `describeTools`) and the app's\n * `customTools`, served by `dispatcher`. Throws at once when a method's\n * input schema cannot describe itself as JSON Schema (use Zod 4.2 or later\n * for it, or `exclude` the method), when two tools share a name, when the\n * dispatcher does not serve one of the services, when an argument of\n * `bind` is in no tool's object input or may be anywhere in an input where\n * it cannot be filled (an input that is not an object schema, or a branch\n * of a union or an intersection, behind a `$ref` too), or when custom tools\n * are served beside the services of apps that admit no kind in common.\n * Every call runs in its caller's concurrency lane: a stdio session, or on\n * HTTP its bearer token, its user without a token, or its address when\n * anonymous.\n *\n * @example\n * const registry = createMcpRegistry({\n * services: [taskService, projectService],\n * dispatcher: server.dispatcher,\n * principal: (request) => verifyAgentToken(request.transport === \"http\" ? request.token : process.env.AGENT_TOKEN),\n * context: (request) => ({ scopes: scopesOf(request) }),\n * });\n */\nexport function createMcpRegistry<\n const S extends readonly AnyService[],\n const Tools extends readonly McpToolInputSchema[] = [],\n>(options: McpRegistryOptions<S, Tools>): McpRegistry {\n const settings = resolveRegistry(options as unknown as McpRegistryOptions<readonly AnyService[]>);\n const tools = Object.freeze([...settings.entries.values()].map((entry) => entry.tool));\n return Object.freeze({\n tools,\n has: (name: string) => settings.entries.has(name),\n call: (name: string, args: unknown, callOptions: McpCallOptions) =>\n callTool(settings, name, args, callOptions),\n callMethod: (service: string, method: string, input: unknown, callOptions: McpCallOptions) =>\n callMethodTool(settings, service, method, input, callOptions),\n });\n}\n","// A tool call's result in the shape of MCP's `tools/call` result, as 4.1\n// wrote it (4.1 `src/server/mcp/McpStdioServer.ts:85-96`): one text block\n// holding the value as indented JSON. A failure is a tool error (`isError`)\n// whose text is the error's wire form, `{ code, message, data? }`, so the\n// agent sees the code; 4.1 answered a failed call with a JSON-RPC error\n// instead. An `INTERNAL` failure keeps its generic message (`toWire`).\n\nimport { toWire } from \"../../protocol/errors\";\nimport type { McpCallResult, McpTextContent, McpToolResult } from \"./types\";\n\nfunction jsonText(value: unknown): McpTextContent {\n // `JSON.stringify` returns `undefined` for `undefined` (a method that\n // returns nothing) and for a function.\n const text: string | undefined = JSON.stringify(value, null, 2);\n return { type: \"text\", text: text ?? \"null\" };\n}\n\n/**\n * The `tools/call` result of a tool call. Throws when the value cannot be\n * written as JSON (a `BigInt` or a cycle); a transport answers that with an\n * `INTERNAL` tool error.\n *\n * @example\n * toToolResult(await registry.call(name, args, { request }));\n */\nexport function toToolResult(result: McpCallResult): McpToolResult {\n if (!result.ok) {\n return { content: [jsonText(toWire(result.error))], isError: true };\n }\n return { content: [jsonText(result.data)] };\n}\n","// The MCP stdio server: JSON-RPC 2.0, one message per line, on stdin and\n// stdout (RFC 0003 section 10). Ported from 4.1's `createMcpStdioServer`\n// (4.1 `src/server/mcp/McpStdioServer.ts:22`), keeping its wire format:\n// protocol version 2024-11-05, `initialize`, `ping`, `tools/list` and\n// `tools/call`, a tool's value as one block of JSON text, and the same\n// JSON-RPC error codes. What changed:\n//\n// - tools come from the registry, and who is calling from its `principal`\n// hook, rather than from a `userId` argument any agent could set;\n// - a failed call is a tool result with `isError` whose text carries the\n// error's code, where 4.1 answered with a JSON-RPC error;\n// - requests are handled concurrently, so the session's queries share one\n// concurrency lane, and `notifications/cancelled` stops a call in flight\n// (MCP sends no reply for a cancelled request);\n// - notifications never get a reply, and a JSON-RPC response from the client\n// is ignored;\n// - it never exits the process: `closed` resolves once stdin ends and every\n// call still running has answered (a client that writes its requests and\n// closes stdin still gets every reply), while `close()` and a broken\n// stream cancel the calls in flight instead.\n//\n// Anything else that writes to stdout corrupts the protocol, so start the\n// server through `bootstrapMcpServer`, which sends console output to stderr.\n\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport type { Logger } from \"../../contract/logger\";\nimport { INTERNAL_MESSAGE, QuickdrawError } from \"../../protocol/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport type { McpRegistry } from \"./registry\";\nimport { toToolResult } from \"./result\";\nimport { stderrLogger } from \"./stderr\";\nimport type { McpCallResult, McpStdioRequest } from \"./types\";\n\n/** The MCP protocol version the stdio server speaks: 4.1's. */\nexport const MCP_PROTOCOL_VERSION = \"2024-11-05\";\n\n/** Options of {@link createMcpStdioServer}. */\nexport interface McpStdioServerOptions {\n /** The tools to serve. */\n readonly registry: McpRegistry;\n /** The server's name, sent in `initialize`'s `serverInfo`. */\n readonly name: string;\n /** The server's version, sent in `initialize`'s `serverInfo`. */\n readonly version: string;\n /** Where messages arrive. Default `process.stdin`. */\n readonly input?: Readable;\n /** Where replies go. Default `process.stdout`. */\n readonly output?: Writable;\n /** Receives the server's own problems. Default: one line per entry on stderr. */\n readonly logger?: Logger;\n}\n\n/** A running stdio server. */\nexport interface McpStdioServer {\n /** The session id every call of this server carries, and its synthetic connection. */\n readonly sessionId: string;\n /**\n * Resolves once the input has ended and every message in flight has been\n * handled: when stdin ends, the calls still running finish and their\n * replies are written first.\n */\n readonly closed: Promise<void>;\n /** Stops reading and cancels the calls in flight (no reply is written for them); resolves as `closed` does. */\n close(): Promise<void>;\n}\n\ntype RequestId = string | number;\n\ninterface Session {\n readonly registry: McpRegistry;\n readonly serverInfo: { readonly name: string; readonly version: string };\n readonly request: McpStdioRequest;\n readonly output: Writable;\n readonly logger: Logger;\n /** The `tools/call` requests in flight, by id, so they can be cancelled. */\n readonly calls: Map<RequestId, AbortController>;\n /** Every message still being handled. */\n readonly pending: Set<Promise<void>>;\n /** False once the output failed. */\n writable: boolean;\n}\n\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INVALID_PARAMS = -32602;\nconst CATEGORY = \"quickdraw.mcp\";\n\nconst INTERNAL_FAILURE: McpCallResult = Object.freeze({\n ok: false,\n error: new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE),\n});\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** MCP request ids are strings or numbers, never `null`. */\nfunction isRequestId(value: unknown): value is RequestId {\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value));\n}\n\n/** Writes one message as one line; returns its size in bytes. */\nfunction write(session: Session, message: object): number | undefined {\n if (!session.writable) {\n return undefined;\n }\n const line = `${JSON.stringify(message)}\\n`;\n session.output.write(line);\n return Buffer.byteLength(line);\n}\n\nfunction reply(session: Session, id: RequestId, result: unknown): number | undefined {\n return write(session, { jsonrpc: \"2.0\", id, result });\n}\n\nfunction replyError(session: Session, id: RequestId | null, code: number, message: string): void {\n write(session, { jsonrpc: \"2.0\", id, error: { code, message } });\n}\n\nfunction replyToolResult(\n session: Session,\n id: RequestId,\n result: McpCallResult,\n): number | undefined {\n let content: unknown;\n try {\n content = toToolResult(result);\n } catch (error) {\n session.logger.error(\n \"A tool's value could not be written as JSON; it was answered with INTERNAL\",\n {\n category: CATEGORY,\n error: describeError(error),\n },\n );\n content = toToolResult(INTERNAL_FAILURE);\n }\n return reply(session, id, content);\n}\n\nasync function callTool(session: Session, id: RequestId, params: unknown): Promise<void> {\n if (!isRecord(params) || typeof params.name !== \"string\") {\n replyError(session, id, INVALID_PARAMS, \"tools/call needs params { name, arguments? }\");\n return;\n }\n const { name } = params;\n if (!session.registry.has(name)) {\n replyError(session, id, INVALID_PARAMS, `Unknown tool: ${name}`);\n return;\n }\n if (session.calls.has(id)) {\n replyError(session, id, INVALID_REQUEST, `Request ${JSON.stringify(id)} is already in flight`);\n return;\n }\n const controller = new AbortController();\n session.calls.set(id, controller);\n const release = (): void => {\n if (session.calls.get(id) === controller) {\n session.calls.delete(id);\n }\n };\n try {\n await session.registry.call(name, params.arguments, {\n request: session.request,\n signal: controller.signal,\n respond: (result) => {\n release();\n // A cancelled call gets no reply, nor does one whose session ended.\n return controller.signal.aborted ? undefined : replyToolResult(session, id, result);\n },\n });\n } finally {\n release();\n }\n}\n\nasync function onRequest(\n session: Session,\n id: RequestId,\n method: string,\n params: unknown,\n): Promise<void> {\n switch (method) {\n case \"initialize\":\n reply(session, id, {\n protocolVersion: MCP_PROTOCOL_VERSION,\n serverInfo: session.serverInfo,\n capabilities: { tools: {} },\n });\n return;\n case \"ping\":\n reply(session, id, {});\n return;\n case \"tools/list\":\n reply(session, id, { tools: session.registry.tools });\n return;\n case \"tools/call\":\n await callTool(session, id, params);\n return;\n default:\n replyError(session, id, METHOD_NOT_FOUND, `Method not found: ${method}`);\n }\n}\n\n/** `notifications/cancelled` stops a call in flight; every other notification needs nothing. */\nfunction onNotification(session: Session, method: string, params: unknown): void {\n if (method === \"notifications/cancelled\" && isRecord(params) && isRequestId(params.requestId)) {\n session.calls.get(params.requestId)?.abort();\n }\n}\n\nconst UNPARSABLE = Symbol(\"unparsable\");\n\nfunction parse(line: string): unknown {\n try {\n return JSON.parse(line) as unknown;\n } catch {\n return UNPARSABLE;\n }\n}\n\nasync function onLine(session: Session, line: string): Promise<void> {\n if (line.trim() === \"\") {\n return;\n }\n const message = parse(line);\n if (message === UNPARSABLE) {\n replyError(session, null, PARSE_ERROR, \"Parse error\");\n return;\n }\n if (!isRecord(message)) {\n replyError(session, null, INVALID_REQUEST, \"Invalid Request\");\n return;\n }\n const { id, method, params } = message;\n if (typeof method !== \"string\") {\n // A response to a request this server never sends: answering it could loop.\n if (!(\"result\" in message) && !(\"error\" in message)) {\n replyError(session, isRequestId(id) ? id : null, INVALID_REQUEST, \"Invalid Request\");\n }\n return;\n }\n if (id === undefined) {\n onNotification(session, method, params);\n return;\n }\n if (!isRequestId(id)) {\n replyError(session, null, INVALID_REQUEST, \"Invalid Request\");\n return;\n }\n await onRequest(session, id, method, params);\n}\n\n/** Handles one message, keeping track of it until it is done. */\nfunction track(session: Session, work: Promise<void>): void {\n const handled = work.catch((error: unknown) => {\n session.logger.error(\"The MCP stdio server failed to handle a message\", {\n category: CATEGORY,\n error: describeError(error),\n });\n });\n session.pending.add(handled);\n void handled.then(() => session.pending.delete(handled));\n}\n\nfunction openSession(options: McpStdioServerOptions): Session {\n if (\n typeof options !== \"object\" ||\n options === null ||\n typeof options.registry?.call !== \"function\"\n ) {\n throw new TypeError(\"createMcpStdioServer: registry must come from createMcpRegistry\");\n }\n if (typeof options.name !== \"string\" || typeof options.version !== \"string\") {\n throw new TypeError(\"createMcpStdioServer: name and version must be strings, for serverInfo\");\n }\n return {\n registry: options.registry,\n serverInfo: Object.freeze({ name: options.name, version: options.version }),\n request: Object.freeze({ transport: \"stdio\", sessionId: randomUUID() }),\n output: options.output ?? process.stdout,\n logger: options.logger ?? stderrLogger,\n calls: new Map(),\n pending: new Set(),\n writable: true,\n };\n}\n\n/**\n * Serves `registry`'s tools over MCP's stdio transport: JSON-RPC messages,\n * one per line, read from stdin and answered on stdout. The server is one\n * session: its calls carry one session id and share one concurrency lane,\n * and the registry's `principal` and `context` hooks see the same\n * `{ transport: \"stdio\", sessionId }` request on every call. It never exits\n * the process.\n *\n * @example\n * // mcp-server.ts, started through bootstrapMcpServer\n * const registry = createMcpRegistry({ services, dispatcher, principal: () => agentFromEnv() });\n * const server = createMcpStdioServer({ registry, name: \"my-app\", version: \"1.0.0\" });\n * await server.closed;\n * await prisma.$disconnect();\n */\nexport function createMcpStdioServer(options: McpStdioServerOptions): McpStdioServer {\n const session = openSession(options);\n const lines = createInterface({\n input: options.input ?? process.stdin,\n crlfDelay: Infinity,\n terminal: false,\n });\n // Ending stdin lets the calls in flight answer; `close()` and a broken stream cancel them.\n let cancel = false;\n const stop = (): void => {\n cancel = true;\n lines.close();\n };\n const fail = (error: Error): void => {\n session.logger.warn(\"The MCP stdio stream failed; the session ends\", {\n category: CATEGORY,\n error: describeError(error),\n });\n stop();\n };\n const onOutputError = (error: Error): void => {\n session.writable = false;\n fail(error);\n };\n session.output.on(\"error\", onOutputError);\n lines.on(\"error\", fail);\n lines.on(\"line\", (line) => track(session, onLine(session, line)));\n const closed = new Promise<void>((resolve) => {\n lines.once(\"close\", () => {\n for (const controller of cancel ? session.calls.values() : []) {\n controller.abort();\n }\n void Promise.allSettled([...session.pending]).then(() => {\n session.output.off(\"error\", onOutputError);\n resolve();\n });\n });\n });\n return Object.freeze({\n sessionId: session.request.sessionId,\n closed,\n close: () => {\n stop();\n return closed;\n },\n });\n}\n","// Writing to stderr. An MCP stdio server owns stdout for the protocol, so its\n// own log lines, and everything `bootstrapMcpServer` takes from the console,\n// go to stderr instead.\n\nimport { format, inspect } from \"node:util\";\nimport type { Logger } from \"../../contract/logger\";\n\n/** Writes one line to stderr, formatting the arguments as `console.log` would. */\nexport function writeStderr(...args: unknown[]): void {\n process.stderr.write(`${format(...args)}\\n`);\n}\n\nfunction entry(level: string): (message: string, meta?: Record<string, unknown>) => void {\n return (message, meta) => {\n const details = meta === undefined ? \"\" : ` ${inspect(meta, { breakLength: Infinity })}`;\n process.stderr.write(`[${level}] ${message}${details}\\n`);\n };\n}\n\n/** A logger that writes each entry to stderr as one line. */\nexport const stderrLogger: Logger = {\n debug: entry(\"DEBUG\"),\n info: entry(\"INFO\"),\n warn: entry(\"WARN\"),\n error: entry(\"ERROR\"),\n child: () => stderrLogger,\n};\n","// `bootstrapMcpServer`: loads the module that starts an MCP stdio server\n// after sending console output to stderr, so nothing but the protocol\n// reaches stdout, not even what that module's imports log while loading.\n// Ported from 4.1 (4.1 `src/server/mcp/McpBootstrap.ts:12`) with two\n// changes: a relative path is resolved against the working directory (4.1\n// handed it to `import()`, which resolves it against the package's own file,\n// so a relative path never found the app's module), and a module that fails\n// to load sets the exit code instead of calling `process.exit`.\n\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { writeStderr } from \"./stderr\";\n\nfunction specifierOf(serverModule: string | URL): string {\n if (serverModule instanceof URL) {\n return serverModule.href;\n }\n return serverModule.startsWith(\"file:\")\n ? serverModule\n : pathToFileURL(resolve(serverModule)).href;\n}\n\n/**\n * Sends `console.log`, `info`, `warn` and `debug` to stderr, sets\n * `MCP_MODE=true` (and `LOG_LEVEL=warn` unless it is set), then imports\n * `serverModule`, the module that creates the stdio server. A path is\n * resolved against the working directory; pass a URL to resolve it against\n * the calling module. Resolves once the module has loaded. When it fails to\n * load, the error goes to stderr and the process exit code becomes 1.\n *\n * @example\n * // mcp.ts: the MCP client runs `node dist/mcp.js`\n * import { bootstrapMcpServer } from \"@fitzzero/quickdraw-core/server/mcp\";\n * await bootstrapMcpServer(new URL(\"./mcp-server.js\", import.meta.url));\n */\nexport async function bootstrapMcpServer(serverModule: string | URL): Promise<void> {\n process.env.MCP_MODE = \"true\";\n process.env.LOG_LEVEL ??= \"warn\";\n // The console methods that write to stdout; `console.error` writes to stderr already.\n Object.assign(console, {\n log: writeStderr,\n info: writeStderr,\n warn: writeStderr,\n debug: writeStderr,\n });\n try {\n await import(specifierOf(serverModule));\n } catch (error) {\n writeStderr(\"Bootstrap error:\", error);\n process.exitCode = 1;\n }\n}\n","// What a request to the MCP HTTP routes stands for, and whether the routes\n// take it. `requestOf` makes each request a session of its own: a random\n// session id, which hooks see, and its bearer token. `requestGate` refuses a\n// request from a web page whose `Origin` `allowedOrigins` does not list\n// (none by default), and, with `allowedHosts`, one for a `Host` it does not\n// list (the 5.1 audit's MCP-3): a page an agent's user opens could otherwise\n// call the routes from their browser, and a DNS-rebinding page could reach a\n// server listening on their machine. A request without an `Origin` is no\n// page's: an MCP client sends none. An `allowedHosts` entry is compared as a\n// host: in any case, an IPv6 address with or without brackets, a name in\n// Unicode or punycode, and a port when it writes one.\n\nimport { randomUUID } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport { originAllowlist, type AllowedOrigin } from \"../auth/routes/origins\";\nimport type { McpHttpRequest } from \"./types\";\n\nexport type { AllowedOrigin };\n\n/** The session an `invoke` request stands for, with its bearer token. */\nexport function requestOf(req: IncomingMessage): McpHttpRequest {\n const header = req.headers.authorization;\n const token = typeof header === \"string\" && header.startsWith(\"Bearer \") ? header.slice(7) : \"\";\n return {\n transport: \"http\",\n sessionId: randomUUID(),\n token: token.trim() === \"\" ? null : token.trim(),\n headers: req.headers,\n req,\n };\n}\n\n/** Why the routes refuse a request, before either route runs. */\nexport interface RequestGate {\n /** Why the routes refuse `req`, or `undefined` when they take it. */\n refusal(req: IncomingMessage): string | undefined;\n}\n\n/**\n * A host as the gate compares it: its name (lower case, an IPv6 address in\n * brackets, a name in punycode), and its port when one is written.\n */\ninterface Host {\n readonly hostname: string;\n readonly port: string | undefined;\n}\n\n/** `value`, a host as a `Host` header or an `allowedHosts` entry writes it, or `undefined` when it is not one. */\nfunction hostOf(value: string): Host | undefined {\n if (/\\s/u.test(value)) {\n return undefined;\n }\n // A bare IPv6 address (two colons or more, no brackets) is a host without a port.\n const host = !value.startsWith(\"[\") && value.split(\":\").length > 2 ? `[${value}]` : value;\n let url: URL;\n try {\n url = new URL(`http://${host}`);\n } catch {\n return undefined;\n }\n const extra = url.username + url.password + url.search + url.hash;\n if (url.hostname === \"\" || extra !== \"\" || url.pathname !== \"/\") {\n return undefined;\n }\n // The URL parser drops port 80, its scheme's default: whether a port is written is read from the text.\n const written = !host.endsWith(\"]\") && /:\\d+$/u.test(host);\n return { hostname: url.hostname, port: written ? url.port || \"80\" : undefined };\n}\n\nfunction checkHosts(hosts: unknown): readonly Host[] | undefined {\n if (hosts === undefined) {\n return undefined;\n }\n const parsed = Array.isArray(hosts)\n ? hosts.map((host: unknown) => (typeof host === \"string\" ? hostOf(host) : undefined))\n : [];\n if (parsed.length === 0 || parsed.includes(undefined)) {\n throw new TypeError(\n 'createMcpHttpRouter: allowedHosts must list host names, such as \"localhost\" or \"mcp.example.com:8443\"',\n );\n }\n return Object.freeze(parsed as Host[]);\n}\n\n/**\n * True when the `Host` header names one of `hosts`. An entry without a port\n * matches any port; a header without one is for its scheme's default port,\n * 80 or 443.\n */\nfunction hostAllowed(hosts: readonly Host[], header: string | undefined): boolean {\n const host = header === undefined ? undefined : hostOf(header);\n if (host === undefined) {\n return false;\n }\n const portMatches = (port: string): boolean =>\n host.port === undefined ? port === \"80\" || port === \"443\" : port === host.port;\n return hosts.some(\n (entry) =>\n entry.hostname === host.hostname && (entry.port === undefined || portMatches(entry.port)),\n );\n}\n\n/** The gate of the routes made with `allowedOrigins` and `allowedHosts`, both checked. */\nexport function requestGate(allowedOrigins: unknown, allowedHosts: unknown): RequestGate {\n const origins = originAllowlist(\n (allowedOrigins ?? []) as readonly AllowedOrigin[],\n \"createMcpHttpRouter\",\n true,\n );\n const hosts = checkHosts(allowedHosts);\n return Object.freeze({\n refusal(req: IncomingMessage): string | undefined {\n const { origin, host } = req.headers;\n if (origin !== undefined && origins.allowed(origin) === null) {\n return \"The MCP routes refuse requests from web pages unless allowedOrigins lists their origin\";\n }\n if (hosts !== undefined && !hostAllowed(hosts, host)) {\n return \"The MCP routes do not answer for this host\";\n }\n return undefined;\n },\n });\n}\n","// The MCP HTTP routes (RFC 0003 section 10), ported from 4.1's\n// `createMcpRoutes` (4.1 `src/server/mcp/McpHttpRoutes.ts:12`) onto the\n// registry, keeping its wire format:\n//\n// GET {path}/tools -> { tools }\n// POST {path}/invoke { service, method, payload } -> { success: true, data }\n//\n// `invoke` also takes `{ name, arguments }`, which reaches every tool, the\n// app's own included. Like the HTTP transport, the routes are a plain Node\n// request handler rather than an `express.Router`, so they mount with\n// `app.use(router)` on Express 4 or 5 and also serve a bare Node server.\n//\n// What changed from 4.1: the registry's `principal` hook decides who a bearer\n// token stands for, and a request without one is anonymous (only `\"public\"`\n// methods and custom tools pass) where 4.1 refused it; a failure answers\n// with its error code's HTTP status and `{ success: false, error, code,\n// data? }` where 4.1 answered 500 and `{ error }`; `invoke` needs\n// `Content-Type: application/json`, as every HTTP transport call does; and a\n// client that goes away cancels its call. Each request is a session of its\n// own, and its queries share the lane of its caller: its bearer token, its\n// user without a token, or its address when anonymous (`lanes.ts`). A\n// request from a web page is refused unless `allowedOrigins` lists its\n// origin, and with `allowedHosts` a request for another `Host`\n// (`httpRequest.ts`).\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\nimport {\n httpStatus,\n INTERNAL_MESSAGE,\n QuickdrawError,\n toWire,\n type ErrorCode,\n} from \"../../protocol/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport { unreadable } from \"../transports/ack\";\nimport { isJsonRequest, readJsonInput, type HttpRequest } from \"../transports/body\";\nimport type { HttpRouter } from \"../transports/http\";\nimport { requestGate, requestOf, type AllowedOrigin, type RequestGate } from \"./httpRequest\";\nimport type { McpRegistry } from \"./registry\";\nimport type { McpCallOptions, McpCallResult } from \"./types\";\n\n/** Options of {@link createMcpHttpRouter}. */\nexport interface McpHttpRouterOptions {\n /** The tools to serve. */\n readonly registry: McpRegistry;\n /** The prefix of the routes: `GET {path}/tools` and `POST {path}/invoke`. Default `\"/mcp\"`, as in 4.1. */\n readonly path?: string;\n /**\n * The largest request body read, in bytes. Default 1 MiB. A body the app's\n * own JSON parser already read (`express.json()`) is used as it is.\n */\n readonly maxBodyBytes?: number;\n /** Default: the console. */\n readonly logger?: Logger;\n /**\n * The web pages that may call the routes, by origin: exact origins\n * (`\"https://app.example.com\"`) or patterns anchored with `^` and `$`, as\n * `socketAuth` takes them. A request whose `Origin` is not listed gets 403;\n * a request without one (an MCP client, a script) is not a page's and\n * passes. Default: none, so no page may call them.\n */\n readonly allowedOrigins?: readonly AllowedOrigin[];\n /**\n * The `Host` names the routes answer for (`\"localhost\"`, `\"127.0.0.1\"`,\n * `\"mcp.example.com:8443\"`; an entry without a port matches any port): a\n * request for another gets 403. Set it for a server on a developer's\n * machine or a LAN, where a page could reach it through DNS rebinding.\n * Default: any host.\n */\n readonly allowedHosts?: readonly string[];\n}\n\n/** What `invoke` answers: 4.1's `{ success, data }`, or a failure's message, code and data. */\nexport type McpHttpReply =\n | { readonly success: true; readonly data: unknown }\n | {\n readonly success: false;\n readonly error: string;\n readonly code: ErrorCode;\n readonly data?: unknown;\n };\n\ninterface Settings {\n readonly registry: McpRegistry;\n readonly prefix: string;\n readonly maxBodyBytes: number;\n readonly logger: Logger;\n readonly gate: RequestGate;\n}\n\n/** What an `invoke` body names: any tool by name, or a method's tool by service and method. */\ntype Target =\n | { readonly kind: \"tool\"; readonly name: string; readonly args: unknown }\n | {\n readonly kind: \"method\";\n readonly service: string;\n readonly method: string;\n readonly input: unknown;\n };\n\nconst DEFAULT_MAX_BODY_BYTES = 1_048_576;\nconst CATEGORY = \"quickdraw.mcp\";\nconst NOT_JSON = \"Send the call as a JSON body with Content-Type: application/json\";\nconst NO_TARGET =\n \"Send { name, arguments } to call a tool, or { service, method, payload } to call a method's tool\";\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction failure(error: QuickdrawError): McpCallResult {\n return { ok: false, error };\n}\n\nfunction replyOf(result: McpCallResult): [number, McpHttpReply] {\n if (result.ok) {\n return [200, { success: true, data: result.data }];\n }\n const { code, message, data } = toWire(result.error);\n const reply = { success: false as const, error: message, code };\n return [httpStatus(code), data === undefined ? reply : { ...reply, data }];\n}\n\n/** Writes a JSON body, unless the response already ended; returns its size in bytes. */\nfunction send(res: ServerResponse, status: number, body: string): number | undefined {\n if (res.headersSent || res.writableEnded || res.destroyed) {\n return undefined;\n }\n const bytes = Buffer.byteLength(body);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n res.setHeader(\"content-length\", bytes);\n // As on `/qd`: a caller's data is never cached, nor read as anything but JSON (TRANSPORT-3).\n res.setHeader(\"cache-control\", \"no-store\");\n res.setHeader(\"x-content-type-options\", \"nosniff\");\n res.end(body);\n return bytes;\n}\n\nfunction sendResult(\n settings: Settings,\n res: ServerResponse,\n result: McpCallResult,\n): number | undefined {\n const [status, reply] = replyOf(result);\n let body: string;\n try {\n body = JSON.stringify(reply);\n } catch (error) {\n settings.logger.error(\n \"An MCP call's reply could not be encoded; it was answered with INTERNAL\",\n {\n category: CATEGORY,\n error: describeError(error),\n },\n );\n const [internal, fallback] = replyOf(failure(new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE)));\n return send(res, internal, JSON.stringify(fallback));\n }\n return send(res, status, body);\n}\n\nfunction routeOf(req: IncomingMessage, prefix: string): \"tools\" | \"invoke\" | undefined {\n const path = (req.url ?? \"\").split(\"?\", 1)[0] ?? \"\";\n if (req.method === \"GET\" && path === `${prefix}/tools`) {\n return \"tools\";\n }\n return req.method === \"POST\" && path === `${prefix}/invoke` ? \"invoke\" : undefined;\n}\n\nfunction targetOf(body: unknown): Target | undefined {\n if (!isRecord(body)) {\n return undefined;\n }\n if (typeof body.name === \"string\") {\n return { kind: \"tool\", name: body.name, args: body.arguments };\n }\n if (typeof body.service === \"string\" && typeof body.method === \"string\") {\n return { kind: \"method\", service: body.service, method: body.method, input: body.payload };\n }\n return undefined;\n}\n\nasync function invoke(settings: Settings, req: HttpRequest, res: ServerResponse): Promise<void> {\n const controller = new AbortController();\n // `req` closes once its body was read; `res` closes when the client leaves.\n res.once(\"close\", () => {\n if (!res.writableFinished) {\n controller.abort();\n }\n });\n if (!isJsonRequest(req)) {\n sendResult(settings, res, failure(unreadable(NOT_JSON)));\n return;\n }\n let body: unknown;\n try {\n body = await readJsonInput(req, settings.maxBodyBytes);\n } catch (error) {\n const reason =\n error instanceof QuickdrawError ? error : unreadable(\"The request body could not be read\");\n sendResult(settings, res, failure(reason));\n return;\n }\n const target = targetOf(body);\n if (target === undefined) {\n sendResult(settings, res, failure(unreadable(NO_TARGET)));\n return;\n }\n const options: McpCallOptions = {\n request: requestOf(req),\n signal: controller.signal,\n respond: (result) => sendResult(settings, res, result),\n };\n await (target.kind === \"tool\"\n ? settings.registry.call(target.name, target.args, options)\n : settings.registry.callMethod(target.service, target.method, target.input, options));\n}\n\n/** `\"/mcp/\"` and `\"mcp\"` become `\"/mcp\"`; `\"/\"` becomes `\"\"`, serving `/tools` and `/invoke`. */\nfunction normalizePath(path: string): string {\n const trimmed = path.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed === \"\" ? \"\" : `/${trimmed}`;\n}\n\nfunction resolveSettings(options: McpHttpRouterOptions): Settings {\n if (typeof options !== \"object\" || options === null || !isRecord(options.registry)) {\n throw new TypeError(\"createMcpHttpRouter: registry must come from createMcpRegistry\");\n }\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n if (!Number.isSafeInteger(maxBodyBytes) || maxBodyBytes < 1) {\n throw new TypeError(\n \"createMcpHttpRouter: maxBodyBytes must be a whole number of bytes, 1 or more\",\n );\n }\n return {\n registry: options.registry,\n prefix: normalizePath(options.path ?? \"/mcp\"),\n maxBodyBytes,\n logger: options.logger ?? consoleLogger,\n gate: requestGate(options.allowedOrigins, options.allowedHosts),\n };\n}\n\n/**\n * Serves `registry`'s tools over HTTP: `GET /mcp/tools` lists them (the\n * same list for every caller: it is not filtered by the principal), and\n * `POST /mcp/invoke` calls one with `{ name, arguments }`, or a method's\n * tool with 4.1's `{ service, method, payload }`, as the bearer token's\n * principal. Mount it with `app.use(router)` on Express 4 or 5, or pass it to\n * `http.createServer`. A request it does not serve goes to `next`, or gets a\n * 404 when there is no `next`.\n *\n * @example\n * app.use(createMcpHttpRouter({ registry }));\n */\nexport function createMcpHttpRouter(options: McpHttpRouterOptions): HttpRouter {\n const settings = resolveSettings(options);\n return (req, res, next) => {\n const route = routeOf(req, settings.prefix);\n if (route === undefined) {\n if (next === undefined) {\n sendResult(settings, res, failure(new QuickdrawError(\"NOT_FOUND\", \"Not found\")));\n } else {\n next();\n }\n return;\n }\n const refusal = settings.gate.refusal(req);\n if (refusal !== undefined) {\n settings.logger.debug(\"An MCP HTTP request was refused\", {\n category: CATEGORY,\n origin: req.headers.origin,\n host: req.headers.host,\n });\n sendResult(settings, res, failure(new QuickdrawError(\"FORBIDDEN\", refusal)));\n return;\n }\n if (route === \"tools\") {\n send(res, 200, JSON.stringify({ tools: settings.registry.tools }));\n return;\n }\n invoke(settings, req, res).catch((error: unknown) => {\n settings.logger.error(\"The MCP HTTP routes failed to serve a call\", {\n category: CATEGORY,\n error: describeError(error),\n });\n sendResult(settings, res, failure(new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE)));\n });\n };\n}\n"],"mappings":"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","names":["entry","parse","isRecord","isRecord","entry","CATEGORY","isRecord","callTool","openSession","resolve","randomUUID","randomUUID","entry","CATEGORY","isRecord","failure","reply"]}
1
+ {"version":3,"sources":["../../../src/server/mcp/tools.ts","../../../src/server/mcp/lanes.ts","../../../src/server/mcp/session.ts","../../../src/server/mcp/custom.ts","../../../src/server/mcp/registry.ts","../../../src/server/mcp/result.ts","../../../src/server/mcp/stdio.ts","../../../src/server/mcp/stderr.ts","../../../src/server/mcp/bootstrap.ts","../../../src/server/mcp/httpRequest.ts","../../../src/server/mcp/http.ts"],"sourcesContent":["// Tools from contracts (RFC 0003 section 10): one tool per method, made when\n// the registry is built, from what the contract already holds: the input\n// schema, the kind and the `describe` text. 4.1 wrote tool metadata ahead of\n// time by parsing service source files with regular expressions\n// (4.1 `src/server/mcp/generateToolMetadata.ts:255`); nothing is generated\n// ahead of time here.\n//\n// A tool's `inputSchema` is the method input's Standard JSON Schema (Zod 4.2\n// or later), drafted as JSON Schema draft-07, the dialect MCP clients of the\n// 2024-11-05 protocol read. MCP tool arguments are always an object, so:\n//\n// - an object input is the arguments themselves;\n// - an input with no JSON Schema form that accepts `undefined`\n// (`z.undefined()`, `z.void()`) is a tool without arguments;\n// - any other input (a string, a union) is the `input` argument.\n//\n// An input whose JSON Schema is a `$ref` to an object (a Zod schema with\n// `.meta({ id })`) counts as that object: its definition is inlined at the\n// root. A wrapped input keeps its `definitions` at the root of the tool's\n// schema, where its `$ref`s resolve for the client.\n//\n// A registry's `bind` names arguments it fills from the principal: they are\n// left out of the `inputSchema` of each object input that has them, and may\n// not appear anywhere else in an input, behind a `$ref` or in any `anyOf`,\n// `oneOf` or `allOf` branch (`inputKeys`), where they could not be filled.\n\nimport type { MethodKind } from \"../../contract/methods\";\nimport { defaultToolName } from \"../../contract/toolName\";\nimport {\n hasJsonSchema,\n type StandardSchemaV1,\n type StandardSchemaWithJSON,\n} from \"../../contract/standardSchema\";\nimport { inputKeys, pointerToken, referenced } from \"../emit/projection\";\nimport type { AnyService } from \"../service\";\nimport type { DescribeToolsOptions, McpInputSchema, McpTool } from \"./types\";\n\n/** How a tool's arguments become its input. */\nexport type ArgumentsMode = \"object\" | \"wrapped\" | \"none\";\n\n/** A tool's argument schema, and how its arguments become the input. */\nexport interface ToolInput {\n readonly schema: McpInputSchema;\n readonly mode: ArgumentsMode;\n}\n\n/** A method's tool, with the method it calls. */\nexport interface MethodTool extends ToolInput {\n readonly tool: McpTool;\n readonly service: string;\n readonly method: string;\n /** The arguments the registry's `bind` fills, which `tool.inputSchema` leaves out. */\n readonly bound: readonly string[];\n}\n\ntype Fail = (message: string) => never;\n\nconst JSON_SCHEMA_TARGET = \"draft-07\";\n\nconst NO_ARGUMENTS: McpInputSchema = Object.freeze({\n type: \"object\",\n properties: Object.freeze({}),\n});\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** True when the schema accepts `undefined` without awaiting anything. */\nfunction acceptsUndefined(schema: StandardSchemaV1): boolean {\n try {\n const result: unknown = schema[\"~standard\"].validate(undefined);\n return isRecord(result) && typeof result.then !== \"function\" && result.issues === undefined;\n } catch {\n return false;\n }\n}\n\n/** The JSON Schema of a schema's input, or why the schema could not write one. */\nfunction draftJsonSchema(schema: StandardSchemaWithJSON): Record<string, unknown> | Error {\n try {\n const json: unknown = schema[\"~standard\"].jsonSchema.input({ target: JSON_SCHEMA_TARGET });\n return isRecord(json) ? json : new Error(\"the schema did not return an object\");\n } catch (error) {\n return error instanceof Error ? error : new Error(String(error));\n }\n}\n\n/**\n * The argument schema of a tool whose input is `schema`, and how its\n * arguments become that input. Fails when the schema cannot describe itself\n * as JSON Schema, naming `label` (what the tool calls) and the fix; `instead`\n * is the other way out. A method can be left out with `exclude`.\n */\nexport function toolInputOf(\n label: string,\n schema: StandardSchemaV1,\n fail: Fail,\n instead = `leave ${label} out with exclude`,\n): ToolInput {\n if (!hasJsonSchema(schema)) {\n fail(\n `the input schema of ${label} cannot describe itself as JSON Schema, which an MCP tool needs: use Zod 4.2 or later for that schema, or ${instead}`,\n );\n }\n const json = draftJsonSchema(schema);\n if (json instanceof Error) {\n if (acceptsUndefined(schema)) {\n return { schema: NO_ARGUMENTS, mode: \"none\" };\n }\n fail(\n `the input schema of ${label} cannot be written as JSON Schema (${json.message}): change that schema, or ${instead}`,\n );\n }\n const described = referenced(json, json);\n if (described?.type === \"object\") {\n return { schema: inlined(json, described) as McpInputSchema, mode: \"object\" };\n }\n const { $schema: dialect, definitions, $defs, ...input } = json;\n return {\n schema: {\n ...(dialect === undefined ? {} : { $schema: dialect }),\n type: \"object\",\n properties: { input: rerooted(input) },\n ...(acceptsUndefined(schema) ? {} : { required: [\"input\"] }),\n ...(definitions === undefined ? {} : { definitions: rerooted(definitions) }),\n ...($defs === undefined ? {} : { $defs: rerooted($defs) }),\n },\n mode: \"wrapped\",\n };\n}\n\n/** Where a wrapped input sits in its tool's schema. */\nconst WRAPPED_INPUT = \"#/properties/input\";\n\n/**\n * `value` with every `$ref` into the input's root, but its definitions,\n * pointed where the wrapped input sits: a recursive input refers to itself\n * as `#`, which is the tool's schema once the input is wrapped. The\n * definitions stay at the root, so their references hold.\n */\nfunction rerooted(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(rerooted);\n }\n if (!isRecord(value)) {\n return value;\n }\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => {\n const intoRoot =\n key === \"$ref\" &&\n typeof item === \"string\" &&\n (item === \"#\" || (item.startsWith(\"#/\") && !/^#\\/(?:definitions|\\$defs)\\//u.test(item)));\n return [key, intoRoot ? `${WRAPPED_INPUT}${item.slice(1)}` : rerooted(item)];\n }),\n );\n}\n\n/** True when `value` holds a `$ref` to `ref` anywhere inside it. */\nfunction refersTo(value: unknown, ref: string): boolean {\n if (Array.isArray(value)) {\n return value.some((item) => refersTo(item, ref));\n }\n if (!isRecord(value)) {\n return false;\n }\n return value.$ref === ref || Object.values(value).some((item) => refersTo(item, ref));\n}\n\n/**\n * The object schema a root `$ref` names, inlined at the root (Zod writes an\n * id'd schema as `{ $schema, $ref: \"#/definitions/<id>\", definitions }`):\n * the root's dialect and definitions beside the target's keywords, without\n * the target's own definition unless something still refers to it.\n */\nfunction inlined(\n json: Readonly<Record<string, unknown>>,\n target: Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> {\n if (target === json) {\n return json;\n }\n const ref = String(json.$ref);\n const { $schema: dialect } = json;\n const schema: Record<string, unknown> = {\n ...(dialect === undefined ? {} : { $schema: dialect }),\n ...target,\n };\n for (const keyword of [\"definitions\", \"$defs\"]) {\n const defs = json[keyword];\n if (!isRecord(defs)) {\n continue;\n }\n const others = Object.fromEntries(\n Object.entries(defs).filter(([name]) => `#/${keyword}/${pointerToken(name)}` !== ref),\n );\n // The target's own entry stays only for a schema that still refers to it (a recursive one).\n const kept = refersTo({ ...schema, [keyword]: others }, ref) ? defs : others;\n if (Object.keys(kept).length > 0) {\n schema[keyword] = kept;\n }\n }\n return schema;\n}\n\n/** The input a call passes to a tool's handler or method, from the tool's arguments. */\nexport function inputOf(mode: ArgumentsMode, args: unknown): unknown {\n if (mode === \"object\") {\n return args ?? {};\n }\n return mode === \"wrapped\" && isRecord(args) ? args.input : undefined;\n}\n\n/** Whether a method is selected by `include` and `exclude`, after checking every reference names one. */\nfunction selector(\n services: readonly AnyService[],\n options: DescribeToolsOptions,\n fail: Fail,\n): (service: string, method: string) => boolean {\n const known = new Set<string>();\n for (const service of services) {\n known.add(service.name);\n for (const method of Object.keys(service.contract.methods)) {\n known.add(`${service.name}.${method}`);\n }\n }\n const refs = (key: \"include\" | \"exclude\"): ReadonlySet<string> | undefined => {\n const list: unknown = options[key];\n if (list === undefined) {\n return undefined;\n }\n if (!Array.isArray(list) || !list.every((ref) => typeof ref === \"string\")) {\n fail(`${key} must be a list of \"service\" and \"service.method\" names`);\n }\n const unknownRef = list.find((ref) => !known.has(ref));\n if (unknownRef !== undefined) {\n fail(`${key} names \"${unknownRef}\", which is not a service or method being served`);\n }\n return new Set(list);\n };\n const include = refs(\"include\");\n const exclude = refs(\"exclude\");\n const names = (set: ReadonlySet<string>, service: string, method: string): boolean =>\n set.has(service) || set.has(`${service}.${method}`);\n return (service, method) =>\n (include === undefined || names(include, service, method)) &&\n (exclude === undefined || !names(exclude, service, method));\n}\n\n/** The function that names a method's tool: the `name` option, checked, or `{service}_{method}`. */\nfunction toolNamer(\n options: DescribeToolsOptions,\n fail: Fail,\n): (service: string, method: string) => string {\n const { name } = options;\n if (name !== undefined && typeof name !== \"function\") {\n fail(\"name must be a function of (service, method)\");\n }\n return (service, method) => {\n const named: unknown =\n name === undefined ? defaultToolName(service, method) : name(service, method);\n if (typeof named !== \"string\" || named === \"\") {\n const shown = typeof named === \"string\" ? `\"\"` : String(named);\n fail(`name returned ${shown} for ${service}.${method}; a tool name is a non-empty string`);\n }\n return named;\n };\n}\n\nfunction describeMethod(service: string, method: string, kind: MethodKind, text: unknown): string {\n return typeof text === \"string\" && text !== \"\" ? text : `${service}.${method} (${kind})`;\n}\n\nfunction propertiesOf(schema: unknown): string[] {\n return isRecord(schema) && isRecord(schema.properties) ? Object.keys(schema.properties) : [];\n}\n\n/**\n * The arguments of `bind` that are properties of the object input of\n * `label`. Fails when one of them is a key the input `schema` may have\n * anywhere else (`inputKeys`: behind a `$ref`, in an `anyOf`, `oneOf` or\n * `allOf` branch, or the input is not an object), where it cannot be\n * filled. An input without arguments has none.\n */\nfunction boundArguments(\n label: string,\n input: ToolInput,\n schema: StandardSchemaV1,\n bind: readonly string[],\n fail: Fail,\n): string[] {\n if (bind.length === 0) {\n return [];\n }\n const bindable = input.mode === \"object\" ? propertiesOf(input.schema) : [];\n const keys = inputKeys(schema) ?? [];\n const misplaced = bind.find((key) => keys.includes(key) && !bindable.includes(key));\n if (misplaced !== undefined) {\n fail(\n `bind.${misplaced} names a property of the input of ${label}, which is not an object: bind fills properties of object inputs only (an object schema, or one with .meta({ id }); not a union, an intersection, or a schema made from an object, as .optional() or .refine() make); leave ${label} out with exclude, or make its input an object`,\n );\n }\n return bind.filter((key) => bindable.includes(key));\n}\n\n/** An object input's schema without the bound arguments, as the tool lists it. */\nfunction withoutArguments(schema: McpInputSchema, bound: readonly string[]): McpInputSchema {\n const kept = (key: string) => !bound.includes(key);\n const { properties = {}, required, ...rest } = schema;\n const stillRequired = required?.filter(kept) ?? [];\n return {\n ...rest,\n properties: Object.fromEntries(Object.entries(properties).filter(([key]) => kept(key))),\n ...(stillRequired.length === 0 ? {} : { required: stillRequired }),\n };\n}\n\n/**\n * The method tools of `services`, in service order and then contract order,\n * with what each calls. Fails on a reference, name or schema that cannot\n * make a tool; `fail` prefixes the message with the caller's name. `bind`\n * names the arguments a registry fills from the principal.\n */\nexport function planMethodTools(\n services: readonly AnyService[],\n options: DescribeToolsOptions,\n fail: Fail,\n bind: readonly string[] = [],\n): MethodTool[] {\n const given: unknown = services;\n if (!Array.isArray(given)) {\n fail(\"services must be an array of services from qd.defineService\");\n }\n const selected = selector(services, options, fail);\n const toolName = toolNamer(options, fail);\n const planned: MethodTool[] = [];\n for (const service of services) {\n for (const [method, def] of Object.entries(service.contract.methods)) {\n if (!selected(service.name, method)) {\n continue;\n }\n const label = `${service.name}.${method}`;\n const input = toolInputOf(label, def.input, fail);\n const bound = boundArguments(label, input, def.input, bind, fail);\n const tool: McpTool = {\n name: toolName(service.name, method),\n description: describeMethod(service.name, method, def.kind, def.describe),\n inputSchema: bound.length === 0 ? input.schema : withoutArguments(input.schema, bound),\n ...(def.kind === \"query\" ? { annotations: { readOnlyHint: true } } : {}),\n };\n planned.push({ ...input, tool: Object.freeze(tool), service: service.name, method, bound });\n }\n }\n return planned;\n}\n\n/** Fails when two tools share a name. `owners` names what each tool comes from, for the message. */\nexport function checkUniqueNames(\n tools: readonly { readonly tool: McpTool; readonly owner: string }[],\n fail: Fail,\n): void {\n const seen = new Map<string, string>();\n for (const { tool, owner } of tools) {\n const first = seen.get(tool.name);\n if (first !== undefined) {\n fail(`two tools are named \"${tool.name}\": ${first} and ${owner}`);\n }\n seen.set(tool.name, owner);\n }\n}\n\n/**\n * The MCP tools of `services`: one per contract method, named\n * `{service}_{method}` unless `name` says otherwise, described by the\n * method's `describe` text, with the input schema's JSON Schema as\n * `inputSchema` and `readOnlyHint` on every query. Throws when a method's\n * input schema cannot describe itself as JSON Schema (use Zod 4.2 or later),\n * when `include` or `exclude` names something that is not served, and when\n * two tools would share a name.\n *\n * @example\n * describeTools([taskService], { exclude: [\"taskService.purge\"] });\n */\nexport function describeTools<const S extends readonly AnyService[]>(\n services: S,\n options: DescribeToolsOptions<S> = {},\n): McpTool[] {\n const fail: Fail = (message) => {\n throw new TypeError(`describeTools: ${message}`);\n };\n const planned = planMethodTools(services, options as DescribeToolsOptions, fail);\n checkUniqueNames(\n planned.map((entry) => ({ tool: entry.tool, owner: `${entry.service}.${entry.method}` })),\n fail,\n );\n return planned.map((entry) => entry.tool);\n}\n","// The concurrency lane of an MCP call: the connection id its queries count\n// against (RFC 0003 section 9, step 2), as a socket's queries count against\n// their socket. A stdio session is one lane. Each HTTP request is a session\n// of its own, so its lane is its caller's (the 5.1 audit's MCP-4):\n//\n// - with a bearer token, the token's, by a hash (never the token itself). A\n// `principal` hook that authenticates by anything else (a cookie, an API\n// key header) must refuse a request whose bearer token it does not\n// verify: otherwise a caller makes a lane per made-up token;\n// - for a principal without a token, its user's;\n// - when anonymous, its address's: Express's `req.ip`, which follows the\n// app's `trust proxy` (behind a proxy without it, every anonymous caller\n// shares the proxy's lane), else the socket's. An IPv4-mapped IPv6\n// address counts as its IPv4 address, and an IPv6 address by its /56,\n// since one host commonly holds a /64 or more (as express-rate-limit\n// keys them).\n\nimport { createHash } from \"node:crypto\";\nimport { isIPv6 } from \"node:net\";\nimport type { Principal } from \"../types\";\nimport type { McpRequest } from \"./types\";\n\n/** The eight 16-bit groups of a valid IPv6 address. */\nfunction groupsOf(address: string): number[] {\n // The URL parser writes an embedded IPv4 address as two groups, and compresses one run of zeros.\n const written = new URL(`http://[${address}]/`).hostname.slice(1, -1);\n const [head = \"\", tail = \"\"] = written.split(\"::\");\n const parse = (part: string): number[] =>\n part === \"\" ? [] : part.split(\":\").map((group) => Number.parseInt(group, 16));\n const before = parse(head);\n const after = parse(tail);\n return [...before, ...new Array<number>(8 - before.length - after.length).fill(0), ...after];\n}\n\n/**\n * The address an anonymous caller's lane is named by: an IPv4 address as it\n * is, an IPv4-mapped IPv6 address as its IPv4 address, another IPv6 address\n * as its /56 network, and anything else as it is.\n */\nexport function addressLane(ip: string): string {\n const address = ip.split(\"%\", 1)[0] ?? ip;\n if (!isIPv6(address)) {\n return ip;\n }\n const [a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0] = groupsOf(address);\n if (a === 0 && b === 0 && c === 0 && d === 0 && e === 0 && f === 0xffff) {\n return [g >> 8, g & 0xff, h >> 8, h & 0xff].join(\".\");\n }\n // The first 56 bits: three groups, and the high byte of the fourth.\n return `${[a, b, c, d & 0xff00].map((group) => group.toString(16)).join(\":\")}::/56`;\n}\n\n/** The address an HTTP request came from: Express's `req.ip` (which honors trust proxy), or the socket's. */\nfunction addressOf(request: McpRequest & { readonly transport: \"http\" }): string {\n const { ip } = request.req as { readonly ip?: unknown };\n return typeof ip === \"string\" && ip !== \"\"\n ? ip\n : (request.req.socket?.remoteAddress ?? \"unknown\");\n}\n\n/** The lane a call's queries share: its stdio session's, or its HTTP caller's. */\nexport function laneOf(request: McpRequest, principal: Principal | null): string {\n if (request.transport === \"stdio\") {\n return `mcp:${request.sessionId}`;\n }\n if (principal === null) {\n return `mcp:http:address:${addressLane(addressOf(request))}`;\n }\n if (request.token === null) {\n return `mcp:http:user:${principal.userId}`;\n }\n const hash = createHash(\"sha256\").update(request.token).digest(\"base64url\").slice(0, 22);\n return `mcp:http:token:${hash}`;\n}\n","// What a tool call runs as: the principal the registry's `principal` hook\n// maps the session or token to, or the one an app that signed the caller in\n// itself gives the call (`McpCallOptions.principal`, which skips the hook\n// and gets its grants loaded as `qd.caller`'s are), the `ctx.mcp` fields\n// the `context` hook adds, and a synthetic connection id: the concurrency\n// lane its queries share (RFC 0003 section 9, step 2), as a socket's\n// queries do. A stdio session is one lane; an HTTP request's lane is its\n// caller's (`lanes.ts`; the 5.1 audit's MCP-4): its bearer token's, its\n// user's without a token, or its address's when anonymous. A hook's refusal\n// (`QuickdrawError` `UNAUTHENTICATED` or `FORBIDDEN`) is logged at debug.\n\nimport type { Logger } from \"../../contract/logger\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { callerGrantsOf, lazyMembers, withCallerGrants, type CallOptions } from \"../caller\";\nimport { toQuickdrawError } from \"../pipeline/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport type { DispatchRequest, DispatchResult } from \"../pipeline/request\";\nimport { isForbiddenCredential, isPrincipal, isRefusal, toPrincipal } from \"../transports/auth\";\nimport type { McpContext, Principal } from \"../types\";\nimport { laneOf } from \"./lanes\";\nimport type { McpCallOptions, McpCallResult, McpRequest } from \"./types\";\n\n/** Who a tool call acts for, what it adds to `ctx.mcp`, and the connection it counts against. */\nexport interface McpSession {\n readonly principal: Principal | null;\n readonly mcp: McpContext | undefined;\n readonly connectionId: string;\n}\n\n/** The registry's `principal` option, as the bridge calls it. */\nexport type PrincipalHook = (request: McpRequest) => unknown;\n\n/** The registry's `context` option, as the bridge calls it. */\nexport type ContextHook = (request: McpRequest, principal: Principal | null) => unknown;\n\n/** What resolving sessions and making calls in them needs. */\nexport interface SessionSettings {\n readonly dispatcher: { call(request: DispatchRequest): Promise<DispatchResult> };\n readonly principal: PrincipalHook | undefined;\n readonly context: ContextHook | undefined;\n readonly logger: Logger;\n}\n\nconst CATEGORY = \"quickdraw.mcp\";\n\nasync function principalOf(\n settings: SessionSettings,\n request: McpRequest,\n): Promise<Principal | null> {\n if (settings.principal === undefined) {\n return null;\n }\n try {\n return toPrincipal(await settings.principal(request));\n } catch (error) {\n // A refusal the hook made on purpose is the caller's doing; a hook that broke is the app's.\n const refused = isRefusal(error) || isForbiddenCredential(error);\n settings.logger[refused ? \"debug\" : \"error\"](\"MCP authentication failed\", {\n category: CATEGORY,\n transport: request.transport,\n error: describeError(error),\n });\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication failed\");\n }\n}\n\nasync function contextOf(\n settings: SessionSettings,\n request: McpRequest,\n principal: Principal | null,\n): Promise<McpContext | undefined> {\n if (settings.context === undefined) {\n return undefined;\n }\n const fields: unknown = await settings.context(request, principal);\n if (fields === undefined) {\n return undefined;\n }\n if (typeof fields !== \"object\" || fields === null) {\n throw new TypeError(\"createMcpRegistry: context must return an object, the fields of ctx.mcp\");\n }\n return fields as McpContext;\n}\n\n/**\n * The principal an app gave a call: `null` or `undefined` for an anonymous\n * caller. Anything else that is no principal is a `TypeError`: the app's\n * mistake, never the caller's refusal.\n */\nfunction givenPrincipal(principal: unknown): Principal | null {\n if (principal === null || principal === undefined) {\n return null;\n }\n if (!isPrincipal(principal)) {\n throw new TypeError(\n \"An MCP call's principal must be a principal with a non-empty string userId, or null\",\n );\n }\n return principal;\n}\n\n/**\n * Resolves who a call acts for and its `ctx.mcp` fields. With a `principal`\n * key in `options` (`null` included), that principal, with the grants the\n * dispatcher's in-process callers load when it carries none (as\n * `qd.caller`'s, at each call; a failed load rejects with `INTERNAL`), and\n * the registry's `principal` hook is not asked; else the hook's, rejecting\n * with `UNAUTHENTICATED` when the hook fails. A failing `context` hook\n * rejects with its own error.\n */\nexport async function openSession(\n settings: SessionSettings,\n options: Pick<McpCallOptions, \"request\" | \"principal\">,\n): Promise<McpSession> {\n const { request } = options;\n const principal = Object.hasOwn(options, \"principal\")\n ? await withCallerGrants(givenPrincipal(options.principal), callerGrantsOf(settings.dispatcher))\n : await principalOf(settings, request);\n const mcp = await contextOf(settings, request, principal);\n return { principal, mcp, connectionId: laneOf(request, principal) };\n}\n\n/** A failed call's result. An `INTERNAL` failure is logged with what was thrown. */\nexport function failure(settings: SessionSettings, error: unknown, tool: string): McpCallResult {\n const converted = toQuickdrawError(error);\n if (converted.code === \"INTERNAL\") {\n settings.logger.error(`The MCP tool \"${tool}\" failed`, {\n category: CATEGORY,\n tool,\n error: describeError(converted),\n });\n }\n return { ok: false, error: converted };\n}\n\n/**\n * Hands `result` to the transport's `respond`, when it gave one, and returns\n * it. An error `respond` throws is logged and does not change the result.\n */\nexport function settle(\n settings: SessionSettings,\n options: McpCallOptions,\n result: McpCallResult,\n): McpCallResult {\n try {\n options.respond?.(result);\n } catch (error) {\n settings.logger.error(\"An MCP transport failed to send a reply\", {\n category: CATEGORY,\n error: describeError(error),\n });\n }\n return result;\n}\n\n/** A dispatcher result as a tool call's result. MCP calls never send a version, so never \"not modified\". */\nexport function fromDispatch(result: DispatchResult): McpCallResult {\n if (!result.ok) {\n return { ok: false, error: result.error };\n }\n return { ok: true, data: result.notModified === true ? undefined : result.data };\n}\n\n/** The dispatcher request of one method call made in `session`. */\nexport function sessionRequest(\n session: McpSession,\n call: Pick<DispatchRequest, \"service\" | \"method\" | \"input\" | \"signal\" | \"respond\">,\n): DispatchRequest {\n return {\n ...call,\n principal: session.principal,\n transport: \"mcp\",\n connectionId: session.connectionId,\n mcp: session.mcp,\n };\n}\n\ntype MethodFunction = (input?: unknown, options?: CallOptions) => Promise<unknown>;\n\n/**\n * An in-process caller acting in `session`: each call goes through the\n * dispatcher as an MCP call, with the session's principal, connection and\n * `ctx.mcp`, so a custom tool cannot reach past what the agent may do.\n */\nexport function sessionCaller(\n settings: SessionSettings,\n session: McpSession,\n signal: AbortSignal,\n): object {\n return lazyMembers((service) =>\n lazyMembers<MethodFunction>((method) => async (input, options) => {\n const request = sessionRequest(session, {\n service,\n method,\n input,\n signal: options?.signal ?? signal,\n });\n const result = await settings.dispatcher.call(request);\n if (!result.ok) {\n throw result.error;\n }\n return result.notModified === true ? undefined : result.data;\n }),\n );\n}\n","// Custom tools (RFC 0003 section 10): an app's own tools, served beside the\n// ones generated from contracts. 4.1's registry had no hook for them\n// (4.1 `src/server/mcp/McpRegistry.ts:13`), so apps that needed one ran a\n// bridge of their own. A custom tool fails closed like a method: unless it\n// declares `access: \"public\"`, an anonymous caller is refused before anything\n// runs, and a principal of a kind the tool does not admit (its `kinds`,\n// within the app's `initQuickdraw({ kinds })`, which it admits by default)\n// is refused too (`FORBIDDEN`, the 5.1 audit's MCP-6). A custom tool that\n// gives a Standard Schema has its arguments validated before its handler\n// runs, as a method's input is, and every handler gets a caller that acts in\n// the same session.\n\nimport { isStandardSchema, type StandardSchemaV1 } from \"../../contract/standardSchema\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { checkKind, narrowKinds } from \"../access/kinds\";\nimport { NEVER_ABORTED } from \"../context\";\nimport { parseInput } from \"../pipeline/validation\";\nimport { runtimeOf, type AnyService } from \"../service\";\nimport { failure, sessionCaller, type McpSession, type SessionSettings } from \"./session\";\nimport { inputOf, toolInputOf, type ArgumentsMode, type ToolInput } from \"./tools\";\nimport type {\n McpCallOptions,\n McpCallResult,\n McpInputSchema,\n McpTool,\n McpToolAccess,\n McpToolCall,\n} from \"./types\";\n\n/** A checked custom tool. */\nexport interface CustomTool {\n readonly tool: McpTool;\n /** Who may call it; `\"authenticated\"` unless the tool said otherwise. */\n readonly access: McpToolAccess;\n /** The kinds of principal that may call it: its own, or the app's; `undefined` admits every kind. */\n readonly kinds: readonly string[] | undefined;\n readonly mode: ArgumentsMode;\n /** The schema that validates the arguments, when the tool gave a Standard Schema. */\n readonly schema: StandardSchemaV1 | undefined;\n readonly handler: (call: McpToolCall) => unknown;\n}\n\ntype Fail = (message: string) => never;\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction argumentsOf(owner: string, inputSchema: unknown, fail: Fail): ToolInput {\n if (isStandardSchema(inputSchema)) {\n return toolInputOf(owner, inputSchema, fail, \"give the tool a JSON Schema object instead\");\n }\n if (isRecord(inputSchema) && inputSchema.type === \"object\") {\n return { schema: inputSchema as McpInputSchema, mode: \"object\" };\n }\n return fail(\n `${owner}: inputSchema must be a Standard Schema, or a JSON Schema whose type is \"object\"`,\n );\n}\n\nfunction accessOf(owner: string, access: unknown, fail: Fail): McpToolAccess {\n if (access === undefined) {\n return \"authenticated\";\n }\n if (access !== \"public\" && access !== \"authenticated\") {\n fail(`${owner}: access must be \"public\" or \"authenticated\"`);\n }\n return access;\n}\n\n/**\n * The kinds every one of `services` admits: what their apps'\n * `initQuickdraw({ kinds })` admit, in common; `undefined` admits every kind.\n */\nfunction appKindsOf(services: readonly AnyService[]): readonly string[] | undefined {\n let kinds: readonly string[] | undefined;\n for (const service of services) {\n const own = runtimeOf(service)?.kinds;\n if (own !== undefined) {\n kinds = kinds === undefined ? own : kinds.filter((kind) => own.includes(kind));\n }\n }\n return kinds;\n}\n\nfunction kindsOf(\n owner: string,\n value: Readonly<Record<string, unknown>>,\n access: McpToolAccess,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): readonly string[] | undefined {\n if (value.kinds !== undefined && access === \"public\") {\n fail(\n `${owner}: a \"public\" tool takes no kinds of its own, since a caller of a refused kind could call it signed out; give it access \"authenticated\"`,\n );\n }\n const above = appKinds === undefined ? undefined : { kinds: appKinds, by: \"initQuickdraw\" };\n return narrowKinds(value.kinds, above, (message) => fail(`${owner}: ${message}`));\n}\n\nfunction checkCustomTool(\n value: unknown,\n index: number,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): CustomTool {\n if (!isRecord(value)) {\n fail(`customTools[${index}] must be { name, description, inputSchema, handler }`);\n }\n const { name, description, inputSchema, annotations, handler } = value;\n if (typeof name !== \"string\" || name === \"\") {\n fail(`customTools[${index}] needs a name, a non-empty string`);\n }\n const owner = `custom tool \"${name}\"`;\n if (typeof description !== \"string\" || description === \"\") {\n fail(`${owner} needs a description, a non-empty string`);\n }\n if (typeof handler !== \"function\") {\n fail(`${owner} needs a handler function`);\n }\n if (annotations !== undefined && !isRecord(annotations)) {\n fail(`${owner}: annotations must be an object of hints`);\n }\n const access = accessOf(owner, value.access, fail);\n const kinds = kindsOf(owner, value, access, appKinds, fail);\n const input = argumentsOf(owner, inputSchema, fail);\n const tool: McpTool = {\n name,\n description,\n inputSchema: input.schema,\n ...(annotations === undefined ? {} : { annotations }),\n };\n return {\n tool: Object.freeze(tool),\n access,\n kinds,\n mode: input.mode,\n schema: isStandardSchema(inputSchema) ? inputSchema : undefined,\n handler: handler as CustomTool[\"handler\"],\n };\n}\n\n/** Checks the registry's `customTools` option, served beside `services`, whose apps' kinds they narrow. */\nexport function checkCustomTools(\n value: unknown,\n fail: Fail,\n services: readonly AnyService[] = [],\n): CustomTool[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value)) {\n fail(\"customTools must be an array of { name, description, inputSchema, handler }\");\n }\n const appKinds = appKindsOf(services);\n if (appKinds?.length === 0 && value.length > 0) {\n fail(\n \"customTools: the served services' apps admit no kind in common (initQuickdraw({ kinds })), so no principal could call a custom tool: serve custom tools beside the services of one app, or of apps that admit a kind in common\",\n );\n }\n return value.map((tool: unknown, index) => checkCustomTool(tool, index, appKinds, fail));\n}\n\n/**\n * Runs a custom tool with the arguments `args` in `session`: refuses an\n * anonymous caller unless the tool's access is `\"public\"`\n * (`UNAUTHENTICATED`) and a principal of a kind it does not admit\n * (`FORBIDDEN`), validates the arguments when the tool gave a Standard\n * Schema (`VALIDATION` with the issues otherwise), then runs the handler.\n * Never rejects.\n */\nexport async function runCustomTool(\n settings: SessionSettings,\n custom: CustomTool,\n args: unknown,\n session: McpSession,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const { name } = custom.tool;\n const signal = options.signal ?? NEVER_ABORTED;\n try {\n if (custom.access === \"authenticated\" && session.principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n checkKind(custom.kinds, session.principal, `The tool \"${name}\"`);\n const input = inputOf(custom.mode, args);\n const parsed =\n custom.schema === undefined\n ? input\n : await parseInput(custom.schema, input, `the tool \"${name}\"`);\n const data: unknown = await custom.handler({\n arguments: parsed,\n principal: session.principal,\n mcp: session.mcp,\n caller: sessionCaller(settings, session, signal) as McpToolCall[\"caller\"],\n signal,\n request: options.request,\n });\n return { ok: true, data };\n } catch (error) {\n return failure(settings, error, name);\n }\n}\n","// `createMcpRegistry` (RFC 0003 section 10): the tools of an app's services,\n// generated from their contracts, plus the app's own, and one `call` every\n// MCP transport uses. It replaces 4.1's `McpRegistry`\n// (4.1 `src/server/mcp/McpRegistry.ts:13`), which validated input, checked\n// access and ran handlers itself, as whatever user the tool's `userId`\n// argument named. Here a method's tool call goes through the dispatcher with\n// transport `\"mcp\"`, so validation and access checks apply as for a socket\n// call, and its queries share a concurrency lane per caller (`session.ts`);\n// the transport says who is calling through `principal` (or an app that\n// signed the caller in itself says it in the call's options, and the hook is\n// not asked), and `context` adds the session's own fields to the handler's\n// `ctx.mcp`. `bind` fills chosen arguments from that principal instead of\n// the agent, so an agent bound to one task cannot name another in its calls,\n// and a call that sends a bound argument its tool does not fill is refused\n// (`FORBIDDEN`).\n\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport type { Dispatcher, PrincipalOfServices } from \"../dispatcher\";\nimport type { AnyService } from \"../service\";\nimport type { AuthenticateResult } from \"../transports/auth\";\nimport type { MaybePromise } from \"../types\";\nimport { checkCustomTools, runCustomTool, type CustomTool } from \"./custom\";\nimport {\n failure,\n fromDispatch,\n openSession,\n sessionRequest,\n settle,\n type McpSession,\n type SessionSettings,\n} from \"./session\";\nimport { checkUniqueNames, inputOf, planMethodTools, type MethodTool } from \"./tools\";\nimport type {\n DescribeToolsOptions,\n McpBindCall,\n McpBinder,\n McpCallOptions,\n McpCallResult,\n McpContextOfServices,\n McpCustomTool,\n McpRequest,\n McpTool,\n McpToolInputSchema,\n} from \"./types\";\n\n/**\n * Options of {@link createMcpRegistry}. `Tools` are the custom tools' input\n * schema types, one per tool, which type each handler's `arguments`.\n */\nexport interface McpRegistryOptions<\n S extends readonly AnyService[],\n Tools extends readonly McpToolInputSchema[] = readonly McpToolInputSchema[],\n> extends DescribeToolsOptions<S> {\n /** The services whose methods become tools. The dispatcher must serve each of them. */\n readonly services: S;\n /** The dispatcher every method's tool calls through, with transport `\"mcp\"`. */\n readonly dispatcher: Pick<Dispatcher, \"call\" | \"registry\">;\n /**\n * Says who an MCP session or request acts for: a principal, a user id when\n * a bare `{ userId }` is a principal of the app's type, or nothing for an\n * anonymous caller, who may call `\"public\"` methods and `\"public\"` custom\n * tools only. A stdio server usually reads a token from its environment;\n * an HTTP request carries one as a bearer token. Throwing fails the call\n * with `UNAUTHENTICATED`: throw `QuickdrawError(\"UNAUTHENTICATED\")` (or\n * `FORBIDDEN`) to refuse a token, which is logged at debug, and never put\n * the token in a message; anything else thrown is logged as an error.\n * Without it every call is anonymous. An HTTP request's queries share the\n * lane of its bearer token: a hook that authenticates by anything else (a\n * cookie, an API key header) must refuse a request whose bearer token it\n * does not verify, or a caller makes a lane per made-up token. A call\n * whose options give `principal` (an app that signed the caller in\n * itself) is not asked about.\n */\n readonly principal?: (\n request: McpRequest,\n ) => MaybePromise<AuthenticateResult<PrincipalOfServices<S>>>;\n /**\n * The fields handlers see as `ctx.mcp` on calls from this registry, typed\n * by the app's `QuickdrawTypes[\"mcp\"]`: the scopes of the agent's token,\n * for example. Runs per call, after `principal`.\n */\n readonly context?: (\n request: McpRequest,\n principal: PrincipalOfServices<S> | null,\n ) => MaybePromise<McpContextOfServices<S>>;\n /**\n * Arguments filled from who is calling instead of by the agent, by name:\n * `{ taskId: ({ principal }) => principal.claims?.taskId }`. Each one is\n * left out of the `inputSchema` of every method's tool whose object input\n * has it, and each call of such a tool, by `call` or `callMethod`, gets the\n * binder's value before its input is validated. The call is refused\n * before the method runs when the caller is anonymous (`UNAUTHENTICATED`),\n * or when the binder returns `undefined` or `null` or the caller sent the\n * argument with another value (`FORBIDDEN`); a binder that throws fails it\n * with `INTERNAL`, or with the code of a `QuickdrawError`. A call of any\n * other method's tool that sends a bound argument is refused (`FORBIDDEN`).\n * An input that is a `$ref` to an object counts as that object, and a\n * bound key anywhere else in an input (in a union's or an intersection's\n * branch, or an input that is no object) fails when the registry is built.\n * Only top-level arguments are bound. Custom tools are never bound.\n * Binding is not access control: the same principal reaches the method\n * over a socket or HTTP with nothing bound, so the method's access must\n * still confine it.\n */\n readonly bind?: Readonly<Record<string, McpBinder<S>>>;\n /** The app's own tools, listed after the generated ones. */\n readonly customTools?: { readonly [K in keyof Tools]: McpCustomTool<S, Tools[K]> };\n /** Receives tool failures and authentication errors. Default: the console. */\n readonly logger?: Logger;\n}\n\n/** The tools an MCP transport serves, and the one way to call them. */\nexport interface McpRegistry {\n /**\n * Every tool, generated ones first, as `tools/list` and `GET /mcp/tools`\n * return them: the same list for every caller, never filtered by the\n * principal, so an agent may see tools whose calls are refused. A\n * registry's `include`/`exclude` decide the list; serve agents of\n * different reach from separate registries.\n */\n readonly tools: readonly McpTool[];\n /** True when a tool has this name. */\n has(name: string): boolean;\n /**\n * Calls the tool `name` with the client's `args` in the session of\n * `options.request`, as `options.principal` when it is given. Resolves\n * with the tool's value or its failure (an unknown name is `NOT_FOUND`),\n * after `options.respond` was given it. Never rejects.\n */\n call(name: string, args: unknown, options: McpCallOptions): Promise<McpCallResult>;\n /**\n * Calls a method's tool by its service and method name with the method's\n * `input` as it is, without the tool's argument mapping: the shape 4.1's\n * HTTP route took. Bound arguments are filled as for `call`, and\n * `options.principal` says who calls as for `call`: an app's own MCP\n * transport over it passes the caller it signed in. A method that is not\n * a tool is `NOT_FOUND`.\n */\n callMethod(\n service: string,\n method: string,\n input: unknown,\n options: McpCallOptions,\n ): Promise<McpCallResult>;\n}\n\ntype Entry =\n | ({ readonly kind: \"method\" } & MethodTool)\n | ({ readonly kind: \"custom\" } & CustomTool);\n\n/** A function of the registry's `bind` option, as the bridge calls it. */\ntype BindHook = (call: McpBindCall) => unknown;\n\ninterface RegistrySettings extends SessionSettings {\n /** Every tool by name, in listing order. */\n readonly entries: ReadonlyMap<string, Entry>;\n /** The method tools by {@link methodKey}. */\n readonly methods: ReadonlyMap<string, MethodTool>;\n /** The `bind` option's functions by the argument each fills. */\n readonly binders: ReadonlyMap<string, BindHook>;\n}\n\ntype Fail = (message: string) => never;\n\n/** A method's key, unambiguous whatever characters its names hold. */\nfunction methodKey(service: string, method: string): string {\n return `${service}\\u0000${method}`;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction checkHook(name: string, hook: unknown, fail: Fail): void {\n if (hook !== undefined && typeof hook !== \"function\") {\n fail(`${name} must be a function of the MCP request`);\n }\n}\n\n/** Fails unless `dispatcher` serves every one of `services`, as the very same service objects. */\nfunction checkDispatcher(dispatcher: unknown, services: unknown, fail: Fail): void {\n if (\n !isRecord(dispatcher) ||\n typeof dispatcher.call !== \"function\" ||\n !isRecord(dispatcher.registry) ||\n !(dispatcher.registry.services instanceof Map)\n ) {\n fail(\"dispatcher must be a dispatcher from createDispatcher or qd.createServer\");\n }\n if (!Array.isArray(services)) {\n fail(\"services must be an array of services from qd.defineService\");\n }\n const served = dispatcher.registry.services as ReadonlyMap<string, unknown>;\n for (const service of services) {\n const name: unknown = isRecord(service) ? service.name : undefined;\n if (typeof name !== \"string\" || served.get(name) !== service) {\n fail(\n `the dispatcher does not serve ${typeof name === \"string\" ? name : \"one of the services\"}; pass services the dispatcher was created with`,\n );\n }\n }\n}\n\n/** Checks the registry's `bind` option: an object of functions, one per argument. */\nfunction checkBinders(bind: unknown, fail: Fail): ReadonlyMap<string, BindHook> {\n if (bind === undefined) {\n return new Map();\n }\n if (!isRecord(bind) || Array.isArray(bind)) {\n fail(\"bind must be an object of functions, one per argument it fills\");\n }\n const binders = new Map<string, BindHook>();\n for (const [key, binder] of Object.entries(bind)) {\n if (typeof binder !== \"function\") {\n fail(`bind.${key} must be a function of the call, returning the argument's value`);\n }\n binders.set(key, binder as BindHook);\n }\n return binders;\n}\n\n/** Fails when an argument of `bind` is in no tool's object input: a misspelled name would bind nothing. */\nfunction checkBound(\n binders: ReadonlyMap<string, BindHook>,\n methodTools: readonly MethodTool[],\n fail: Fail,\n): void {\n for (const key of binders.keys()) {\n if (!methodTools.some((tool) => tool.bound.includes(key))) {\n fail(\n `bind.${key} fills nothing: no method served as a tool has \"${key}\" in its object input`,\n );\n }\n }\n}\n\nfunction resolveRegistry(options: McpRegistryOptions<readonly AnyService[]>): RegistrySettings {\n const fail: Fail = (message) => {\n throw new TypeError(`createMcpRegistry: ${message}`);\n };\n if (!isRecord(options)) {\n fail(\"options must be an object with services and dispatcher\");\n }\n checkDispatcher(options.dispatcher, options.services, fail);\n checkHook(\"principal\", options.principal, fail);\n checkHook(\"context\", options.context, fail);\n const binders = checkBinders(options.bind, fail);\n const methodTools = planMethodTools(options.services, options, fail, [...binders.keys()]);\n checkBound(binders, methodTools, fail);\n const customTools = checkCustomTools(options.customTools, fail, options.services);\n const entries: Entry[] = [\n ...methodTools.map((tool) => ({ kind: \"method\" as const, ...tool })),\n ...customTools.map((tool) => ({ kind: \"custom\" as const, ...tool })),\n ];\n checkUniqueNames(\n entries.map((entry) => ({\n tool: entry.tool,\n owner: entry.kind === \"method\" ? `${entry.service}.${entry.method}` : \"a custom tool\",\n })),\n fail,\n );\n return {\n dispatcher: options.dispatcher,\n principal: options.principal,\n context: options.context as SessionSettings[\"context\"],\n logger: options.logger ?? consoleLogger,\n entries: new Map(entries.map((entry) => [entry.tool.name, entry])),\n methods: new Map(methodTools.map((tool) => [methodKey(tool.service, tool.method), tool])),\n binders,\n };\n}\n\n/**\n * Runs `run` in the session of `options.request`, as `options.principal`\n * when it is given, or fails the call when the session cannot open.\n */\nasync function inSession(\n settings: RegistrySettings,\n name: string,\n options: McpCallOptions,\n run: (session: McpSession) => Promise<McpCallResult>,\n): Promise<McpCallResult> {\n let session: McpSession;\n try {\n session = await openSession(settings, options);\n } catch (error) {\n return settle(settings, options, failure(settings, error, name));\n }\n return run(session);\n}\n\n/**\n * The input of a call of a tool with bound arguments: `input` with each of\n * them filled by its binder. Rejects with `UNAUTHENTICATED` for an anonymous\n * caller, `VALIDATION` when the arguments are not an object, and `FORBIDDEN`\n * when a binder has no value or the caller sent another one.\n */\nasync function bindInput(\n settings: RegistrySettings,\n tool: MethodTool,\n input: unknown,\n session: McpSession,\n request: McpRequest,\n): Promise<unknown> {\n const { principal } = session;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const given: unknown = input ?? {};\n if (!isRecord(given) || Array.isArray(given)) {\n throw new QuickdrawError(\"VALIDATION\", `Invalid input for ${tool.service}.${tool.method}`, {\n issues: [{ path: [], message: \"Expected an object\" }],\n });\n }\n const call: McpBindCall = {\n principal,\n mcp: session.mcp,\n request,\n service: tool.service,\n method: tool.method,\n };\n const filled: [string, unknown][] = [];\n for (const [key, binder] of settings.binders) {\n if (!tool.bound.includes(key)) {\n continue;\n }\n const value = await binder(call);\n if (value === undefined || value === null) {\n throw new QuickdrawError(\"FORBIDDEN\", `\"${key}\" is bound to the caller, who has none`);\n }\n // The binder's value replaces what the caller sent. Another value is\n // refused rather than replaced in silence, so an agent never believes it\n // called with the value it named.\n const sent = Object.hasOwn(given, key) ? given[key] : undefined;\n if (sent !== undefined && JSON.stringify(sent) !== JSON.stringify(value)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${key}\" is bound to the caller and cannot be set to another value`,\n );\n }\n filled.push([key, value]);\n }\n return { ...given, ...Object.fromEntries(filled) };\n}\n\n/** Calls a method through the dispatcher, which hands the result to `respond` before it flushes. */\nasync function dispatchMethod(\n settings: RegistrySettings,\n tool: MethodTool,\n input: unknown,\n session: McpSession,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n // A bound argument the tool does not fill is never the agent's to send (MCP-1): refused, not passed on.\n const stray =\n settings.binders.size === 0 || !isRecord(input) || Array.isArray(input)\n ? undefined\n : [...settings.binders.keys()].find(\n (key) => !tool.bound.includes(key) && Object.hasOwn(input, key),\n );\n if (stray !== undefined) {\n const error = new QuickdrawError(\n \"FORBIDDEN\",\n `\"${stray}\" is bound to the caller; ${tool.service}.${tool.method} does not take it from the agent`,\n );\n return settle(settings, options, failure(settings, error, tool.tool.name));\n }\n let bound = input;\n if (tool.bound.length > 0) {\n try {\n bound = await bindInput(settings, tool, input, session, options.request);\n } catch (error) {\n return settle(settings, options, failure(settings, error, tool.tool.name));\n }\n }\n const { respond } = options;\n const request = sessionRequest(session, {\n service: tool.service,\n method: tool.method,\n input: bound,\n signal: options.signal,\n respond: respond === undefined ? undefined : (result) => respond(fromDispatch(result)),\n });\n return fromDispatch(await settings.dispatcher.call(request));\n}\n\nfunction callTool(\n settings: RegistrySettings,\n name: string,\n args: unknown,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const entry = settings.entries.get(name);\n if (entry === undefined) {\n const error = new QuickdrawError(\"NOT_FOUND\", `Unknown tool \"${name}\"`);\n return Promise.resolve(settle(settings, options, { ok: false, error }));\n }\n if (entry.kind === \"method\") {\n const input = inputOf(entry.mode, args);\n return inSession(settings, name, options, (session) =>\n dispatchMethod(settings, entry, input, session, options),\n );\n }\n return inSession(settings, name, options, async (session) =>\n settle(settings, options, await runCustomTool(settings, entry, args, session, options)),\n );\n}\n\nfunction callMethodTool(\n settings: RegistrySettings,\n service: string,\n method: string,\n input: unknown,\n options: McpCallOptions,\n): Promise<McpCallResult> {\n const tool = settings.methods.get(methodKey(service, method));\n if (tool === undefined) {\n const error = new QuickdrawError(\"NOT_FOUND\", `${service}.${method} is not an MCP tool`);\n return Promise.resolve(settle(settings, options, { ok: false, error }));\n }\n return inSession(settings, tool.tool.name, options, (session) =>\n dispatchMethod(settings, tool, input, session, options),\n );\n}\n\n/**\n * Builds the MCP tools of `services` (see `describeTools`) and the app's\n * `customTools`, served by `dispatcher`. Throws at once when a method's\n * input schema cannot describe itself as JSON Schema (use Zod 4.2 or later\n * for it, or `exclude` the method), when two tools share a name, when the\n * dispatcher does not serve one of the services, when an argument of\n * `bind` is in no tool's object input or may be anywhere in an input where\n * it cannot be filled (an input that is not an object schema, or a branch\n * of a union or an intersection, behind a `$ref` too), or when custom tools\n * are served beside the services of apps that admit no kind in common.\n * Every call runs in its caller's concurrency lane: a stdio session, or on\n * HTTP its bearer token, its user without a token, or its address when\n * anonymous.\n *\n * @example\n * const registry = createMcpRegistry({\n * services: [taskService, projectService],\n * dispatcher: server.dispatcher,\n * principal: (request) => verifyAgentToken(request.transport === \"http\" ? request.token : process.env.AGENT_TOKEN),\n * context: (request) => ({ scopes: scopesOf(request) }),\n * });\n */\nexport function createMcpRegistry<\n const S extends readonly AnyService[],\n const Tools extends readonly McpToolInputSchema[] = [],\n>(options: McpRegistryOptions<S, Tools>): McpRegistry {\n const settings = resolveRegistry(options as unknown as McpRegistryOptions<readonly AnyService[]>);\n const tools = Object.freeze([...settings.entries.values()].map((entry) => entry.tool));\n return Object.freeze({\n tools,\n has: (name: string) => settings.entries.has(name),\n call: (name: string, args: unknown, callOptions: McpCallOptions) =>\n callTool(settings, name, args, callOptions),\n callMethod: (service: string, method: string, input: unknown, callOptions: McpCallOptions) =>\n callMethodTool(settings, service, method, input, callOptions),\n });\n}\n","// A tool call's result in the shape of MCP's `tools/call` result, as 4.1\n// wrote it (4.1 `src/server/mcp/McpStdioServer.ts:85-96`): one text block\n// holding the value as indented JSON. A failure is a tool error (`isError`)\n// whose text is the error's wire form, `{ code, message, data? }`, so the\n// agent sees the code; 4.1 answered a failed call with a JSON-RPC error\n// instead. An `INTERNAL` failure keeps its generic message (`toWire`).\n\nimport { toWire } from \"../../protocol/errors\";\nimport type { McpCallResult, McpTextContent, McpToolResult } from \"./types\";\n\nfunction jsonText(value: unknown): McpTextContent {\n // `JSON.stringify` returns `undefined` for `undefined` (a method that\n // returns nothing) and for a function.\n const text: string | undefined = JSON.stringify(value, null, 2);\n return { type: \"text\", text: text ?? \"null\" };\n}\n\n/**\n * The `tools/call` result of a tool call. Throws when the value cannot be\n * written as JSON (a `BigInt` or a cycle); a transport answers that with an\n * `INTERNAL` tool error.\n *\n * @example\n * toToolResult(await registry.call(name, args, { request }));\n */\nexport function toToolResult(result: McpCallResult): McpToolResult {\n if (!result.ok) {\n return { content: [jsonText(toWire(result.error))], isError: true };\n }\n return { content: [jsonText(result.data)] };\n}\n","// The MCP stdio server: JSON-RPC 2.0, one message per line, on stdin and\n// stdout (RFC 0003 section 10). Ported from 4.1's `createMcpStdioServer`\n// (4.1 `src/server/mcp/McpStdioServer.ts:22`), keeping its wire format:\n// protocol version 2024-11-05, `initialize`, `ping`, `tools/list` and\n// `tools/call`, a tool's value as one block of JSON text, and the same\n// JSON-RPC error codes. What changed:\n//\n// - tools come from the registry, and who is calling from its `principal`\n// hook, rather than from a `userId` argument any agent could set;\n// - a failed call is a tool result with `isError` whose text carries the\n// error's code, where 4.1 answered with a JSON-RPC error;\n// - requests are handled concurrently, so the session's queries share one\n// concurrency lane, and `notifications/cancelled` stops a call in flight\n// (MCP sends no reply for a cancelled request);\n// - notifications never get a reply, and a JSON-RPC response from the client\n// is ignored;\n// - it never exits the process: `closed` resolves once stdin ends and every\n// call still running has answered (a client that writes its requests and\n// closes stdin still gets every reply), while `close()` and a broken\n// stream cancel the calls in flight instead.\n//\n// Anything else that writes to stdout corrupts the protocol, so start the\n// server through `bootstrapMcpServer`, which sends console output to stderr.\n\nimport { randomUUID } from \"node:crypto\";\nimport { createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport type { Logger } from \"../../contract/logger\";\nimport { INTERNAL_MESSAGE, QuickdrawError } from \"../../protocol/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport type { McpRegistry } from \"./registry\";\nimport { toToolResult } from \"./result\";\nimport { stderrLogger } from \"./stderr\";\nimport type { McpCallResult, McpStdioRequest } from \"./types\";\n\n/** The MCP protocol version the stdio server speaks: 4.1's. */\nexport const MCP_PROTOCOL_VERSION = \"2024-11-05\";\n\n/** Options of {@link createMcpStdioServer}. */\nexport interface McpStdioServerOptions {\n /** The tools to serve. */\n readonly registry: McpRegistry;\n /** The server's name, sent in `initialize`'s `serverInfo`. */\n readonly name: string;\n /** The server's version, sent in `initialize`'s `serverInfo`. */\n readonly version: string;\n /** Where messages arrive. Default `process.stdin`. */\n readonly input?: Readable;\n /** Where replies go. Default `process.stdout`. */\n readonly output?: Writable;\n /** Receives the server's own problems. Default: one line per entry on stderr. */\n readonly logger?: Logger;\n}\n\n/** A running stdio server. */\nexport interface McpStdioServer {\n /** The session id every call of this server carries, and its synthetic connection. */\n readonly sessionId: string;\n /**\n * Resolves once the input has ended and every message in flight has been\n * handled: when stdin ends, the calls still running finish and their\n * replies are written first.\n */\n readonly closed: Promise<void>;\n /** Stops reading and cancels the calls in flight (no reply is written for them); resolves as `closed` does. */\n close(): Promise<void>;\n}\n\ntype RequestId = string | number;\n\ninterface Session {\n readonly registry: McpRegistry;\n readonly serverInfo: { readonly name: string; readonly version: string };\n readonly request: McpStdioRequest;\n readonly output: Writable;\n readonly logger: Logger;\n /** The `tools/call` requests in flight, by id, so they can be cancelled. */\n readonly calls: Map<RequestId, AbortController>;\n /** Every message still being handled. */\n readonly pending: Set<Promise<void>>;\n /** False once the output failed. */\n writable: boolean;\n}\n\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INVALID_PARAMS = -32602;\nconst CATEGORY = \"quickdraw.mcp\";\n\nconst INTERNAL_FAILURE: McpCallResult = Object.freeze({\n ok: false,\n error: new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE),\n});\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** MCP request ids are strings or numbers, never `null`. */\nfunction isRequestId(value: unknown): value is RequestId {\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value));\n}\n\n/** Writes one message as one line; returns its size in bytes. */\nfunction write(session: Session, message: object): number | undefined {\n if (!session.writable) {\n return undefined;\n }\n const line = `${JSON.stringify(message)}\\n`;\n session.output.write(line);\n return Buffer.byteLength(line);\n}\n\nfunction reply(session: Session, id: RequestId, result: unknown): number | undefined {\n return write(session, { jsonrpc: \"2.0\", id, result });\n}\n\nfunction replyError(session: Session, id: RequestId | null, code: number, message: string): void {\n write(session, { jsonrpc: \"2.0\", id, error: { code, message } });\n}\n\nfunction replyToolResult(\n session: Session,\n id: RequestId,\n result: McpCallResult,\n): number | undefined {\n let content: unknown;\n try {\n content = toToolResult(result);\n } catch (error) {\n session.logger.error(\n \"A tool's value could not be written as JSON; it was answered with INTERNAL\",\n {\n category: CATEGORY,\n error: describeError(error),\n },\n );\n content = toToolResult(INTERNAL_FAILURE);\n }\n return reply(session, id, content);\n}\n\nasync function callTool(session: Session, id: RequestId, params: unknown): Promise<void> {\n if (!isRecord(params) || typeof params.name !== \"string\") {\n replyError(session, id, INVALID_PARAMS, \"tools/call needs params { name, arguments? }\");\n return;\n }\n const { name } = params;\n if (!session.registry.has(name)) {\n replyError(session, id, INVALID_PARAMS, `Unknown tool: ${name}`);\n return;\n }\n if (session.calls.has(id)) {\n replyError(session, id, INVALID_REQUEST, `Request ${JSON.stringify(id)} is already in flight`);\n return;\n }\n const controller = new AbortController();\n session.calls.set(id, controller);\n const release = (): void => {\n if (session.calls.get(id) === controller) {\n session.calls.delete(id);\n }\n };\n try {\n await session.registry.call(name, params.arguments, {\n request: session.request,\n signal: controller.signal,\n respond: (result) => {\n release();\n // A cancelled call gets no reply, nor does one whose session ended.\n return controller.signal.aborted ? undefined : replyToolResult(session, id, result);\n },\n });\n } finally {\n release();\n }\n}\n\nasync function onRequest(\n session: Session,\n id: RequestId,\n method: string,\n params: unknown,\n): Promise<void> {\n switch (method) {\n case \"initialize\":\n reply(session, id, {\n protocolVersion: MCP_PROTOCOL_VERSION,\n serverInfo: session.serverInfo,\n capabilities: { tools: {} },\n });\n return;\n case \"ping\":\n reply(session, id, {});\n return;\n case \"tools/list\":\n reply(session, id, { tools: session.registry.tools });\n return;\n case \"tools/call\":\n await callTool(session, id, params);\n return;\n default:\n replyError(session, id, METHOD_NOT_FOUND, `Method not found: ${method}`);\n }\n}\n\n/** `notifications/cancelled` stops a call in flight; every other notification needs nothing. */\nfunction onNotification(session: Session, method: string, params: unknown): void {\n if (method === \"notifications/cancelled\" && isRecord(params) && isRequestId(params.requestId)) {\n session.calls.get(params.requestId)?.abort();\n }\n}\n\nconst UNPARSABLE = Symbol(\"unparsable\");\n\nfunction parse(line: string): unknown {\n try {\n return JSON.parse(line) as unknown;\n } catch {\n return UNPARSABLE;\n }\n}\n\nasync function onLine(session: Session, line: string): Promise<void> {\n if (line.trim() === \"\") {\n return;\n }\n const message = parse(line);\n if (message === UNPARSABLE) {\n replyError(session, null, PARSE_ERROR, \"Parse error\");\n return;\n }\n if (!isRecord(message)) {\n replyError(session, null, INVALID_REQUEST, \"Invalid Request\");\n return;\n }\n const { id, method, params } = message;\n if (typeof method !== \"string\") {\n // A response to a request this server never sends: answering it could loop.\n if (!(\"result\" in message) && !(\"error\" in message)) {\n replyError(session, isRequestId(id) ? id : null, INVALID_REQUEST, \"Invalid Request\");\n }\n return;\n }\n if (id === undefined) {\n onNotification(session, method, params);\n return;\n }\n if (!isRequestId(id)) {\n replyError(session, null, INVALID_REQUEST, \"Invalid Request\");\n return;\n }\n await onRequest(session, id, method, params);\n}\n\n/** Handles one message, keeping track of it until it is done. */\nfunction track(session: Session, work: Promise<void>): void {\n const handled = work.catch((error: unknown) => {\n session.logger.error(\"The MCP stdio server failed to handle a message\", {\n category: CATEGORY,\n error: describeError(error),\n });\n });\n session.pending.add(handled);\n void handled.then(() => session.pending.delete(handled));\n}\n\nfunction openSession(options: McpStdioServerOptions): Session {\n if (\n typeof options !== \"object\" ||\n options === null ||\n typeof options.registry?.call !== \"function\"\n ) {\n throw new TypeError(\"createMcpStdioServer: registry must come from createMcpRegistry\");\n }\n if (typeof options.name !== \"string\" || typeof options.version !== \"string\") {\n throw new TypeError(\"createMcpStdioServer: name and version must be strings, for serverInfo\");\n }\n return {\n registry: options.registry,\n serverInfo: Object.freeze({ name: options.name, version: options.version }),\n request: Object.freeze({ transport: \"stdio\", sessionId: randomUUID() }),\n output: options.output ?? process.stdout,\n logger: options.logger ?? stderrLogger,\n calls: new Map(),\n pending: new Set(),\n writable: true,\n };\n}\n\n/**\n * Serves `registry`'s tools over MCP's stdio transport: JSON-RPC messages,\n * one per line, read from stdin and answered on stdout. The server is one\n * session: its calls carry one session id and share one concurrency lane,\n * and the registry's `principal` and `context` hooks see the same\n * `{ transport: \"stdio\", sessionId }` request on every call. It never exits\n * the process.\n *\n * @example\n * // mcp-server.ts, started through bootstrapMcpServer\n * const registry = createMcpRegistry({ services, dispatcher, principal: () => agentFromEnv() });\n * const server = createMcpStdioServer({ registry, name: \"my-app\", version: \"1.0.0\" });\n * await server.closed;\n * await prisma.$disconnect();\n */\nexport function createMcpStdioServer(options: McpStdioServerOptions): McpStdioServer {\n const session = openSession(options);\n const lines = createInterface({\n input: options.input ?? process.stdin,\n crlfDelay: Infinity,\n terminal: false,\n });\n // Ending stdin lets the calls in flight answer; `close()` and a broken stream cancel them.\n let cancel = false;\n const stop = (): void => {\n cancel = true;\n lines.close();\n };\n const fail = (error: Error): void => {\n session.logger.warn(\"The MCP stdio stream failed; the session ends\", {\n category: CATEGORY,\n error: describeError(error),\n });\n stop();\n };\n const onOutputError = (error: Error): void => {\n session.writable = false;\n fail(error);\n };\n session.output.on(\"error\", onOutputError);\n lines.on(\"error\", fail);\n lines.on(\"line\", (line) => track(session, onLine(session, line)));\n const closed = new Promise<void>((resolve) => {\n lines.once(\"close\", () => {\n for (const controller of cancel ? session.calls.values() : []) {\n controller.abort();\n }\n void Promise.allSettled([...session.pending]).then(() => {\n session.output.off(\"error\", onOutputError);\n resolve();\n });\n });\n });\n return Object.freeze({\n sessionId: session.request.sessionId,\n closed,\n close: () => {\n stop();\n return closed;\n },\n });\n}\n","// Writing to stderr. An MCP stdio server owns stdout for the protocol, so its\n// own log lines, and everything `bootstrapMcpServer` takes from the console,\n// go to stderr instead.\n\nimport { format, inspect } from \"node:util\";\nimport type { Logger } from \"../../contract/logger\";\n\n/** Writes one line to stderr, formatting the arguments as `console.log` would. */\nexport function writeStderr(...args: unknown[]): void {\n process.stderr.write(`${format(...args)}\\n`);\n}\n\nfunction entry(level: string): (message: string, meta?: Record<string, unknown>) => void {\n return (message, meta) => {\n const details = meta === undefined ? \"\" : ` ${inspect(meta, { breakLength: Infinity })}`;\n process.stderr.write(`[${level}] ${message}${details}\\n`);\n };\n}\n\n/** A logger that writes each entry to stderr as one line. */\nexport const stderrLogger: Logger = {\n debug: entry(\"DEBUG\"),\n info: entry(\"INFO\"),\n warn: entry(\"WARN\"),\n error: entry(\"ERROR\"),\n child: () => stderrLogger,\n};\n","// `bootstrapMcpServer`: loads the module that starts an MCP stdio server\n// after sending console output to stderr, so nothing but the protocol\n// reaches stdout, not even what that module's imports log while loading.\n// Ported from 4.1 (4.1 `src/server/mcp/McpBootstrap.ts:12`) with two\n// changes: a relative path is resolved against the working directory (4.1\n// handed it to `import()`, which resolves it against the package's own file,\n// so a relative path never found the app's module), and a module that fails\n// to load sets the exit code instead of calling `process.exit`.\n\nimport { resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { writeStderr } from \"./stderr\";\n\nfunction specifierOf(serverModule: string | URL): string {\n if (serverModule instanceof URL) {\n return serverModule.href;\n }\n return serverModule.startsWith(\"file:\")\n ? serverModule\n : pathToFileURL(resolve(serverModule)).href;\n}\n\n/**\n * Sends `console.log`, `info`, `warn` and `debug` to stderr, sets\n * `MCP_MODE=true` (and `LOG_LEVEL=warn` unless it is set), then imports\n * `serverModule`, the module that creates the stdio server. A path is\n * resolved against the working directory; pass a URL to resolve it against\n * the calling module. Resolves once the module has loaded. When it fails to\n * load, the error goes to stderr and the process exit code becomes 1.\n *\n * @example\n * // mcp.ts: the MCP client runs `node dist/mcp.js`\n * import { bootstrapMcpServer } from \"@fitzzero/quickdraw-core/server/mcp\";\n * await bootstrapMcpServer(new URL(\"./mcp-server.js\", import.meta.url));\n */\nexport async function bootstrapMcpServer(serverModule: string | URL): Promise<void> {\n process.env.MCP_MODE = \"true\";\n process.env.LOG_LEVEL ??= \"warn\";\n // The console methods that write to stdout; `console.error` writes to stderr already.\n Object.assign(console, {\n log: writeStderr,\n info: writeStderr,\n warn: writeStderr,\n debug: writeStderr,\n });\n try {\n await import(specifierOf(serverModule));\n } catch (error) {\n writeStderr(\"Bootstrap error:\", error);\n process.exitCode = 1;\n }\n}\n","// What a request to the MCP HTTP routes stands for, and whether the routes\n// take it. `requestOf` makes each request a session of its own: a random\n// session id, which hooks see, and its bearer token. `requestGate` refuses a\n// request from a web page whose `Origin` `allowedOrigins` does not list\n// (none by default), and, with `allowedHosts`, one for a `Host` it does not\n// list (the 5.1 audit's MCP-3): a page an agent's user opens could otherwise\n// call the routes from their browser, and a DNS-rebinding page could reach a\n// server listening on their machine. A request without an `Origin` is no\n// page's: an MCP client sends none. An `allowedHosts` entry is compared as a\n// host: in any case, an IPv6 address with or without brackets, a name in\n// Unicode or punycode, and a port when it writes one.\n\nimport { randomUUID } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport { originAllowlist, type AllowedOrigin } from \"../auth/routes/origins\";\nimport type { McpHttpRequest } from \"./types\";\n\nexport type { AllowedOrigin };\n\n/** The session an `invoke` request stands for, with its bearer token. */\nexport function requestOf(req: IncomingMessage): McpHttpRequest {\n const header = req.headers.authorization;\n const token = typeof header === \"string\" && header.startsWith(\"Bearer \") ? header.slice(7) : \"\";\n return {\n transport: \"http\",\n sessionId: randomUUID(),\n token: token.trim() === \"\" ? null : token.trim(),\n headers: req.headers,\n req,\n };\n}\n\n/** Why the routes refuse a request, before either route runs. */\nexport interface RequestGate {\n /** Why the routes refuse `req`, or `undefined` when they take it. */\n refusal(req: IncomingMessage): string | undefined;\n}\n\n/**\n * A host as the gate compares it: its name (lower case, an IPv6 address in\n * brackets, a name in punycode), and its port when one is written.\n */\ninterface Host {\n readonly hostname: string;\n readonly port: string | undefined;\n}\n\n/** `value`, a host as a `Host` header or an `allowedHosts` entry writes it, or `undefined` when it is not one. */\nfunction hostOf(value: string): Host | undefined {\n if (/\\s/u.test(value)) {\n return undefined;\n }\n // A bare IPv6 address (two colons or more, no brackets) is a host without a port.\n const host = !value.startsWith(\"[\") && value.split(\":\").length > 2 ? `[${value}]` : value;\n let url: URL;\n try {\n url = new URL(`http://${host}`);\n } catch {\n return undefined;\n }\n const extra = url.username + url.password + url.search + url.hash;\n if (url.hostname === \"\" || extra !== \"\" || url.pathname !== \"/\") {\n return undefined;\n }\n // The URL parser drops port 80, its scheme's default: whether a port is written is read from the text.\n const written = !host.endsWith(\"]\") && /:\\d+$/u.test(host);\n return { hostname: url.hostname, port: written ? url.port || \"80\" : undefined };\n}\n\nfunction checkHosts(hosts: unknown): readonly Host[] | undefined {\n if (hosts === undefined) {\n return undefined;\n }\n const parsed = Array.isArray(hosts)\n ? hosts.map((host: unknown) => (typeof host === \"string\" ? hostOf(host) : undefined))\n : [];\n if (parsed.length === 0 || parsed.includes(undefined)) {\n throw new TypeError(\n 'createMcpHttpRouter: allowedHosts must list host names, such as \"localhost\" or \"mcp.example.com:8443\"',\n );\n }\n return Object.freeze(parsed as Host[]);\n}\n\n/**\n * True when the `Host` header names one of `hosts`. An entry without a port\n * matches any port; a header without one is for its scheme's default port,\n * 80 or 443.\n */\nfunction hostAllowed(hosts: readonly Host[], header: string | undefined): boolean {\n const host = header === undefined ? undefined : hostOf(header);\n if (host === undefined) {\n return false;\n }\n const portMatches = (port: string): boolean =>\n host.port === undefined ? port === \"80\" || port === \"443\" : port === host.port;\n return hosts.some(\n (entry) =>\n entry.hostname === host.hostname && (entry.port === undefined || portMatches(entry.port)),\n );\n}\n\n/** The gate of the routes made with `allowedOrigins` and `allowedHosts`, both checked. */\nexport function requestGate(allowedOrigins: unknown, allowedHosts: unknown): RequestGate {\n const origins = originAllowlist(\n (allowedOrigins ?? []) as readonly AllowedOrigin[],\n \"createMcpHttpRouter\",\n true,\n );\n const hosts = checkHosts(allowedHosts);\n return Object.freeze({\n refusal(req: IncomingMessage): string | undefined {\n const { origin, host } = req.headers;\n if (origin !== undefined && origins.allowed(origin) === null) {\n return \"The MCP routes refuse requests from web pages unless allowedOrigins lists their origin\";\n }\n if (hosts !== undefined && !hostAllowed(hosts, host)) {\n return \"The MCP routes do not answer for this host\";\n }\n return undefined;\n },\n });\n}\n","// The MCP HTTP routes (RFC 0003 section 10), ported from 4.1's\n// `createMcpRoutes` (4.1 `src/server/mcp/McpHttpRoutes.ts:12`) onto the\n// registry, keeping its wire format:\n//\n// GET {path}/tools -> { tools }\n// POST {path}/invoke { service, method, payload } -> { success: true, data }\n//\n// `invoke` also takes `{ name, arguments }`, which reaches every tool, the\n// app's own included. Like the HTTP transport, the routes are a plain Node\n// request handler rather than an `express.Router`, so they mount with\n// `app.use(router)` on Express 4 or 5 and also serve a bare Node server.\n//\n// What changed from 4.1: the registry's `principal` hook decides who a bearer\n// token stands for, and a request without one is anonymous (only `\"public\"`\n// methods and custom tools pass) where 4.1 refused it; a failure answers\n// with its error code's HTTP status and `{ success: false, error, code,\n// data? }` where 4.1 answered 500 and `{ error }`; `invoke` needs\n// `Content-Type: application/json`, as every HTTP transport call does; and a\n// client that goes away cancels its call. Each request is a session of its\n// own, and its queries share the lane of its caller: its bearer token, its\n// user without a token, or its address when anonymous (`lanes.ts`). A\n// request from a web page is refused unless `allowedOrigins` lists its\n// origin, and with `allowedHosts` a request for another `Host`\n// (`httpRequest.ts`).\n\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\nimport {\n httpStatus,\n INTERNAL_MESSAGE,\n QuickdrawError,\n toWire,\n type ErrorCode,\n} from \"../../protocol/errors\";\nimport { describeError } from \"../pipeline/metrics\";\nimport { unreadable } from \"../transports/ack\";\nimport { isJsonRequest, readJsonInput, type HttpRequest } from \"../transports/body\";\nimport type { HttpRouter } from \"../transports/http\";\nimport { requestGate, requestOf, type AllowedOrigin, type RequestGate } from \"./httpRequest\";\nimport type { McpRegistry } from \"./registry\";\nimport type { McpCallOptions, McpCallResult } from \"./types\";\n\n/** Options of {@link createMcpHttpRouter}. */\nexport interface McpHttpRouterOptions {\n /** The tools to serve. */\n readonly registry: McpRegistry;\n /** The prefix of the routes: `GET {path}/tools` and `POST {path}/invoke`. Default `\"/mcp\"`, as in 4.1. */\n readonly path?: string;\n /**\n * The largest request body read, in bytes. Default 1 MiB. A body the app's\n * own JSON parser already read (`express.json()`) is used as it is.\n */\n readonly maxBodyBytes?: number;\n /** Default: the console. */\n readonly logger?: Logger;\n /**\n * The web pages that may call the routes, by origin: exact origins\n * (`\"https://app.example.com\"`) or patterns anchored with `^` and `$`, as\n * `socketAuth` takes them. A request whose `Origin` is not listed gets 403;\n * a request without one (an MCP client, a script) is not a page's and\n * passes. Default: none, so no page may call them.\n */\n readonly allowedOrigins?: readonly AllowedOrigin[];\n /**\n * The `Host` names the routes answer for (`\"localhost\"`, `\"127.0.0.1\"`,\n * `\"mcp.example.com:8443\"`; an entry without a port matches any port): a\n * request for another gets 403. Set it for a server on a developer's\n * machine or a LAN, where a page could reach it through DNS rebinding.\n * Default: any host.\n */\n readonly allowedHosts?: readonly string[];\n}\n\n/** What `invoke` answers: 4.1's `{ success, data }`, or a failure's message, code and data. */\nexport type McpHttpReply =\n | { readonly success: true; readonly data: unknown }\n | {\n readonly success: false;\n readonly error: string;\n readonly code: ErrorCode;\n readonly data?: unknown;\n };\n\ninterface Settings {\n readonly registry: McpRegistry;\n readonly prefix: string;\n readonly maxBodyBytes: number;\n readonly logger: Logger;\n readonly gate: RequestGate;\n}\n\n/** What an `invoke` body names: any tool by name, or a method's tool by service and method. */\ntype Target =\n | { readonly kind: \"tool\"; readonly name: string; readonly args: unknown }\n | {\n readonly kind: \"method\";\n readonly service: string;\n readonly method: string;\n readonly input: unknown;\n };\n\nconst DEFAULT_MAX_BODY_BYTES = 1_048_576;\nconst CATEGORY = \"quickdraw.mcp\";\nconst NOT_JSON = \"Send the call as a JSON body with Content-Type: application/json\";\nconst NO_TARGET =\n \"Send { name, arguments } to call a tool, or { service, method, payload } to call a method's tool\";\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction failure(error: QuickdrawError): McpCallResult {\n return { ok: false, error };\n}\n\nfunction replyOf(result: McpCallResult): [number, McpHttpReply] {\n if (result.ok) {\n return [200, { success: true, data: result.data }];\n }\n const { code, message, data } = toWire(result.error);\n const reply = { success: false as const, error: message, code };\n return [httpStatus(code), data === undefined ? reply : { ...reply, data }];\n}\n\n/** Writes a JSON body, unless the response already ended; returns its size in bytes. */\nfunction send(res: ServerResponse, status: number, body: string): number | undefined {\n if (res.headersSent || res.writableEnded || res.destroyed) {\n return undefined;\n }\n const bytes = Buffer.byteLength(body);\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json; charset=utf-8\");\n res.setHeader(\"content-length\", bytes);\n // As on `/qd`: a caller's data is never cached, nor read as anything but JSON (TRANSPORT-3).\n res.setHeader(\"cache-control\", \"no-store\");\n res.setHeader(\"x-content-type-options\", \"nosniff\");\n res.end(body);\n return bytes;\n}\n\nfunction sendResult(\n settings: Settings,\n res: ServerResponse,\n result: McpCallResult,\n): number | undefined {\n const [status, reply] = replyOf(result);\n let body: string;\n try {\n body = JSON.stringify(reply);\n } catch (error) {\n settings.logger.error(\n \"An MCP call's reply could not be encoded; it was answered with INTERNAL\",\n {\n category: CATEGORY,\n error: describeError(error),\n },\n );\n const [internal, fallback] = replyOf(failure(new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE)));\n return send(res, internal, JSON.stringify(fallback));\n }\n return send(res, status, body);\n}\n\nfunction routeOf(req: IncomingMessage, prefix: string): \"tools\" | \"invoke\" | undefined {\n const path = (req.url ?? \"\").split(\"?\", 1)[0] ?? \"\";\n if (req.method === \"GET\" && path === `${prefix}/tools`) {\n return \"tools\";\n }\n return req.method === \"POST\" && path === `${prefix}/invoke` ? \"invoke\" : undefined;\n}\n\nfunction targetOf(body: unknown): Target | undefined {\n if (!isRecord(body)) {\n return undefined;\n }\n if (typeof body.name === \"string\") {\n return { kind: \"tool\", name: body.name, args: body.arguments };\n }\n if (typeof body.service === \"string\" && typeof body.method === \"string\") {\n return { kind: \"method\", service: body.service, method: body.method, input: body.payload };\n }\n return undefined;\n}\n\nasync function invoke(settings: Settings, req: HttpRequest, res: ServerResponse): Promise<void> {\n const controller = new AbortController();\n // `req` closes once its body was read; `res` closes when the client leaves.\n res.once(\"close\", () => {\n if (!res.writableFinished) {\n controller.abort();\n }\n });\n if (!isJsonRequest(req)) {\n sendResult(settings, res, failure(unreadable(NOT_JSON)));\n return;\n }\n let body: unknown;\n try {\n body = await readJsonInput(req, settings.maxBodyBytes);\n } catch (error) {\n const reason =\n error instanceof QuickdrawError ? error : unreadable(\"The request body could not be read\");\n sendResult(settings, res, failure(reason));\n return;\n }\n const target = targetOf(body);\n if (target === undefined) {\n sendResult(settings, res, failure(unreadable(NO_TARGET)));\n return;\n }\n const options: McpCallOptions = {\n request: requestOf(req),\n signal: controller.signal,\n respond: (result) => sendResult(settings, res, result),\n };\n await (target.kind === \"tool\"\n ? settings.registry.call(target.name, target.args, options)\n : settings.registry.callMethod(target.service, target.method, target.input, options));\n}\n\n/** `\"/mcp/\"` and `\"mcp\"` become `\"/mcp\"`; `\"/\"` becomes `\"\"`, serving `/tools` and `/invoke`. */\nfunction normalizePath(path: string): string {\n const trimmed = path.replace(/^\\/+|\\/+$/g, \"\");\n return trimmed === \"\" ? \"\" : `/${trimmed}`;\n}\n\nfunction resolveSettings(options: McpHttpRouterOptions): Settings {\n if (typeof options !== \"object\" || options === null || !isRecord(options.registry)) {\n throw new TypeError(\"createMcpHttpRouter: registry must come from createMcpRegistry\");\n }\n const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;\n if (!Number.isSafeInteger(maxBodyBytes) || maxBodyBytes < 1) {\n throw new TypeError(\n \"createMcpHttpRouter: maxBodyBytes must be a whole number of bytes, 1 or more\",\n );\n }\n return {\n registry: options.registry,\n prefix: normalizePath(options.path ?? \"/mcp\"),\n maxBodyBytes,\n logger: options.logger ?? consoleLogger,\n gate: requestGate(options.allowedOrigins, options.allowedHosts),\n };\n}\n\n/**\n * Serves `registry`'s tools over HTTP: `GET /mcp/tools` lists them (the\n * same list for every caller: it is not filtered by the principal), and\n * `POST /mcp/invoke` calls one with `{ name, arguments }`, or a method's\n * tool with 4.1's `{ service, method, payload }`, as the bearer token's\n * principal. Mount it with `app.use(router)` on Express 4 or 5, or pass it to\n * `http.createServer`. A request it does not serve goes to `next`, or gets a\n * 404 when there is no `next`.\n *\n * @example\n * app.use(createMcpHttpRouter({ registry }));\n */\nexport function createMcpHttpRouter(options: McpHttpRouterOptions): HttpRouter {\n const settings = resolveSettings(options);\n return (req, res, next) => {\n const route = routeOf(req, settings.prefix);\n if (route === undefined) {\n if (next === undefined) {\n sendResult(settings, res, failure(new QuickdrawError(\"NOT_FOUND\", \"Not found\")));\n } else {\n next();\n }\n return;\n }\n const refusal = settings.gate.refusal(req);\n if (refusal !== undefined) {\n settings.logger.debug(\"An MCP HTTP request was refused\", {\n category: CATEGORY,\n origin: req.headers.origin,\n host: req.headers.host,\n });\n sendResult(settings, res, failure(new QuickdrawError(\"FORBIDDEN\", refusal)));\n return;\n }\n if (route === \"tools\") {\n send(res, 200, JSON.stringify({ tools: settings.registry.tools }));\n return;\n }\n invoke(settings, req, res).catch((error: unknown) => {\n settings.logger.error(\"The MCP HTTP routes failed to serve a call\", {\n category: CATEGORY,\n error: describeError(error),\n });\n sendResult(settings, res, failure(new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE)));\n });\n };\n}\n"],"mappings":"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","names":["entry","parse","isRecord","isRecord","entry","CATEGORY","isRecord","callTool","openSession","resolve","randomUUID","randomUUID","entry","CATEGORY","isRecord","failure","reply"]}