@haddowg/json-api-mcp 1.4.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haddowg/json-api-mcp",
3
- "version": "1.4.2",
3
+ "version": "1.6.0",
4
4
  "description": "MCP tool definitions and a call handler for a JSON:API server, served from a model generated at build time from its OpenAPI document.",
5
5
  "license": "MIT",
6
6
  "author": "Gregory Haddow (https://github.com/haddowg)",
@@ -58,10 +58,10 @@
58
58
  "provenance": true
59
59
  },
60
60
  "dependencies": {
61
- "@haddowg/json-api-client": "^1.10.1"
61
+ "@haddowg/json-api-client": "^1.11.0"
62
62
  },
63
63
  "peerDependencies": {
64
- "@haddowg/json-api-codegen": "^1.15.1"
64
+ "@haddowg/json-api-codegen": "^1.17.0"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "@haddowg/json-api-codegen": {
@@ -71,7 +71,7 @@
71
71
  "devDependencies": {
72
72
  "@modelcontextprotocol/sdk": "^1.32.0",
73
73
  "ajv": "^8.20.0",
74
- "@haddowg/json-api-codegen": "^1.15.1"
74
+ "@haddowg/json-api-codegen": "^1.17.0"
75
75
  },
76
76
  "scripts": {
77
77
  "build": "tsdown",
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-yf5Kc4Yh.mjs","names":[],"sources":["../src/openapi.ts","../src/outputs.ts","../src/portable.ts","../src/inputs.ts","../src/names.ts","../src/safety.ts","../src/scopes.ts","../src/catalogue.ts","../src/contract.ts","../src/model.ts","../src/build.ts","../src/generate.ts"],"sourcesContent":["/**\n * The parts of an OpenAPI 3.1 document this package reads, typed loosely: every object keeps its\n * other members, vendor extensions included, so hooks see the operation as the server wrote it.\n */\n\n/** A JSON Schema node as the document writes it. */\nexport type JsonSchema = { [key: string]: unknown }\n\n/** One security requirement: scheme name to the scopes it needs. */\nexport type SecurityRequirement = Readonly<Record<string, readonly string[]>>\n\nexport interface ParameterObject {\n name: string\n in: string\n description?: string\n required?: boolean\n schema?: JsonSchema\n [key: string]: unknown\n}\n\nexport interface MediaTypeObject {\n schema?: JsonSchema\n [key: string]: unknown\n}\n\nexport interface RequestBodyObject {\n description?: string\n required?: boolean\n content?: Record<string, MediaTypeObject>\n [key: string]: unknown\n}\n\nexport interface ResponseObject {\n description?: string\n content?: Record<string, MediaTypeObject>\n [key: string]: unknown\n}\n\nexport interface OperationObject {\n operationId?: string\n summary?: string\n description?: string\n parameters?: (ParameterObject | { $ref: string })[]\n requestBody?: RequestBodyObject | { $ref: string }\n responses?: Record<string, ResponseObject | { $ref: string }>\n security?: SecurityRequirement[]\n [key: string]: unknown\n}\n\nexport type HttpMethod = 'get' | 'post' | 'patch' | 'put' | 'delete'\n\nexport const HTTP_METHODS: readonly HttpMethod[] = ['get', 'post', 'patch', 'put', 'delete']\n\nexport type PathItemObject = Partial<Record<HttpMethod, OperationObject>> & {\n parameters?: (ParameterObject | { $ref: string })[]\n [key: string]: unknown\n}\n\nexport interface OpenApiDocument {\n openapi?: string\n info?: { 'x-generator'?: { contract?: unknown; [key: string]: unknown }; [key: string]: unknown }\n servers?: { url: string; [key: string]: unknown }[]\n paths?: Record<string, PathItemObject>\n components?: {\n schemas?: Record<string, JsonSchema>\n parameters?: Record<string, ParameterObject>\n requestBodies?: Record<string, RequestBodyObject>\n responses?: Record<string, ResponseObject>\n [key: string]: unknown\n }\n security?: SecurityRequirement[]\n [key: string]: unknown\n}\n\nexport const isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** Follow a local `#/...` reference. `undefined` for anything else or a dangling one. */\nexport function resolvePointer(doc: OpenApiDocument, ref: string): unknown {\n if (!ref.startsWith('#/')) {\n return undefined\n }\n let node: unknown = doc\n for (const raw of ref.slice(2).split('/')) {\n const segment = decodeURIComponent(raw).replace(/~1/g, '/').replace(/~0/g, '~')\n if (!isObject(node) || !Object.hasOwn(node, segment)) {\n return undefined\n }\n node = node[segment]\n }\n return node\n}\n\n/** Follow `$ref`s until a node that isn't one. A cycle or dangling ref gives `undefined`. */\nexport function deref<T>(\n doc: OpenApiDocument,\n value: T | { $ref: string } | undefined,\n): T | undefined {\n let node: unknown = value\n const seen = new Set<string>()\n while (isObject(node) && typeof node['$ref'] === 'string') {\n const ref = node['$ref']\n if (seen.has(ref)) {\n return undefined\n }\n seen.add(ref)\n node = resolvePointer(doc, ref)\n }\n return node as T | undefined\n}\n\n/** An operation's parameters, path-level ones included, with refs followed. */\nexport function operationParameters(\n doc: OpenApiDocument,\n item: PathItemObject,\n op: OperationObject,\n): ParameterObject[] {\n const out = new Map<string, ParameterObject>()\n for (const raw of [...(item.parameters ?? []), ...(op.parameters ?? [])]) {\n const param = deref<ParameterObject>(doc, raw)\n if (param !== undefined && typeof param.name === 'string') {\n out.set(`${param.in}:${param.name}`, param)\n }\n }\n return [...out.values()]\n}\n","/**\n * Each tool's output schema, generated from the descriptor and the document's resource schemas.\n * Output schemas aren't held to the portable subset inputs are: the model only reads them.\n */\nimport { type ApiDescriptor, isPolymorphic } from '@haddowg/json-api-client'\nimport {\n deref,\n isObject,\n type JsonSchema,\n type OpenApiDocument,\n type OperationObject,\n type ResponseObject,\n resolvePointer,\n} from './openapi'\n\ntype ObjectSchema = JsonSchema & { type: 'object' }\n\nconst DROPPED = new Set(['example', 'examples', 'x-enum-varnames'])\n\n/** A document schema with refs inlined, examples dropped and any cycle cut to `{}`. */\nexport function outputSchema(\n doc: OpenApiDocument,\n value: unknown,\n stack: readonly string[] = [],\n): JsonSchema {\n if (!isObject(value)) {\n return value === false ? { not: {} } : {}\n }\n if (typeof value['$ref'] === 'string') {\n const ref = value['$ref']\n if (stack.includes(ref)) {\n return {}\n }\n const { $ref: _ref, ...siblings } = value\n const target = outputSchema(doc, resolvePointer(doc, ref), [...stack, ref])\n return { ...target, ...outputSchema(doc, siblings, stack) }\n }\n const out: JsonSchema = {}\n for (const [key, member] of Object.entries(value)) {\n if (DROPPED.has(key)) {\n continue\n }\n if (key === 'properties' && isObject(member)) {\n const props: Record<string, JsonSchema> = {}\n for (const [name, prop] of Object.entries(member)) {\n props[name] = outputSchema(doc, prop, stack)\n }\n out[key] = props\n } else if (\n (key === 'items' || key === 'additionalProperties' || key === 'not') &&\n isObject(member)\n ) {\n out[key] = outputSchema(doc, member, stack)\n } else if ((key === 'allOf' || key === 'anyOf' || key === 'oneOf') && Array.isArray(member)) {\n out[key] = member.map((m) => outputSchema(doc, m, stack))\n } else {\n out[key] = member\n }\n }\n return out\n}\n\n/** Index the document's resource object schemas by their type, preferring `<Type>Resource`. */\nexport function resourceSchemas(doc: OpenApiDocument): Map<string, JsonSchema> {\n const out = new Map<string, JsonSchema>()\n const entries = Object.entries(doc.components?.schemas ?? {})\n const ordered = [\n ...entries.filter(([name]) => name.endsWith('Resource')),\n ...entries.filter(([name]) => !name.endsWith('Resource')),\n ]\n for (const [, schema] of ordered) {\n const props = isObject(schema['properties']) ? schema['properties'] : undefined\n const typeConst = isObject(props?.['type']) ? props['type']['const'] : undefined\n const describesFields =\n props?.['attributes'] !== undefined || props?.['relationships'] !== undefined\n if (typeof typeConst === 'string' && describesFields && !out.has(typeConst)) {\n out.set(typeConst, schema)\n }\n }\n return out\n}\n\n/** Every type an `include` path can reach from the primary types, the primary types included. */\nexport function reachableTypes(\n descriptor: ApiDescriptor,\n primary: readonly string[],\n paths: readonly string[],\n): Set<string> {\n const out = new Set(primary)\n for (const path of paths) {\n let current = [...primary]\n for (const segment of path.split('.')) {\n const next: string[] = []\n for (const type of current) {\n for (const related of descriptor[type]?.relations[segment]?.types ?? []) {\n out.add(related)\n next.push(related)\n }\n }\n current = next\n }\n }\n return out\n}\n\n/** The include paths no more than `depth` relationships deep; all of them when `depth` is null. */\nexport function capIncludePaths(paths: readonly string[], depth: number | null): string[] {\n return depth === null ? [...paths] : paths.filter((path) => path.split('.').length <= depth)\n}\n\n/** The include paths an operation's `include` parameter lists. */\nexport function includePaths(doc: OpenApiDocument, op: OperationObject): string[] {\n for (const raw of op.parameters ?? []) {\n const param = deref<{ name?: string; schema?: JsonSchema }>(doc, raw)\n if (param?.name === 'include') {\n const items = deref<JsonSchema>(doc, param.schema?.['items'] as JsonSchema | undefined)\n return Array.isArray(items?.['enum']) ? (items['enum'] as string[]) : []\n }\n }\n return []\n}\n\nconst ref = (type: string): JsonSchema => ({ $ref: `#/$defs/${type}` })\n\n/** Links every resource may carry, which a flattened resource leaves out. */\nconst GENERIC_LINKS = new Set(['self', 'related', 'describedby'])\n\n/** The members a flattened link keeps. */\nconst LINK_MEMBERS = ['href', 'type', 'title', 'meta'] as const\n\n/**\n * The links a resource schema names: its declared links and its action links. From generator\n * contract 18 they're the properties of the `<Type>ResourceLinks` component's own `allOf`\n * member; before, they sit beside `self` in its properties.\n */\nfunction namedLinkSchemas(\n doc: OpenApiDocument,\n resource: JsonSchema | undefined,\n): [string, JsonSchema][] {\n const props = isObject(resource?.['properties']) ? resource['properties'] : {}\n const component = deref<JsonSchema>(doc, props['links'] as JsonSchema | undefined)\n if (!isObject(component)) {\n return []\n }\n const own = isObject(component['properties']) ? Object.entries(component['properties']) : []\n const extended = (Array.isArray(component['allOf']) ? component['allOf'] : [])\n .filter((member): member is JsonSchema => isObject(member) && member['$ref'] === undefined)\n .flatMap((member) =>\n isObject(member['properties']) ? Object.entries(member['properties']) : [],\n )\n return [...own, ...extended].filter(\n (entry): entry is [string, JsonSchema] => !GENERIC_LINKS.has(entry[0]) && isObject(entry[1]),\n )\n}\n\nconst hasHref = (s: unknown): s is JsonSchema =>\n isObject(s) && isObject(s['properties']) && s['properties']['href'] !== undefined\n\n/** The link object branch of a link schema: the schema itself, or its `anyOf` branch with `href`. */\nfunction linkObjectSchema(schema: JsonSchema): JsonSchema | undefined {\n if (hasHref(schema)) {\n return schema\n }\n return (Array.isArray(schema['anyOf']) ? schema['anyOf'] : []).find(hasHref)\n}\n\n/**\n * One named link as a flattened resource carries it: `{ href, type?, title?, meta? }`, typed from\n * the document's link schema, meta members included. A link the server renders as a bare URL is\n * normalised to `{ href }`.\n */\nfunction linkOutput(doc: OpenApiDocument, schema: JsonSchema): JsonSchema {\n const resolved = outputSchema(doc, schema)\n const object = linkObjectSchema(resolved)\n const source = isObject(object?.['properties']) ? object['properties'] : {}\n const properties: Record<string, JsonSchema> = {\n href: { type: 'string', format: 'uri-reference' },\n }\n for (const member of LINK_MEMBERS) {\n const value = source[member]\n if (isObject(value)) {\n properties[member] = member === 'href' ? { ...properties['href'], ...value } : value\n }\n }\n const declared = Array.isArray(object?.['required']) ? (object['required'] as string[]) : []\n const out: JsonSchema = {\n type: 'object',\n properties,\n required: ['href', ...declared.filter((name) => name !== 'href' && name in properties)],\n }\n if (typeof resolved['description'] === 'string') {\n out['description'] = resolved['description']\n }\n return out\n}\n\n/**\n * The names of the links each type names, for the types that name any. Throws when such a type\n * also has an attribute or relationship called `links`, which the flattened resource couldn't\n * hold beside them.\n */\nexport function resourceLinkNames(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n schemas: Map<string, JsonSchema>,\n): Record<string, string[]> {\n const out: Record<string, string[]> = {}\n for (const [type, resource] of Object.entries(descriptor)) {\n const names = namedLinkSchemas(doc, schemas.get(type)).map(([name]) => name)\n if (names.length === 0) {\n continue\n }\n if ('links' in resource.attributes || 'links' in resource.relations) {\n throw new Error(\n `The \"${type}\" type names links (${names.join(', ')}) and also has a field called \"links\". A flattened resource carries its links under \"links\", so rename the field.`,\n )\n }\n out[type] = names\n }\n return out\n}\n\n/** One type's flattened resource schema: id, type, attributes, relations and named links, all optional but id and type. */\nfunction flatResource(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n schemas: Map<string, JsonSchema>,\n type: string,\n expanded: ReadonlySet<string>,\n): JsonSchema {\n const resource = schemas.get(type)\n const resourceProps = isObject(resource?.['properties']) ? resource['properties'] : {}\n const attributes = outputSchema(doc, resourceProps['attributes'])\n const properties: Record<string, JsonSchema> = {\n id: { type: 'string' },\n type: { type: 'string', const: type },\n }\n if (isObject(attributes['properties'])) {\n Object.assign(properties, attributes['properties'])\n }\n for (const [name, relation] of Object.entries(descriptor[type]?.relations ?? {})) {\n if (relation.writeOnly === true) {\n continue\n }\n const polymorphic = isPolymorphic(relation)\n const identifier: JsonSchema = polymorphic\n ? {\n type: 'object',\n properties: {\n type: { type: 'string', enum: [...relation.types] },\n id: { type: 'string' },\n },\n required: ['type', 'id'],\n }\n : { type: 'string' }\n const full = relation.types.filter((t) => expanded.has(t)).map(ref)\n const member = full.length === 0 ? identifier : { anyOf: [identifier, ...full] }\n const target = relation.types.join(' or ')\n properties[name] =\n relation.cardinality === 'many'\n ? {\n type: 'array',\n items: member,\n description: `The related ${target} resources: ${polymorphic ? 'type and id' : 'ids'}, or the resources themselves when included.`,\n }\n : {\n anyOf: [\n ...(full.length === 0 ? [identifier] : [identifier, ...full]),\n { type: 'null' },\n ],\n description: `The related ${target}: ${polymorphic ? 'its type and id' : 'its id'}, or the resource itself when included.`,\n }\n }\n const links = namedLinkSchemas(doc, resource)\n if (links.length > 0) {\n properties['links'] = {\n type: 'object',\n description:\n 'The links the resource names, such as an upload or download URL or a custom action. A link that does not apply to this resource is absent.',\n properties: Object.fromEntries(links.map(([name, link]) => [name, linkOutput(doc, link)])),\n }\n }\n const schema: JsonSchema = { type: 'object', properties, required: ['id', 'type'] }\n if (typeof resource?.['description'] === 'string') {\n schema['description'] = resource['description']\n }\n return schema\n}\n\nfunction defsFor(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n schemas: Map<string, JsonSchema>,\n types: ReadonlySet<string>,\n): Record<string, JsonSchema> {\n const defs: Record<string, JsonSchema> = {}\n for (const type of types) {\n defs[type] = flatResource(doc, descriptor, schemas, type, types)\n }\n return defs\n}\n\nexport interface OutputContext {\n doc: OpenApiDocument\n descriptor: ApiDescriptor\n schemas: Map<string, JsonSchema>\n operation: OperationObject\n /** The include paths the tool may ask for, already capped at the model's include depth. */\n includes: readonly string[]\n}\n\n/** The `meta` schema a success response declares, else a free-form object. */\nfunction responseMeta(ctx: OutputContext): JsonSchema {\n for (const [status, raw] of Object.entries(ctx.operation.responses ?? {})) {\n if (!status.startsWith('2')) continue\n const response = deref<ResponseObject>(ctx.doc, raw)\n const schema = deref<JsonSchema>(\n ctx.doc,\n response?.content?.['application/vnd.api+json']?.schema,\n )\n const meta = isObject(schema?.['properties']) ? schema['properties']['meta'] : undefined\n if (meta !== undefined) {\n return outputSchema(ctx.doc, meta)\n }\n }\n return { type: 'object' }\n}\n\nconst LINKS: JsonSchema = {\n type: 'object',\n description:\n 'Pagination links. Pass one to this tool as `pageLink` to fetch that page; a missing link means there is no such page.',\n properties: {\n first: { type: 'string' },\n prev: { type: 'string' },\n next: { type: 'string' },\n last: { type: 'string' },\n },\n}\n\n/** The document `meta` member of an envelope: what the response declares, when it sends any. */\nfunction documentMeta(ctx: OutputContext, description: string): JsonSchema {\n return { ...responseMeta(ctx), description }\n}\n\n/** A collection: `{ data, links, meta? }`. */\nexport function collectionOutput(ctx: OutputContext, types: readonly string[]): ObjectSchema {\n const reachable = reachableTypes(ctx.descriptor, types, ctx.includes)\n const items = types.length === 1 ? ref(types[0]!) : { anyOf: types.map(ref) }\n return {\n type: 'object',\n properties: {\n data: { type: 'array', items, description: 'The resources on this page.' },\n links: LINKS,\n meta: documentMeta(ctx, 'The document meta, such as page totals.'),\n },\n required: ['data', 'links'],\n $defs: defsFor(ctx.doc, ctx.descriptor, ctx.schemas, reachable),\n }\n}\n\n/**\n * One resource: `{ data, meta? }`. `data` is null where the operation may find nothing, such as\n * a to-one related read with nothing related.\n */\nexport function resourceOutput(\n ctx: OutputContext,\n types: readonly string[],\n nullable: string | false = false,\n): ObjectSchema {\n const reachable = reachableTypes(ctx.descriptor, types, ctx.includes)\n const data: JsonSchema =\n nullable !== false\n ? { anyOf: [...types.map(ref), { type: 'null' }], description: nullable }\n : types.length === 1\n ? { ...ref(types[0]!), description: 'The resource.' }\n : { anyOf: types.map(ref), description: 'The resource.' }\n return {\n type: 'object',\n properties: {\n data,\n meta: documentMeta(ctx, 'The document meta, when the API sends any.'),\n },\n required: ['data'],\n $defs: defsFor(ctx.doc, ctx.descriptor, ctx.schemas, reachable),\n }\n}\n\n/** A delete: `{ data: null, meta? }`. */\nexport function deletedOutput(ctx: OutputContext): ObjectSchema {\n return {\n type: 'object',\n properties: {\n data: { type: 'null', description: 'Always null: the resource is gone.' },\n meta: documentMeta(ctx, 'The document meta, when the API sends any.'),\n },\n required: ['data'],\n }\n}\n\n/** A meta-only result: `{ meta }`, the document's own `meta`, with no `data`. */\nexport function metaOutput(ctx: OutputContext): ObjectSchema {\n return {\n type: 'object',\n properties: {\n meta: { ...responseMeta(ctx), type: 'object', description: 'The document meta.' },\n },\n required: ['meta'],\n }\n}\n\n/** A JSON:API result whose primary type the descriptor doesn't name. */\nexport const LOOSE_OUTPUT: ObjectSchema = {\n type: 'object',\n properties: {\n data: { description: 'The flattened resource or resources.' },\n links: LINKS,\n meta: { type: 'object', description: 'The document meta, when the API sends any.' },\n },\n}\n\n/** The URL an action answered with (generator contract 17): `{ url, type, expiresAt? }`. */\nfunction locationData(mediaType: string): JsonSchema {\n return {\n type: 'object',\n description:\n 'The URL the action produced, such as a short-lived download link. The tool does not fetch it.',\n properties: {\n url: { type: 'string', format: 'uri-reference', description: 'The URL.' },\n type: {\n type: 'string',\n description: `The media type the URL serves. The action declares \\`${mediaType}\\`.`,\n },\n expiresAt: {\n type: 'string',\n format: 'date-time',\n description: 'When the URL stops working. Absent when it does not expire.',\n },\n },\n required: ['url', 'type'],\n additionalProperties: false,\n }\n}\n\n/** An action that answered with a URL: `{ data: { url, type, expiresAt? } }`. */\nexport function locationOutput(mediaType: string): ObjectSchema {\n return {\n type: 'object',\n properties: { data: locationData(mediaType) },\n required: ['data'],\n }\n}\n\n/** An action's usual output or the URL it may answer with instead, sharing the root `$defs`. */\nexport function orLocation(schema: JsonSchema, mediaType: string): ObjectSchema {\n const { $defs, ...rest } = schema\n return {\n type: 'object',\n anyOf: [rest, locationOutput(mediaType)],\n ...($defs === undefined ? {} : { $defs }),\n }\n}\n","/**\n * Convert document schemas into tool input schemas every major model API accepts: OpenAI's strict\n * function calling and Anthropic's strict tool use. That means no `oneOf`, `allOf`, `if`, `then`\n * or `$ref`, every object closed with `additionalProperties: false` and listing all its\n * properties as required, an optional property made nullable instead, and no numeric, length or\n * pattern keywords. Constraints that can't stay as keywords move into the description, and a\n * value with no portable shape, such as a free-form object, is taken as JSON text.\n *\n * Each schema comes with a {@link Decoder} that turns the arguments a model sends back into the\n * value the API expects: a `null` the conversion added is dropped, and JSON text is parsed.\n */\nimport { isObject, type JsonSchema, type OpenApiDocument, resolvePointer } from './openapi'\n\n/** The string formats both APIs accept. */\nexport const PORTABLE_FORMATS: ReadonlySet<string> = new Set([\n 'date-time',\n 'time',\n 'date',\n 'duration',\n 'email',\n 'hostname',\n 'ipv4',\n 'ipv6',\n 'uuid',\n])\n\n/** Objects may nest this deep before a value is taken as JSON text instead. */\nconst MAX_DEPTH = 6\n\nexport type Decoder =\n | { kind: 'value' }\n | { kind: 'json' }\n | { kind: 'object'; props: Readonly<Record<string, PropertyDecoder>> }\n | { kind: 'array'; items: Decoder }\n\nexport interface PropertyDecoder {\n decoder: Decoder\n /** The conversion made this property nullable, so `null` means \"not given\". */\n nullMeansOmit: boolean\n}\n\nexport interface Portable {\n schema: JsonSchema\n decoder: Decoder\n}\n\nconst VALUE: Decoder = { kind: 'value' }\n\n/** Thrown when a model's argument can't be decoded, such as JSON text that doesn't parse. */\nexport class ArgumentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ArgumentError'\n }\n}\n\n/** Turn a model's argument back into the value the API expects. */\nexport function decode(value: unknown, decoder: Decoder, path = 'value'): unknown {\n if (value === null || value === undefined) {\n return value\n }\n switch (decoder.kind) {\n case 'json':\n if (typeof value !== 'string') {\n return value\n }\n try {\n return JSON.parse(value) as unknown\n } catch {\n throw new ArgumentError(`${path} must be JSON text`)\n }\n case 'array':\n return Array.isArray(value)\n ? value.map((item, index) => decode(item, decoder.items, `${path}[${index}]`))\n : value\n case 'object': {\n if (!isObject(value)) {\n return value\n }\n const out: Record<string, unknown> = {}\n for (const [key, member] of Object.entries(value)) {\n const prop = decoder.props[key]\n if (prop === undefined) {\n out[key] = member\n } else if (!(member === null && prop.nullMeansOmit)) {\n out[key] = decode(member, prop.decoder, `${path}.${key}`)\n }\n }\n return out\n }\n default:\n return value\n }\n}\n\n/** Add `null` to a portable schema's allowed values. */\nexport function nullable(schema: JsonSchema): JsonSchema {\n const out = { ...schema }\n if (Array.isArray(out['anyOf'])) {\n const branches = out['anyOf'] as JsonSchema[]\n if (!branches.some((b) => b['type'] === 'null')) {\n out['anyOf'] = [...branches, { type: 'null' }]\n }\n return out\n }\n const type = out['type']\n if (typeof type === 'string' && type !== 'null') {\n out['type'] = [type, 'null']\n } else if (Array.isArray(type) && !type.includes('null')) {\n out['type'] = [...(type as string[]), 'null']\n }\n if (Array.isArray(out['enum']) && !(out['enum'] as unknown[]).includes(null)) {\n out['enum'] = [...(out['enum'] as unknown[]), null]\n }\n return out\n}\n\n/** Whether a portable schema already allows `null`. */\nexport function allowsNull(schema: JsonSchema): boolean {\n const type = schema['type']\n if (type === 'null' || (Array.isArray(type) && type.includes('null'))) {\n return true\n }\n return Array.isArray(schema['anyOf']) && (schema['anyOf'] as JsonSchema[]).some(allowsNull)\n}\n\n/** A closed object schema listing every property as required, as strict mode wants. */\nexport function closedObject(\n properties: Record<string, JsonSchema>,\n description?: string,\n): JsonSchema {\n const schema: JsonSchema = {\n type: 'object',\n properties,\n required: Object.keys(properties),\n additionalProperties: false,\n }\n if (description !== undefined && description !== '') {\n schema['description'] = description\n }\n return schema\n}\n\nconst jsonText = (description: string | undefined): Portable => ({\n schema: {\n type: 'string',\n description: joinText(description, 'Send the value as JSON text.'),\n },\n decoder: { kind: 'json' },\n})\n\nfunction joinText(...parts: (string | undefined)[]): string {\n return parts\n .filter((part): part is string => part !== undefined && part.trim() !== '')\n .map((part) => part.trim())\n .join(' ')\n}\n\n/** The non-null `type` keys a schema names. */\nfunction typeKeys(schema: JsonSchema): { types: string[]; nullable: boolean } {\n const raw = schema['type']\n const list = typeof raw === 'string' ? [raw] : Array.isArray(raw) ? (raw as string[]) : []\n return { types: list.filter((t) => t !== 'null'), nullable: list.includes('null') }\n}\n\nfunction inferType(values: readonly unknown[]): string | undefined {\n const types = new Set(\n values\n .filter((v) => v !== null)\n .map((v) =>\n typeof v === 'number' ? (Number.isInteger(v) ? 'integer' : 'number') : typeof v,\n ),\n )\n if (types.size === 1) {\n return [...types][0]\n }\n if (types.size === 2 && types.has('integer') && types.has('number')) {\n return 'number'\n }\n return undefined\n}\n\n/** A range as a sentence, such as `Between 1 and 200 characters.` */\nfunction bounds(\n min: number | undefined,\n max: number | undefined,\n unit: string,\n): string | undefined {\n const suffix = unit === '' ? '' : ` ${unit}`\n if (min !== undefined && max !== undefined) return `Between ${min} and ${max}${suffix}.`\n if (min !== undefined) return `At least ${min}${suffix}.`\n if (max !== undefined) return `At most ${max}${suffix}.`\n return undefined\n}\n\n/** The constraints a schema states that can't stay as keywords, as sentences. */\nfunction constraintNote(schema: JsonSchema): string | undefined {\n const num = (key: string): number | undefined =>\n typeof schema[key] === 'number' ? schema[key] : undefined\n const notes = [\n bounds(num('minLength'), num('maxLength'), 'characters'),\n bounds(num('minimum'), num('maximum'), ''),\n num('exclusiveMinimum') === undefined ? undefined : `Greater than ${num('exclusiveMinimum')}.`,\n num('exclusiveMaximum') === undefined ? undefined : `Less than ${num('exclusiveMaximum')}.`,\n num('multipleOf') === undefined ? undefined : `A multiple of ${num('multipleOf')}.`,\n bounds(num('minItems'), num('maxItems'), 'items'),\n typeof schema['pattern'] === 'string'\n ? `Matches the pattern \\`${schema['pattern']}\\`.`\n : undefined,\n typeof schema['format'] === 'string' && !PORTABLE_FORMATS.has(schema['format'])\n ? `Format: ${schema['format']}.`\n : undefined,\n schema['default'] === undefined\n ? undefined\n : `Defaults to ${JSON.stringify(schema['default'])}.`,\n ].filter((note): note is string => note !== undefined)\n return notes.length === 0 ? undefined : notes.join(' ')\n}\n\n/** Merge an `allOf` into one schema: the members' keywords, then the outer node's own. */\nfunction mergeAllOf(\n doc: OpenApiDocument,\n node: JsonSchema,\n stack: readonly string[],\n): JsonSchema | undefined {\n const members = node['allOf'] as unknown[]\n const merged: JsonSchema = {}\n const properties: Record<string, unknown> = {}\n const required = new Set<string>()\n for (const member of members) {\n const resolved = follow(doc, member, stack)\n if (resolved === undefined) {\n return undefined\n }\n const inner = Array.isArray(resolved.node['allOf'])\n ? mergeAllOf(doc, resolved.node, resolved.stack)\n : resolved.node\n if (inner === undefined) {\n return undefined\n }\n Object.assign(properties, isObject(inner['properties']) ? inner['properties'] : {})\n for (const key of Array.isArray(inner['required']) ? (inner['required'] as string[]) : []) {\n required.add(key)\n }\n Object.assign(merged, inner)\n }\n const { allOf: _allOf, ...own } = node\n Object.assign(merged, own)\n if (Object.keys(properties).length > 0) {\n merged['properties'] = {\n ...properties,\n ...(isObject(own['properties']) ? own['properties'] : {}),\n }\n }\n if (required.size > 0 || Array.isArray(own['required'])) {\n merged['required'] = [\n ...required,\n ...(Array.isArray(own['required']) ? (own['required'] as string[]) : []),\n ]\n }\n return merged\n}\n\n/**\n * Follow a node's `$ref`s, keeping the outermost description. `undefined` on a cycle, which the\n * caller then takes as JSON text.\n */\nfunction follow(\n doc: OpenApiDocument,\n value: unknown,\n stack: readonly string[],\n): { node: JsonSchema; stack: readonly string[] } | undefined {\n let node: unknown = value\n let description: string | undefined\n let path = stack\n while (isObject(node) && typeof node['$ref'] === 'string') {\n const ref = node['$ref']\n if (description === undefined && typeof node['description'] === 'string') {\n description = node['description']\n }\n if (path.includes(ref)) {\n return undefined\n }\n path = [...path, ref]\n node = resolvePointer(doc, ref)\n }\n if (node === true) {\n return { node: {}, stack: path }\n }\n if (!isObject(node)) {\n return undefined\n }\n return {\n node: description === undefined ? node : { ...node, description },\n stack: path,\n }\n}\n\nconst isNull = (b: unknown): boolean => isObject(b) && b['type'] === 'null'\n\n/** Convert one document schema into a portable input schema and its decoder. */\nexport function toPortable(\n doc: OpenApiDocument,\n raw: unknown,\n stack: readonly string[] = [],\n depth = 0,\n): Portable {\n const outerDescription =\n isObject(raw) && typeof raw['description'] === 'string' ? raw['description'] : undefined\n const followed = follow(doc, raw, stack)\n if (followed === undefined) {\n return jsonText(outerDescription)\n }\n let node = followed.node\n const path = followed.stack\n if (Array.isArray(node['allOf'])) {\n const merged = mergeAllOf(doc, node, path)\n if (merged === undefined) {\n return jsonText(outerDescription)\n }\n node = merged\n }\n const description = typeof node['description'] === 'string' ? node['description'] : undefined\n\n const branches = (node['oneOf'] ?? node['anyOf']) as unknown[] | undefined\n if (Array.isArray(branches)) {\n const { oneOf: _oneOf, anyOf: _anyOf, ...rest } = node\n const others = branches.filter((b) => !isNull(b))\n const withNull = others.length < branches.length\n if (others.length === 1) {\n const resolved = follow(doc, others[0], path)\n if (resolved === undefined) {\n return jsonText(description)\n }\n const single = toPortable(doc, { ...resolved.node, ...rest }, resolved.stack, depth)\n return withNull ? { ...single, schema: nullable(single.schema) } : single\n }\n if (depth >= MAX_DEPTH) {\n return jsonText(description)\n }\n const converted = others.map((b) => toPortable(doc, b, path, depth + 1).schema)\n const schema: JsonSchema = { anyOf: withNull ? [...converted, { type: 'null' }] : converted }\n const text = joinText(description, constraintNote(node))\n if (text !== '') {\n schema['description'] = text\n }\n return { schema, decoder: VALUE }\n }\n\n let { types, nullable: isNullable } = typeKeys(node)\n const enumValues = Array.isArray(node['enum'])\n ? (node['enum'] as unknown[])\n : node['const'] !== undefined\n ? [node['const']]\n : undefined\n if (enumValues !== undefined && enumValues.includes(null)) {\n isNullable = true\n }\n if (types.length === 0) {\n const inferred =\n enumValues !== undefined\n ? inferType(enumValues)\n : isObject(node['properties'])\n ? 'object'\n : node['items'] !== undefined\n ? 'array'\n : undefined\n if (inferred === undefined) {\n return jsonText(description)\n }\n types = [inferred]\n }\n if (types.length > 1) {\n const schema: JsonSchema = {\n anyOf: [...types.map((type) => ({ type })), ...(isNullable ? [{ type: 'null' }] : [])],\n }\n if (description !== undefined) {\n schema['description'] = description\n }\n return { schema, decoder: VALUE }\n }\n\n const type = types[0]!\n const text = joinText(description, constraintNote(node))\n let result: Portable\n\n if (type === 'object') {\n const props = isObject(node['properties']) ? node['properties'] : {}\n const writable = Object.entries(props).filter(\n ([, prop]) => !(isObject(prop) && prop['readOnly'] === true),\n )\n if (writable.length === 0 || depth >= MAX_DEPTH) {\n return jsonText(text)\n }\n const required = new Set(Array.isArray(node['required']) ? (node['required'] as string[]) : [])\n const properties: Record<string, JsonSchema> = {}\n const decoders: Record<string, PropertyDecoder> = {}\n for (const [key, prop] of writable) {\n const converted = toPortable(doc, prop, path, depth + 1)\n const optional = !required.has(key)\n const addNull = optional && !allowsNull(converted.schema)\n properties[key] = addNull ? nullable(converted.schema) : converted.schema\n decoders[key] = { decoder: converted.decoder, nullMeansOmit: addNull }\n }\n result = {\n schema: closedObject(properties, text),\n decoder: { kind: 'object', props: decoders },\n }\n } else if (type === 'array') {\n if (node['items'] === undefined || node['items'] === true || depth >= MAX_DEPTH) {\n return jsonText(text)\n }\n const items = toPortable(doc, node['items'], path, depth + 1)\n result = {\n schema: { type: 'array', items: items.schema },\n decoder: { kind: 'array', items: items.decoder },\n }\n if (text !== '') {\n result.schema['description'] = text\n }\n } else {\n const schema: JsonSchema = { type }\n if (text !== '') {\n schema['description'] = text\n }\n if (enumValues !== undefined) {\n schema['enum'] = enumValues.filter((v) => v !== null)\n }\n if (\n type === 'string' &&\n typeof node['format'] === 'string' &&\n PORTABLE_FORMATS.has(node['format'])\n ) {\n schema['format'] = node['format']\n }\n result = { schema, decoder: VALUE }\n }\n\n return isNullable ? { ...result, schema: nullable(result.schema) } : result\n}\n","/**\n * Each tool's input schema, and the plan the call handler follows to turn a model's arguments\n * back into a client call. Every schema is portable (see ./portable.ts): a parameter the API\n * doesn't require is nullable, and `null` at the top level means \"not given\".\n */\nimport {\n type ActionDescriptor,\n type ApiDescriptor,\n type CountableDescriptor,\n isPolymorphic,\n type PaginatorDescriptor,\n type RelationDescriptor,\n resolvePaginator,\n} from '@haddowg/json-api-client'\nimport {\n deref,\n isObject,\n type JsonSchema,\n type OpenApiDocument,\n type OperationObject,\n type ParameterObject,\n type RequestBodyObject,\n} from './openapi'\nimport { capIncludePaths, includePaths } from './outputs'\nimport {\n allowsNull,\n closedObject,\n type Decoder,\n nullable,\n type PropertyDecoder,\n toPortable,\n} from './portable'\n\n/** The include description, for a tool capped at `depth` relationships or uncapped. */\nexport function includeDescription(depth: number | null): string {\n const reach =\n depth === null\n ? ''\n : depth === 1\n ? ' Only direct relationships can be included, so relations of an included resource come back as ids.'\n : ` Paths reach at most ${depth} relationships deep, and relations below that come back as ids.`\n return `Relationship paths to include in the result (JSON:API compound documents). An included relation comes back as the related resource in place of its id.${reach} Leave null to include nothing.`\n}\n\nexport const FIELDS_DESCRIPTION =\n 'Sparse fieldsets (JSON:API): per resource type, the attribute and relationship names to return. A relationship only has a value in the result when it is also included. Leave a type null for its default fields.'\n\n/** The Countable profile's token for counting the collection itself. */\nexport const SELF_COUNT = '_self_'\n\nexport const WITH_COUNT_DESCRIPTION =\n 'Set true to have the total number of results counted and returned in meta. Counting can be slow on a large collection, so leave it null unless the total is needed.'\n\nexport const PAGE_LINK_DESCRIPTION =\n 'A pagination link (first, prev, next or last) copied from the links of an earlier result of this same tool, to fetch that page. When given, every other argument is ignored.'\n\n/** How the handler reads a read tool's query arguments. */\nexport interface QueryPlan {\n filter?: Decoder\n sort: boolean\n include: boolean\n /**\n * The include paths the tool accepts, the ones its input lists. A model before format 3\n * doesn't carry them and its tools accept any path.\n */\n includePaths?: readonly string[]\n fields: readonly string[]\n /** The wire key `pageSize` maps to, when the endpoint paginates by a size. */\n sizeKey?: string\n maxPageSize?: number\n defaultPageSize?: number\n /** Whether `pageLink` is offered: the endpoint paginates at all. */\n paginated: boolean\n /**\n * Whether `withCount` is offered: the endpoint counts its own collection under the Countable\n * profile, sent as `withCount=_self_` with this profile negotiated.\n */\n countProfile?: string\n}\n\n/** One top-level write field: an attribute, or a relation sent as ids. */\nexport interface WriteField {\n relation?: { cardinality: 'one' | 'many'; types: readonly string[]; polymorphic?: boolean }\n property: PropertyDecoder\n}\n\n/** How the handler reads a create, update or flat document action's arguments. */\nexport interface WritePlan {\n fields: Readonly<Record<string, WriteField>>\n /** The client id argument: whether the body takes one. */\n clientId: 'none' | 'optional' | 'required'\n /** Fields `clear` may name, for an update. */\n clearable: readonly string[]\n}\n\n/** How the handler reads a custom action's body. */\nexport type ActionBodyPlan =\n | { kind: 'none' }\n | { kind: 'flat'; write: WritePlan }\n | {\n kind: 'body'\n decoder: Decoder\n required: boolean\n /** The request media type the body goes out as. */\n mediaType: string\n mediaKind: 'document' | 'json' | 'text' | 'form'\n }\n\nexport interface ToolInput {\n schema: JsonSchema & { type: 'object' }\n query?: QueryPlan\n write?: WritePlan\n action?: ActionBodyPlan\n}\n\nconst nullableString = (description: string): JsonSchema =>\n nullable({ type: 'string', description })\n\nconst idSchema = (description: string): JsonSchema => ({ type: 'string', description })\n\n/** The `filter[...]` parameters as one closed object, each member nullable. */\nfunction filterInput(\n doc: OpenApiDocument,\n params: readonly ParameterObject[],\n): { schema: JsonSchema; decoder: Decoder } | undefined {\n const properties: Record<string, JsonSchema> = {}\n const props: Record<string, PropertyDecoder> = {}\n for (const param of params) {\n const match = /^filter\\[(.+)\\]$/.exec(param.name)\n if (param.in !== 'query' || match === null) {\n continue\n }\n const converted = toPortable(doc, param.schema ?? {}, [], 1)\n const schema = { ...converted.schema }\n if (typeof param.description === 'string' && schema['description'] === undefined) {\n schema['description'] = param.description\n } else if (typeof param.description === 'string') {\n schema['description'] = `${param.description} ${String(schema['description'])}`\n }\n const addNull = !allowsNull(schema)\n properties[match[1]!] = addNull ? nullable(schema) : schema\n props[match[1]!] = { decoder: converted.decoder, nullMeansOmit: true }\n }\n if (Object.keys(properties).length === 0) {\n return undefined\n }\n return {\n schema: nullable(\n closedObject(\n properties,\n 'Filters to apply. Leave a filter null to not apply it, or the whole object null for none.',\n ),\n ),\n decoder: { kind: 'object', props },\n }\n}\n\n/** The page parameter's size bound and default for the strategy that answers by default. */\nfunction pageBounds(\n doc: OpenApiDocument,\n params: readonly ParameterObject[],\n kind: string,\n sizeKey: string,\n): { max?: number; default?: number } {\n const param = params.find((p) => p.in === 'query' && p.name === 'page')\n let schema = deref<JsonSchema>(doc, param?.schema)\n const branches = schema?.['oneOf'] ?? schema?.['anyOf']\n if (Array.isArray(branches)) {\n schema = branches\n .map((b) => deref<JsonSchema>(doc, b as JsonSchema))\n .find((b) => isObject(b?.['x-paginator']) && b['x-paginator']['strategy'] === kind)\n }\n const size = isObject(schema?.['properties']) ? schema['properties'][sizeKey] : undefined\n if (!isObject(size)) {\n return {}\n }\n const out: { max?: number; default?: number } = {}\n if (typeof size['maximum'] === 'number') out.max = size['maximum']\n if (typeof size['default'] === 'number') out.default = size['default']\n return out\n}\n\n/** A read tool's query arguments, read from the operation's own parameters. */\nfunction queryInput(\n ctx: InputContext,\n paginator: PaginatorDescriptor | undefined,\n collection: boolean,\n): { properties: Record<string, JsonSchema>; plan: QueryPlan } {\n const { doc, params, defaultPageSize, includeDepth } = ctx\n const properties: Record<string, JsonSchema> = {}\n const plan: QueryPlan = { sort: false, include: false, fields: [], paginated: false }\n\n if (collection) {\n const filter = filterInput(doc, params)\n if (filter !== undefined) {\n properties['filter'] = filter.schema\n plan.filter = filter.decoder\n }\n const sort = params.find((p) => p.in === 'query' && p.name === 'sort')\n const sortItems = deref<JsonSchema>(doc, sort?.schema?.['items'] as JsonSchema | undefined)\n const tokens = Array.isArray(sortItems?.['enum']) ? (sortItems['enum'] as string[]) : []\n if (tokens.length > 0) {\n properties['sort'] = nullable({\n type: 'array',\n items: { type: 'string', enum: tokens },\n description:\n 'Fields to sort by, in order. A leading `-` sorts that field descending. Leave null for the default order.',\n })\n plan.sort = true\n }\n }\n\n const includable = params.some((p) => p.in === 'query' && p.name === 'include')\n const paths = includable ? capIncludePaths(includePaths(doc, ctx.operation), includeDepth) : []\n if (paths.length > 0) {\n properties['include'] = nullable({\n type: 'array',\n items: { type: 'string', enum: paths },\n description: includeDescription(includeDepth),\n })\n plan.include = true\n plan.includePaths = paths\n }\n\n const fieldTypes = params\n .map((p) => (p.in === 'query' ? /^fields\\[(.+)\\]$/.exec(p.name)?.[1] : undefined))\n .filter((t): t is string => t !== undefined)\n if (fieldTypes.length > 0) {\n const members: Record<string, JsonSchema> = {}\n for (const type of fieldTypes) {\n members[type] = nullable({ type: 'array', items: { type: 'string' } })\n }\n properties['fields'] = nullable(closedObject(members, FIELDS_DESCRIPTION))\n plan.fields = fieldTypes\n }\n\n if (collection && paginator !== undefined) {\n const resolved = resolvePaginator(paginator)\n if (resolved.kind !== 'none') {\n plan.paginated = true\n const sizeKey = resolved.keys.size ?? resolved.keys.limit\n if (sizeKey !== undefined) {\n const bounds = pageBounds(doc, params, resolved.kind, sizeKey)\n const fallback = Math.min(defaultPageSize, bounds.max ?? defaultPageSize)\n plan.sizeKey = sizeKey\n plan.defaultPageSize = fallback\n if (bounds.max !== undefined) plan.maxPageSize = bounds.max\n const range = bounds.max === undefined ? 'at least 1' : `1 to ${bounds.max}`\n properties['pageSize'] = nullable({\n type: 'integer',\n description: `How many results a page holds, ${range}. Leave null for ${fallback}.`,\n })\n }\n properties['pageLink'] = nullableString(PAGE_LINK_DESCRIPTION)\n }\n }\n\n return { properties, plan }\n}\n\n/** The `data` member's schema of a write request body. */\nfunction requestData(doc: OpenApiDocument, schema: unknown): JsonSchema | undefined {\n const body = deref<JsonSchema>(doc, schema as JsonSchema)\n const data = isObject(body?.['properties']) ? body['properties']['data'] : undefined\n return deref<JsonSchema>(doc, data as JsonSchema)\n}\n\n/** A relation's write argument: an id, ids, or `{ type, id }` objects for a polymorphic one. */\nfunction relationArgument(\n name: string,\n relation: RelationDescriptor,\n allowNull: boolean,\n): JsonSchema {\n const polymorphic = isPolymorphic(relation)\n const one: JsonSchema = polymorphic\n ? closedObject({\n type: { type: 'string', enum: [...relation.types] },\n id: { type: 'string' },\n })\n : { type: 'string' }\n const target = polymorphic ? relation.types.join(' or ') : relation.types[0]\n if (relation.cardinality === 'many') {\n return {\n type: 'array',\n items: one,\n description: polymorphic\n ? `The ${name} relationship: every related resource, as its type (${target}) and id.`\n : `The ${name} relationship: the ids of the related \\`${target}\\` resources.`,\n }\n }\n const schema: JsonSchema = {\n ...one,\n description: polymorphic\n ? `The ${name} relationship: the related resource's type (${target}) and id.`\n : `The ${name} relationship: the id of the related \\`${target}\\` resource.`,\n }\n return allowNull ? nullable(schema) : schema\n}\n\n/**\n * A flat write input from a JSON:API write request body: the attributes and relationships as\n * one object, the API's required members required, the rest nullable.\n */\nfunction writeInput(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n type: string,\n bodySchema: unknown,\n mode: 'create' | 'update' | 'action',\n): { properties: Record<string, JsonSchema>; required: string[]; plan: WritePlan } {\n const properties: Record<string, JsonSchema> = {}\n const required: string[] = []\n const fields: Record<string, WriteField> = {}\n const clearable: string[] = []\n const data = requestData(doc, bodySchema)\n const dataProps = isObject(data?.['properties']) ? data['properties'] : {}\n\n const attributes = deref<JsonSchema>(doc, dataProps['attributes'] as JsonSchema)\n const converted = attributes === undefined ? undefined : toPortable(doc, attributes, [], 0)\n if (converted !== undefined && converted.decoder.kind === 'object') {\n const attrRequired = new Set(\n Array.isArray(attributes!['required']) ? (attributes!['required'] as string[]) : [],\n )\n const attrProps = converted.schema['properties'] as Record<string, JsonSchema>\n for (const [name, prop] of Object.entries(converted.decoder.props)) {\n const schema = attrProps[name]!\n // The converted object already made every optional member nullable.\n properties[name] = schema\n const isRequired = mode !== 'update' && attrRequired.has(name)\n // At the top level null means \"not given\", except for a required member the API lets be null.\n fields[name] = { property: { decoder: prop.decoder, nullMeansOmit: !isRequired } }\n if (isRequired) {\n required.push(name)\n }\n if (!prop.nullMeansOmit && allowsNull(schema)) {\n clearable.push(name)\n }\n }\n }\n\n const relationships = deref<JsonSchema>(doc, dataProps['relationships'] as JsonSchema)\n const relProps = isObject(relationships?.['properties']) ? relationships['properties'] : {}\n const relRequired = new Set(\n Array.isArray(relationships?.['required']) ? (relationships['required'] as string[]) : [],\n )\n for (const [name, raw] of Object.entries(relProps)) {\n const relation = descriptor[type]?.relations[name]\n if (relation === undefined || name in properties) {\n continue\n }\n const relSchema = deref<JsonSchema>(doc, raw as JsonSchema)\n const linkage = isObject(relSchema?.['properties'])\n ? relSchema['properties']['data']\n : undefined\n const linkageAllowsNull =\n relation.cardinality === 'one' && JSON.stringify(deref(doc, linkage) ?? {}).includes('\"null\"')\n const isRequired = mode !== 'update' && relRequired.has(name)\n const schema = relationArgument(name, relation, linkageAllowsNull)\n properties[name] = isRequired || allowsNull(schema) ? schema : nullable(schema)\n fields[name] = {\n relation: isPolymorphic(relation)\n ? { cardinality: relation.cardinality, types: relation.types, polymorphic: true }\n : { cardinality: relation.cardinality, types: relation.types },\n property: { decoder: { kind: 'value' }, nullMeansOmit: !isRequired },\n }\n if (isRequired) {\n required.push(name)\n }\n if (linkageAllowsNull) {\n clearable.push(name)\n }\n }\n\n let clientId: WritePlan['clientId'] = 'none'\n if (mode === 'create') {\n const idProp = dataProps['id']\n const dataRequired = Array.isArray(data?.['required']) ? (data['required'] as string[]) : []\n if (idProp !== undefined && idProp !== false) {\n clientId = dataRequired.includes('id') ? 'required' : 'optional'\n }\n }\n\n return {\n properties,\n required,\n plan: { fields, clientId, clearable: mode === 'update' ? clearable : [] },\n }\n}\n\n/** Close a root object: every property required, the optional ones already nullable. */\nfunction root(\n properties: Record<string, JsonSchema>,\n required: readonly string[],\n): JsonSchema & { type: 'object' } {\n const out: Record<string, JsonSchema> = {}\n for (const [name, schema] of Object.entries(properties)) {\n out[name] = required.includes(name) || allowsNull(schema) ? schema : nullable(schema)\n }\n return closedObject(out) as JsonSchema & { type: 'object' }\n}\n\nexport interface InputContext {\n doc: OpenApiDocument\n descriptor: ApiDescriptor\n params: readonly ParameterObject[]\n operation: OperationObject\n defaultPageSize: number\n /** How many relationships deep `include` may reach; null for every declared path. */\n includeDepth: number | null\n}\n\n/** A list or to-many related read. */\nexport function collectionInput(\n ctx: InputContext,\n paginator: PaginatorDescriptor | undefined,\n parent: { type: string; relation: string } | undefined,\n countable: CountableDescriptor | undefined,\n): ToolInput {\n const { properties, plan } = queryInput(ctx, paginator, true)\n if (countable !== undefined && countable.tokens.includes(SELF_COUNT)) {\n properties['withCount'] = nullable({ type: 'boolean', description: WITH_COUNT_DESCRIPTION })\n plan.countProfile = countable.profile\n }\n const props: Record<string, JsonSchema> = {}\n const required: string[] = []\n if (parent !== undefined) {\n props['id'] = idSchema(\n `The id of the \\`${parent.type}\\` resource whose ${parent.relation} to list.`,\n )\n required.push('id')\n }\n return { schema: root({ ...props, ...properties }, required), query: plan }\n}\n\n/** A get or to-one related read. */\nexport function singleInput(ctx: InputContext, description: string): ToolInput {\n const { properties, plan } = queryInput(ctx, undefined, false)\n return { schema: root({ id: idSchema(description), ...properties }, ['id']), query: plan }\n}\n\n/** A create, from the type's create request body. */\nexport function createInput(ctx: InputContext, type: string): ToolInput {\n const body = deref<RequestBodyObject>(ctx.doc, ctx.operation.requestBody)\n const schema = body?.content?.['application/vnd.api+json']?.schema\n const write = writeInput(ctx.doc, ctx.descriptor, type, schema, 'create')\n const properties: Record<string, JsonSchema> = {}\n const required = [...write.required]\n if (write.plan.clientId !== 'none') {\n properties['id'] = idSchema(`The id to give the new \\`${type}\\` resource.`)\n if (write.plan.clientId === 'required') {\n required.push('id')\n }\n }\n return { schema: root({ ...properties, ...write.properties }, required), write: write.plan }\n}\n\n/** An update, from the type's update request body. */\nexport function updateInput(ctx: InputContext, type: string): ToolInput {\n const body = deref<RequestBodyObject>(ctx.doc, ctx.operation.requestBody)\n const schema = body?.content?.['application/vnd.api+json']?.schema\n const write = writeInput(ctx.doc, ctx.descriptor, type, schema, 'update')\n const properties: Record<string, JsonSchema> = {\n id: idSchema(`The id of the \\`${type}\\` resource to update.`),\n }\n const clearable = 'clear' in write.properties ? [] : write.plan.clearable\n const extra: Record<string, JsonSchema> = {}\n if (clearable.length > 0) {\n extra['clear'] = nullable({\n type: 'array',\n items: { type: 'string', enum: [...clearable] },\n description: 'Fields to set to null. Every other argument left null keeps its current value.',\n })\n }\n return {\n schema: root({ ...properties, ...write.properties, ...extra }, ['id']),\n write: { ...write.plan, clearable },\n }\n}\n\n/** A delete. */\nexport function deleteInput(type: string): ToolInput {\n return { schema: root({ id: idSchema(`The id of the \\`${type}\\` resource to delete.`) }, ['id']) }\n}\n\n/** The request media type a model can send to an action, in order of preference. */\nfunction pickBody(\n ctx: InputContext,\n):\n | { mediaType: string; schema: unknown; kind: 'document' | 'json' | 'text' | 'form' }\n | 'none'\n | undefined {\n const body = deref<RequestBodyObject>(ctx.doc, ctx.operation.requestBody)\n const content = Object.entries(body?.content ?? {})\n if (content.length === 0) {\n return 'none'\n }\n const find = (test: (mediaType: string) => boolean) =>\n content.find(([mediaType]) => test(mediaType.toLowerCase()))\n const document = find((m) => m === 'application/vnd.api+json')\n if (document !== undefined) {\n return { mediaType: document[0], schema: document[1].schema, kind: 'document' }\n }\n const json = find((m) => m === 'application/json' || m.endsWith('+json'))\n if (json !== undefined) {\n return { mediaType: json[0], schema: json[1].schema, kind: 'json' }\n }\n const text = find((m) => m.startsWith('text/'))\n if (text !== undefined) {\n return { mediaType: text[0], schema: { type: 'string' }, kind: 'text' }\n }\n const form = content.find(([mediaType, media]) => {\n const m = mediaType.toLowerCase()\n const schema = deref<JsonSchema>(ctx.doc, media.schema)\n return (\n (m === 'application/x-www-form-urlencoded' || m.startsWith('multipart/')) &&\n isObject(schema?.['properties']) &&\n Object.keys(schema['properties']).length > 0\n )\n })\n if (form !== undefined) {\n return { mediaType: form[0], schema: form[1].schema, kind: 'form' }\n }\n return undefined\n}\n\n/**\n * A custom action's input: the resource id at resource scope, then the body. A JSON:API body\n * whose type the descriptor knows is flat, like a create; any other body is one `body` argument.\n * `undefined` when every media type the action takes is one a model can't send, such as binary.\n */\nexport function actionInput(\n ctx: InputContext,\n type: string,\n name: string,\n action: ActionDescriptor,\n): ToolInput | undefined {\n const properties: Record<string, JsonSchema> = {}\n const required: string[] = []\n if (action.scope === 'resource') {\n properties['id'] = idSchema(`The id of the \\`${type}\\` resource to run ${name} on.`)\n required.push('id')\n }\n const picked = pickBody(ctx)\n if (picked === undefined) {\n return undefined\n }\n if (picked === 'none') {\n return { schema: root(properties, required), action: { kind: 'none' } }\n }\n const body = deref<RequestBodyObject>(ctx.doc, ctx.operation.requestBody)\n const bodyRequired = body?.required === true\n if (picked.kind === 'document' && action.inputType !== undefined) {\n const write = writeInput(ctx.doc, ctx.descriptor, action.inputType, picked.schema, 'action')\n for (const [key, schema] of Object.entries(write.properties)) {\n if (!(key in properties)) {\n properties[key] = schema\n }\n }\n return {\n schema: root(properties, [...required, ...write.required.filter((r) => r !== 'id')]),\n action: { kind: 'flat', write: write.plan },\n }\n }\n\n const converted = toPortable(ctx.doc, picked.schema ?? {}, [], 1)\n const description =\n typeof body?.description === 'string'\n ? body.description\n : `The request body, as ${picked.mediaType}.`\n properties['body'] = {\n ...converted.schema,\n description:\n converted.schema['description'] === undefined\n ? description\n : `${description} ${String(converted.schema['description'])}`,\n }\n if (bodyRequired) {\n required.push('body')\n }\n return {\n schema: root(properties, required),\n action: {\n kind: 'body',\n decoder: converted.decoder,\n required: bodyRequired,\n mediaType: picked.mediaType,\n mediaKind: picked.kind,\n },\n }\n}\n","import type { ApiDescriptor } from '@haddowg/json-api-client'\nimport { HTTP_METHODS, type HttpMethod } from './openapi'\nimport type { McpOperationKind } from './types'\n\n/** The name pattern OpenAI's and Anthropic's tool names share. */\nexport const TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/\n\n/** What an `operationId` names, for an operation that becomes a tool. */\nexport interface ParsedOperationId {\n kind: McpOperationKind\n type: string\n relation?: string\n action?: string\n /** The method suffix of a multi-method action's id. */\n method?: HttpMethod\n}\n\nconst CRUD: Readonly<Record<string, McpOperationKind>> = {\n fetchCollection: 'list',\n fetchOne: 'get',\n create: 'create',\n update: 'update',\n delete: 'delete',\n}\n\n/**\n * Parse an `operationId` into what a tool needs. `undefined` for an operation that isn't a tool:\n * relationship endpoints, Atomic Operations, or an id this package doesn't recognise.\n */\nexport function parseOperationId(operationId: string): ParsedOperationId | undefined {\n const parts = operationId.split('.')\n const [verb, type] = parts\n if (verb === undefined || type === undefined || type === '') {\n return undefined\n }\n const crud = CRUD[verb]\n if (crud !== undefined) {\n return parts.length === 2 ? { kind: crud, type } : undefined\n }\n if (verb === 'fetchRelated' && parts.length === 3 && parts[2] !== '') {\n return { kind: 'related', type, relation: parts[2]! }\n }\n if (verb === 'action' && parts[2] !== undefined && parts[2] !== '') {\n if (parts.length === 3) {\n return { kind: 'action', type, action: parts[2] }\n }\n const method = parts[3] as HttpMethod\n if (parts.length === 4 && HTTP_METHODS.includes(method)) {\n return { kind: 'action', type, action: parts[2], method }\n }\n }\n return undefined\n}\n\nconst snake = (value: string): string => value.replace(/-/g, '_')\n\n/**\n * The tool name for a parsed `operationId`: noun first, the type as the document spells it with\n * kebab-case turned into snake_case. A related read ends in `list` or `get` by the relation's\n * cardinality; an action is named after its path, plus the method for a multi-method action.\n */\nexport function toolName(parsed: ParsedOperationId, descriptor: ApiDescriptor): string {\n const type = snake(parsed.type)\n switch (parsed.kind) {\n case 'related': {\n const relation = descriptor[parsed.type]?.relations[parsed.relation!]\n const verb = relation?.cardinality === 'one' ? 'get' : 'list'\n return `${type}_${snake(parsed.relation!)}_${verb}`\n }\n case 'action':\n return parsed.method === undefined\n ? `${type}_${snake(parsed.action!)}`\n : `${type}_${snake(parsed.action!)}_${parsed.method}`\n default:\n return `${type}_${parsed.kind}`\n }\n}\n\n/** Thrown when the tools can't be named: a name too long, with a stray character, or a clash. */\nexport class ToolNameError extends Error {\n readonly problems: readonly string[]\n\n constructor(problems: readonly string[]) {\n super(`Cannot build MCP tools from this document:\\n- ${problems.join('\\n- ')}`)\n this.name = 'ToolNameError'\n this.problems = problems\n }\n}\n\n/** Collect every naming problem across the tools, so one build reports them all. */\nexport function checkToolNames(tools: readonly { name: string; operationId: string }[]): void {\n const problems: string[] = []\n const byName = new Map<string, string[]>()\n for (const { name, operationId } of tools) {\n if (name.length > 64) {\n problems.push(`\"${name}\" (${operationId}) is ${name.length} characters; tool names allow 64`)\n } else if (!TOOL_NAME_PATTERN.test(name)) {\n problems.push(`\"${name}\" (${operationId}) has characters outside [a-zA-Z0-9_-]`)\n }\n byName.set(name, [...(byName.get(name) ?? []), operationId])\n }\n for (const [name, ids] of byName) {\n if (ids.length > 1) {\n problems.push(`\"${name}\" is the tool name of ${ids.join(' and ')}`)\n }\n }\n if (problems.length > 0) {\n throw new ToolNameError(problems)\n }\n}\n","import { isObject, type OperationObject } from './openapi'\n\n/** The vendor extension an action's operation declares its safety in. */\nexport const SAFETY_EXTENSION = 'x-safety'\n\n/** What an action declares about itself. A flag it doesn't declare is absent. */\nexport interface ActionSafety {\n readOnly?: boolean\n destructive?: boolean\n idempotent?: boolean\n}\n\n/**\n * Read an action's declared safety from its operation. An operation without the extension, or\n * with one this package can't read, declares nothing.\n */\nexport function readActionSafety(operation: OperationObject): ActionSafety {\n const raw = operation[SAFETY_EXTENSION]\n const safety: ActionSafety = {}\n if (!isObject(raw)) {\n return safety\n }\n for (const key of ['readOnly', 'destructive', 'idempotent'] as const) {\n if (typeof raw[key] === 'boolean') {\n safety[key] = raw[key]\n }\n }\n return safety\n}\n","import type { McpOperation, McpOperationKind } from './types'\n\n/** The descriptor's key for each kind's operation in a type's `scopes`. */\nconst SCOPE_KEYS: Readonly<Record<Exclude<McpOperationKind, 'related' | 'action'>, string>> = {\n list: 'fetchCollection',\n get: 'fetchOne',\n create: 'create',\n update: 'update',\n delete: 'delete',\n}\n\n/** The scopes the descriptor says an operation needs, or `undefined` when it names none. */\nexport function descriptorScopes(\n op: Pick<McpOperation, 'kind' | 'relation' | 'resource' | 'actionDescriptor'>,\n): readonly string[] | undefined {\n let scopes: readonly string[] | undefined\n if (op.kind === 'action') {\n scopes = op.actionDescriptor?.scopes\n } else if (op.kind === 'related') {\n scopes = op.resource.scopes?.[`fetchRelated.${op.relation ?? ''}`]\n } else {\n scopes = op.resource.scopes?.[SCOPE_KEYS[op.kind]]\n }\n return scopes === undefined || scopes.length === 0 ? undefined : scopes\n}\n","import type { ActionDescriptor, ApiDescriptor, PaginatorDescriptor } from '@haddowg/json-api-client'\nimport {\n actionInput,\n collectionInput,\n createInput,\n deleteInput,\n type InputContext,\n singleInput,\n updateInput,\n type ToolInput,\n} from './inputs'\nimport { checkToolNames, parseOperationId, type ParsedOperationId, toolName } from './names'\nimport {\n HTTP_METHODS,\n type JsonSchema,\n type OpenApiDocument,\n operationParameters,\n type OperationObject,\n} from './openapi'\nimport {\n collectionOutput,\n deletedOutput,\n LOOSE_OUTPUT,\n locationOutput,\n metaOutput,\n orLocation,\n type OutputContext,\n capIncludePaths,\n includePaths,\n resourceLinkNames,\n resourceOutput,\n resourceSchemas,\n} from './outputs'\nimport { type ActionSafety, readActionSafety } from './safety'\nimport { descriptorScopes } from './scopes'\nimport type { McpOperation, McpTool, McpToolAnnotations, SkippedOperation } from './types'\n\n/** How the handler shapes a call's result. */\nexport type ResultShape =\n | 'collection'\n | 'resource'\n | 'item'\n | 'deleted'\n | 'meta'\n | 'location'\n | 'none'\n | 'raw'\n | 'loose'\n\n/** One tool and everything its handler needs. */\nexport interface CatalogueEntry {\n op: McpOperation\n tool: McpTool\n input: ToolInput\n result: ResultShape\n /**\n * An action's key in the type's descriptor `actions`: its name for the preferred method, the\n * name plus the method for the others.\n */\n actionKey?: string\n}\n\nexport interface Catalogue {\n entries: CatalogueEntry[]\n skipped: SkippedOperation[]\n /** The names of the links each type names, for the types that name any. */\n resourceLinks: Record<string, string[]>\n}\n\nfunction annotations(op: McpOperation): McpToolAnnotations | undefined {\n switch (op.kind) {\n case 'list':\n case 'get':\n case 'related':\n return { readOnlyHint: true }\n case 'create':\n case 'update':\n return { readOnlyHint: false, destructiveHint: false, idempotentHint: false }\n case 'delete':\n return { readOnlyHint: false, destructiveHint: true, idempotentHint: true }\n case 'action': {\n const safety = actionSafety(op)\n const out: McpToolAnnotations = {}\n if (safety.readOnly !== undefined) out.readOnlyHint = safety.readOnly\n if (safety.destructive !== undefined) out.destructiveHint = safety.destructive\n if (safety.idempotent !== undefined) out.idempotentHint = safety.idempotent\n return Object.keys(out).length > 0 ? out : undefined\n }\n }\n}\n\n/**\n * An action's declared safety: the flags its descriptor entry carries, with the operation's own\n * `x-safety` winning where both say. A codegen descriptor mirrors `x-safety`, so they agree.\n */\nfunction actionSafety(op: McpOperation): ActionSafety {\n const safety: ActionSafety = {}\n const declared = op.actionDescriptor\n for (const key of ['readOnly', 'destructive', 'idempotent'] as const) {\n const value = declared?.[key]\n if (typeof value === 'boolean') {\n safety[key] = value\n }\n }\n return { ...safety, ...readActionSafety(op.operation) }\n}\n\n/** The descriptor entry an action operation calls: the one at its path and method. */\nfunction findAction(op: McpOperation): [string, ActionDescriptor] | undefined {\n const entries = Object.entries(op.resource.actions ?? {})\n return entries.find(\n ([, action]) => action.path === op.path && (action.method ?? 'POST') === op.method,\n )\n}\n\nfunction actionResult(action: ActionDescriptor): ResultShape {\n if (action.output === 'location') {\n return 'location'\n }\n if (action.output === 'none') {\n return action.rawOutput !== undefined && action.rawOutput.length > 0 ? 'raw' : 'none'\n }\n if (action.output === 'meta') {\n return 'meta'\n }\n if (action.outputType === undefined) {\n return 'loose'\n }\n return action.outputCardinality === 'many' ? 'collection' : 'resource'\n}\n\n/**\n * An action's output schema. One that may answer with a URL instead of its usual result takes\n * either; one that only answers with a URL takes the URL.\n */\nfunction actionOutput(ctx: OutputContext, action: ActionDescriptor): JsonSchema | undefined {\n const usual = documentOutput(ctx, action)\n if (action.location === undefined) {\n return usual\n }\n return usual === undefined\n ? locationOutput(action.location.mediaType)\n : orLocation(usual, action.location.mediaType)\n}\n\nfunction documentOutput(ctx: OutputContext, action: ActionDescriptor): JsonSchema | undefined {\n switch (actionResult(action)) {\n case 'collection':\n return collectionOutput(ctx, [action.outputType!])\n case 'resource':\n return resourceOutput(ctx, [action.outputType!], 'The resource the action returned.')\n case 'meta':\n return metaOutput(ctx)\n case 'loose':\n return LOOSE_OUTPUT\n default:\n return undefined\n }\n}\n\n/** Build every tool the document and descriptor describe. Throws on a naming problem. */\nexport function buildCatalogue(\n doc: OpenApiDocument,\n descriptor: ApiDescriptor,\n defaultPageSize: number,\n includeDepth: number | null = null,\n): Catalogue {\n const entries: CatalogueEntry[] = []\n const skipped: SkippedOperation[] = []\n const schemas = resourceSchemas(doc)\n const resourceLinks = resourceLinkNames(doc, descriptor, schemas)\n\n for (const [path, item] of Object.entries(doc.paths ?? {})) {\n for (const method of HTTP_METHODS) {\n const operation = item[method]\n const operationId = operation?.operationId\n if (operation === undefined || typeof operationId !== 'string') {\n continue\n }\n const parsed = parseOperationId(operationId)\n if (parsed === undefined) {\n continue\n }\n const resource = descriptor[parsed.type]\n if (resource === undefined) {\n skipped.push({ operationId, reason: `the descriptor has no type \"${parsed.type}\"` })\n continue\n }\n const op: McpOperation = {\n operationId,\n toolName: toolName(parsed, descriptor),\n kind: parsed.kind,\n type: parsed.type,\n method: method.toUpperCase(),\n path,\n resource,\n operation,\n security: operation.security ?? doc.security ?? [],\n }\n const inputCtx: InputContext = {\n doc,\n descriptor,\n params: operationParameters(doc, item, operation),\n operation,\n defaultPageSize,\n includeDepth,\n }\n const outputCtx: OutputContext = {\n doc,\n descriptor,\n schemas,\n operation,\n includes: capIncludePaths(includePaths(doc, operation), includeDepth),\n }\n const built = buildEntry(op, parsed, inputCtx, outputCtx, descriptor)\n if (typeof built === 'string') {\n skipped.push({ operationId, reason: built })\n continue\n }\n entries.push(built)\n }\n }\n\n checkToolNames(entries.map((e) => ({ name: e.tool.name, operationId: e.op.operationId })))\n // oxlint-disable-next-line no-array-sort -- sorting the freshly built array\n entries.sort((a, b) => a.tool.name.localeCompare(b.tool.name))\n return { entries, skipped, resourceLinks }\n}\n\nfunction buildEntry(\n op: McpOperation,\n parsed: ParsedOperationId,\n inputCtx: InputContext,\n outputCtx: OutputContext,\n descriptor: ApiDescriptor,\n): CatalogueEntry | string {\n let input: ToolInput | undefined\n let output: JsonSchema | undefined\n let result: ResultShape\n let key: string | undefined\n\n switch (parsed.kind) {\n case 'list':\n input = collectionInput(inputCtx, op.resource.paginator, undefined, op.resource.countable)\n output = collectionOutput(outputCtx, [op.type])\n result = 'collection'\n break\n case 'get':\n input = singleInput(inputCtx, `The id of the \\`${op.type}\\` resource to get.`)\n output = resourceOutput(outputCtx, [op.type])\n result = 'item'\n break\n case 'create':\n input = createInput(inputCtx, op.type)\n output = resourceOutput(outputCtx, [op.type])\n result = 'resource'\n break\n case 'update':\n input = updateInput(inputCtx, op.type)\n output = resourceOutput(outputCtx, [op.type])\n result = 'resource'\n break\n case 'delete':\n input = deleteInput(op.type)\n output = deletedOutput(outputCtx)\n result = 'deleted'\n break\n case 'related': {\n const relation = op.resource.relations[parsed.relation!]\n if (relation === undefined) {\n return `the descriptor has no relation \"${parsed.relation}\" on \"${op.type}\"`\n }\n op.relation = parsed.relation!\n op.relationDescriptor = relation\n if (relation.cardinality === 'many') {\n const paginator: PaginatorDescriptor | undefined =\n relation.paginator ?? descriptor[relation.types[0] ?? '']?.paginator\n input = collectionInput(\n inputCtx,\n paginator,\n { type: op.type, relation: parsed.relation! },\n relation.countable,\n )\n output = collectionOutput(outputCtx, relation.types)\n result = 'collection'\n } else {\n input = singleInput(\n inputCtx,\n `The id of the \\`${op.type}\\` resource whose ${parsed.relation} to get.`,\n )\n output = resourceOutput(\n outputCtx,\n relation.types,\n 'The related resource, or null when there is none.',\n )\n result = 'item'\n }\n break\n }\n case 'action': {\n const found = findAction(op)\n if (found === undefined) {\n return `the descriptor has no ${op.method} action at \"${op.path}\" on \"${op.type}\"`\n }\n const [actionKey, action] = found\n op.action = parsed.action!\n op.actionDescriptor = action\n key = actionKey\n input = actionInput(inputCtx, op.type, parsed.action!, action)\n if (input === undefined) {\n return 'every request media type it accepts is one a model cannot send, such as a binary upload'\n }\n output = actionOutput(outputCtx, action)\n result = actionResult(action)\n break\n }\n }\n\n const scopes = descriptorScopes(op)\n if (scopes !== undefined) {\n op.scopes = scopes\n }\n\n const tool: McpTool = { name: op.toolName, inputSchema: input.schema }\n const operation: OperationObject = op.operation\n if (typeof operation.summary === 'string') {\n tool.title = operation.summary\n }\n const description = operation.description ?? operation.summary\n if (typeof description === 'string') {\n tool.description = description\n }\n if (output !== undefined) {\n tool.outputSchema = output as McpTool['outputSchema'] & object\n }\n const hints = annotations(op)\n if (hints !== undefined) {\n tool.annotations = hints\n }\n // oxlint-disable-next-line no-underscore-dangle -- MCP names the field `_meta`\n tool._meta = { operationId: op.operationId }\n return key === undefined\n ? { op, tool, input, result }\n : { op, tool, input, result, actionKey: key }\n}\n","import type { OpenApiDocument } from './openapi'\n\n/** The oldest generator contract this package reads: the baseline current servers stamp. */\nexport const MINIMUM_CONTRACT = 13\n\n/** The newest generator contract this package reads. */\nexport const MAXIMUM_CONTRACT = 19\n\n/**\n * Throw unless the document's `info.x-generator.contract` is in the range this package reads. A\n * document outside it would yield tools that miss or misread what the server offers, so there is\n * no warning mode.\n */\nexport function assertContract(doc: OpenApiDocument): number {\n const contract = doc.info?.['x-generator']?.contract\n if (typeof contract !== 'number') {\n throw new Error(\n `The OpenAPI document declares no generator contract (info.x-generator.contract). @haddowg/json-api-mcp reads contracts ${MINIMUM_CONTRACT} to ${MAXIMUM_CONTRACT}; regenerate the document from a newer haddowg/json-api server.`,\n )\n }\n if (contract < MINIMUM_CONTRACT) {\n throw new Error(\n `The OpenAPI document declares generator contract ${contract}, older than this package reads (${MINIMUM_CONTRACT} to ${MAXIMUM_CONTRACT}). Regenerate it from a newer haddowg/json-api server.`,\n )\n }\n if (contract > MAXIMUM_CONTRACT) {\n throw new Error(\n `The OpenAPI document declares generator contract ${contract}, newer than this package reads (${MINIMUM_CONTRACT} to ${MAXIMUM_CONTRACT}). Upgrade @haddowg/json-api-mcp.`,\n )\n }\n return contract\n}\n","/**\n * The generated artefact the runtime reads: everything a host needs to serve the tools, built\n * from the OpenAPI document at build time. It is plain JSON, so any host can load it, and it\n * carries the client's descriptor because the client can't make a call without one.\n */\nimport type { ApiDescriptor } from '@haddowg/json-api-client'\nimport type { ResultShape } from './catalogue'\nimport { MAXIMUM_CONTRACT, MINIMUM_CONTRACT } from './contract'\nimport type { ActionBodyPlan, QueryPlan, WritePlan } from './inputs'\nimport { isObject, type OperationObject, type SecurityRequirement } from './openapi'\nimport type { McpOperationKind, McpTool, SkippedOperation } from './types'\n\n/** The artefact's own format. A runtime refuses a format it doesn't know. */\nexport const MODEL_FORMAT = 4\n\n/**\n * Every format this runtime reads. Format 1 has no `credentialSchemes`. Formats 1 and 2 have no\n * `includeDepth`, and store each operation's `scopes` and the `security` of its operation object.\n * Formats 1 to 3 have no `resourceLinks`, and their output schemas describe the results before\n * the envelope, which the runtime still returns for them.\n */\nconst READABLE_FORMATS: readonly number[] = [1, 2, 3, MODEL_FORMAT]\n\n/** The package that writes the artefact. */\nexport const MODEL_GENERATOR = '@haddowg/json-api-mcp'\n\n/** One operation, as hooks see it, without the descriptor entries the runtime adds back. */\nexport interface McpModelOperation {\n operationId: string\n toolName: string\n kind: McpOperationKind\n type: string\n relation?: string\n action?: string\n /** The action's key in the type's descriptor `actions`. */\n actionKey?: string\n method: string\n path: string\n /**\n * The operation object, extensions included, without its `parameters`, `requestBody` and\n * `responses`: the tool already holds what those say, and they can refer to components the\n * artefact doesn't carry. From format 3 it has no `security` either: the runtime puts back\n * the `security` below.\n */\n operation: OperationObject\n /**\n * The operation's own `security`, else the document's. From format 3 it is absent when the\n * operation declares none, and the runtime takes the model's `security`.\n */\n security?: readonly SecurityRequirement[]\n /**\n * Formats 1 and 2: the OAuth scopes the descriptor says the operation needs. From format 3\n * the runtime reads them from the descriptor.\n */\n scopes?: readonly string[]\n}\n\n/** How the handler turns one tool's arguments into a client call. */\nexport interface McpModelPlan {\n query?: QueryPlan\n write?: WritePlan\n action?: ActionBodyPlan\n}\n\nexport interface McpModelTool {\n operation: McpModelOperation\n tool: McpTool\n plan: McpModelPlan\n result: ResultShape\n}\n\n/** The generated artefact. */\nexport interface McpModel {\n format: 1 | 2 | 3 | typeof MODEL_FORMAT\n generator: typeof MODEL_GENERATOR\n /** The generator contract the source document declared. */\n contract: number\n /** Which document it was built from. */\n source: { title: string; hash: string }\n /** The document's first server URL, the default base URL. */\n baseUrl?: string\n /**\n * The security schemes an MCP caller authenticates with: the document's `oauth2` schemes.\n * Empty when it has none. A format 1 model doesn't carry it.\n */\n credentialSchemes?: string[]\n /**\n * Format 3: the document's `security`, which an operation declaring none of its own takes.\n * Absent when the document declares none.\n */\n security?: readonly SecurityRequirement[]\n /**\n * How many relationships deep a tool's `include` may reach; null for every path the document\n * declares. Formats 1 and 2 don't carry it and set no cap.\n */\n includeDepth?: number | null\n /**\n * Format 4: the links each type names, its declared links and action links, for the types that\n * name any. A flattened resource carries these under `links`.\n */\n resourceLinks?: Record<string, string[]>\n /** The json-api-ts descriptor the client calls through. */\n descriptor: ApiDescriptor\n tools: McpModelTool[]\n skipped: SkippedOperation[]\n}\n\n/** Thrown when an artefact can't be read: another format, or a contract out of range. */\nexport class McpModelError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'McpModelError'\n }\n}\n\n/** Check a parsed artefact before the runtime trusts it. */\nexport function assertModel(value: unknown): McpModel {\n if (!isObject(value) || value['generator'] !== MODEL_GENERATOR) {\n throw new McpModelError(\n `This isn't a model written by ${MODEL_GENERATOR}. Generate one with the json-api-mcp CLI.`,\n )\n }\n if (typeof value['format'] !== 'number' || !READABLE_FORMATS.includes(value['format'])) {\n throw new McpModelError(\n `The model is format ${String(value['format'])} and this runtime reads formats ${READABLE_FORMATS.slice(0, -1).join(', ')} and ${MODEL_FORMAT}. Regenerate it with the same version of ${MODEL_GENERATOR} the server runs.`,\n )\n }\n const contract = value['contract']\n if (typeof contract !== 'number' || contract < MINIMUM_CONTRACT || contract > MAXIMUM_CONTRACT) {\n throw new McpModelError(\n `The model was built from a document with generator contract ${String(contract)}, and this runtime reads contracts ${MINIMUM_CONTRACT} to ${MAXIMUM_CONTRACT}.`,\n )\n }\n if (!isObject(value['descriptor']) || !Array.isArray(value['tools'])) {\n throw new McpModelError('The model has no descriptor or tools; regenerate it.')\n }\n const credentialSchemes = value['credentialSchemes']\n if (\n value['format'] !== 1 &&\n (!Array.isArray(credentialSchemes) || !credentialSchemes.every((s) => typeof s === 'string'))\n ) {\n throw new McpModelError('The model has no credentialSchemes list; regenerate it.')\n }\n const includeDepth = value['includeDepth']\n if (\n (value['format'] as number) >= 3 &&\n includeDepth !== null &&\n !(typeof includeDepth === 'number' && Number.isInteger(includeDepth) && includeDepth >= 0)\n ) {\n throw new McpModelError('The model has no includeDepth; regenerate it.')\n }\n const resourceLinks = value['resourceLinks']\n if (\n value['format'] === MODEL_FORMAT &&\n !(\n isObject(resourceLinks) &&\n Object.values(resourceLinks).every(\n (names) => Array.isArray(names) && names.every((name) => typeof name === 'string'),\n )\n )\n ) {\n throw new McpModelError('The model has no resourceLinks; regenerate it.')\n }\n return value as unknown as McpModel\n}\n\n/**\n * The schemes a format 1 model's caller is taken to authenticate with, since it doesn't record\n * them: every scheme some operation lists scopes under.\n */\nexport function inferCredentialSchemes(model: McpModel): string[] {\n const schemes = new Set<string>()\n for (const tool of model.tools) {\n for (const requirement of tool.operation.security ?? []) {\n for (const [scheme, scopes] of Object.entries(requirement)) {\n if (scopes.length > 0) schemes.add(scheme)\n }\n }\n }\n return [...schemes]\n}\n","import type { ApiDescriptor } from '@haddowg/json-api-client'\nimport { buildCatalogue } from './catalogue'\nimport { assertContract } from './contract'\nimport { MODEL_FORMAT, MODEL_GENERATOR, type McpModel, type McpModelOperation } from './model'\nimport { deref, isObject, type OpenApiDocument, type OperationObject } from './openapi'\n\n/** Options for {@link buildMcpModel}. */\nexport interface BuildModelOptions {\n /** The page size a list tool asks for when the model gives none. Defaults to 10. */\n defaultPageSize?: number\n /**\n * How many relationships deep a tool's `include` may reach, 1 by default. Each tool lists and\n * accepts only the declared paths within it, and its output schema covers only the types those\n * reach. `null` keeps every path the document declares.\n */\n includeDepth?: number | null\n /** The source document's content hash, recorded in the model. */\n hash: string\n}\n\n// `security` is stored once, on the model operation, and put back by the runtime.\nconst OMITTED = new Set(['parameters', 'requestBody', 'responses', 'callbacks', 'security'])\n\nfunction lightOperation(operation: OperationObject): OperationObject {\n const out: OperationObject = {}\n for (const [key, value] of Object.entries(operation)) {\n if (!OMITTED.has(key)) {\n out[key] = value\n }\n }\n return out\n}\n\n/** The names of the document's `oauth2` security schemes, the ones an MCP caller presents. */\nfunction oauthSchemes(document: OpenApiDocument): string[] {\n const schemes = document.components?.['securitySchemes']\n if (!isObject(schemes)) {\n return []\n }\n return Object.keys(schemes).filter((name) => {\n const scheme = deref<unknown>(document, schemes[name])\n return isObject(scheme) && scheme['type'] === 'oauth2'\n })\n}\n\n/**\n * Build the model from a document and its descriptor. Throws when the document's generator\n * contract is out of range or a tool name breaks the rules. Needs no codegen: pass the\n * descriptor a generated client exports, or use `generateMcpModel` to build it too.\n */\nexport function buildMcpModel(\n document: OpenApiDocument,\n descriptor: ApiDescriptor,\n options: BuildModelOptions,\n): McpModel {\n const contract = assertContract(document)\n const includeDepth = options.includeDepth === undefined ? 1 : options.includeDepth\n if (includeDepth !== null && !(Number.isInteger(includeDepth) && includeDepth >= 0)) {\n throw new Error(\n `includeDepth must be a whole number of 0 or more, or null; got ${includeDepth}`,\n )\n }\n const catalogue = buildCatalogue(\n document,\n descriptor,\n options.defaultPageSize ?? 10,\n includeDepth,\n )\n const info = document.info as { title?: unknown; version?: unknown } | undefined\n const model: McpModel = {\n format: MODEL_FORMAT,\n generator: MODEL_GENERATOR,\n contract,\n source: {\n title: `${String(info?.title ?? 'unknown')} ${String(info?.version ?? 'unknown')}`,\n hash: options.hash,\n },\n credentialSchemes: oauthSchemes(document),\n includeDepth,\n resourceLinks: catalogue.resourceLinks,\n descriptor,\n tools: catalogue.entries.map((entry) => {\n const { op } = entry\n const operation: McpModelOperation = {\n operationId: op.operationId,\n toolName: op.toolName,\n kind: op.kind,\n type: op.type,\n method: op.method,\n path: op.path,\n operation: lightOperation(op.operation),\n }\n if (op.operation.security !== undefined) operation.security = op.operation.security\n if (op.relation !== undefined) operation.relation = op.relation\n if (op.action !== undefined) operation.action = op.action\n if (entry.actionKey !== undefined) operation.actionKey = entry.actionKey\n const { schema: _schema, ...plan } = entry.input\n return { operation, tool: entry.tool, plan, result: entry.result }\n }),\n skipped: catalogue.skipped,\n }\n if (document.security !== undefined) {\n model.security = document.security\n }\n const server = document.servers?.[0]?.url\n if (server !== undefined) {\n model.baseUrl = server\n }\n return model\n}\n","/**\n * @haddowg/json-api-mcp/generate: the build-time half. It reads an OpenAPI document, builds the\n * descriptor with `@haddowg/json-api-codegen` and writes the model the runtime serves. Run it\n * against the committed spec and commit its output, as with the generated client. The runtime\n * entry point never loads this module or the codegen.\n */\nimport { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { ApiDescriptor } from '@haddowg/json-api-client'\nimport { buildMcpModel } from './build'\nimport type { McpModel } from './model'\nimport type { OpenApiDocument } from './openapi'\n\nexport { buildMcpModel } from './build'\nexport type { BuildModelOptions } from './build'\n\ntype Codegen = typeof import('@haddowg/json-api-codegen')\n\nasync function codegen(): Promise<Codegen> {\n try {\n return await import('@haddowg/json-api-codegen')\n } catch (error) {\n throw new Error(\n 'Generating an MCP model needs @haddowg/json-api-codegen; add it to your dev dependencies.',\n { cause: error },\n )\n }\n}\n\n/** Options for {@link generateMcpModel}. */\nexport interface GenerateModelOptions {\n /** The page size a list tool asks for when the model gives none. Defaults to 10. */\n defaultPageSize?: number\n /**\n * How many relationships deep a tool's `include` may reach, 1 by default. `null` keeps every\n * path the document declares.\n */\n includeDepth?: number | null\n}\n\n/** Build the model from a parsed document, building its descriptor with the codegen. */\nexport async function generateMcpModel(\n document: OpenApiDocument,\n options: GenerateModelOptions = {},\n): Promise<McpModel> {\n const { buildDescriptor, hashJson } = await codegen()\n const descriptor = buildDescriptor(\n document as Parameters<typeof buildDescriptor>[0],\n ) as ApiDescriptor\n return buildMcpModel(document, descriptor, { ...options, hash: hashJson(document) })\n}\n\n/** The model as the generator writes it: two-space JSON with a trailing newline. */\nexport function serialiseMcpModel(model: McpModel): string {\n return `${JSON.stringify(model, null, 2)}\\n`\n}\n\n/** Options for {@link writeMcpModel}. */\nexport interface WriteModelOptions extends GenerateModelOptions {\n /** The OpenAPI document: an http(s) URL or a local file, JSON or YAML. */\n input: string\n /** Where the model goes, such as `src/api.mcp.json`. */\n output: string\n /** Compare against the committed model instead of writing it. */\n check?: boolean\n}\n\n/** What {@link writeMcpModel} did. */\nexport interface WriteModelResult {\n path: string\n /** For a check: whether the committed model matches. Always true after a write. */\n upToDate: boolean\n}\n\n/**\n * Read the document, build the model and write it, or with `check` compare it with the committed\n * file. The comparison is of the parsed JSON, so a formatter rewriting the file's whitespace\n * doesn't count as a change.\n */\nexport async function writeMcpModel(options: WriteModelOptions): Promise<WriteModelResult> {\n const { readDocument } = await codegen()\n const document = (await readDocument(options.input)) as OpenApiDocument\n const generateOptions: GenerateModelOptions = {}\n if (options.defaultPageSize !== undefined)\n generateOptions.defaultPageSize = options.defaultPageSize\n if (options.includeDepth !== undefined) generateOptions.includeDepth = options.includeDepth\n const content = serialiseMcpModel(await generateMcpModel(document, generateOptions))\n if (options.check === true) {\n let committed: unknown\n try {\n committed = JSON.parse(await readFile(options.output, 'utf8')) as unknown\n } catch {\n return { path: options.output, upToDate: false }\n }\n return {\n path: options.output,\n upToDate: JSON.stringify(committed) === JSON.stringify(JSON.parse(content)),\n }\n }\n await mkdir(dirname(options.output), { recursive: true })\n await writeFile(options.output, content, 'utf8')\n return { path: options.output, upToDate: true }\n}\n"],"mappings":"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"}