{"version":3,"file":"mcp.mjs","names":["Type.String","Type.Object","Type.Array","Type.Optional","Type.Integer"],"sources":["../src/mcp.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n  CallToolRequestSchema,\n  ListToolsRequestSchema,\n  type CallToolResult,\n  type Tool,\n  type ToolAnnotations,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { Type, type Static, type TSchema } from \"typebox\";\nimport type { Client } from \"./core/client.ts\";\nimport {\n  bulkPackagesOperation,\n  dependenciesOperation,\n  ecosystemsOperation,\n  maintainersOperation,\n  MAX_BULK_CONCURRENCY,\n  MAX_BULK_PACKAGES,\n  MAX_PURL_LENGTH,\n  packageOperation,\n  type ToolResult,\n  versionsOperation,\n} from \"./tool-operations.ts\";\nimport { version } from \"./version.ts\";\n\nconst PURL = Type.String({\n  minLength: 1,\n  maxLength: MAX_PURL_LENGTH,\n  description: \"Package URL, for example pkg:npm/lodash or pkg:pypi/requests@2.32.3\",\n});\n\nconst PURLParams = Type.Object({ purl: PURL }, { additionalProperties: false });\nconst BulkPackagesParams = Type.Object(\n  {\n    purls: Type.Array(PURL, { minItems: 1, maxItems: MAX_BULK_PACKAGES }),\n    concurrency: Type.Optional(Type.Integer({ minimum: 1, maximum: MAX_BULK_CONCURRENCY })),\n  },\n  { additionalProperties: false },\n);\nconst EmptyParams = Type.Object({}, { additionalProperties: false });\n\nconst REMOTE_READ: ToolAnnotations = {\n  readOnlyHint: true,\n  destructiveHint: false,\n  idempotentHint: false,\n  openWorldHint: true,\n};\nconst LOCAL_READ: ToolAnnotations = {\n  readOnlyHint: true,\n  destructiveHint: false,\n  idempotentHint: true,\n  openWorldHint: false,\n};\n\ninterface RegistryTool<S extends TSchema> {\n  readonly name: string;\n  readonly title: string;\n  readonly description: string;\n  readonly inputSchema: S;\n  readonly annotations: ToolAnnotations;\n  execute(\n    params: Readonly<Static<S>>,\n    signal?: AbortSignal,\n    client?: Client,\n  ): Promise<ToolResult<unknown>>;\n}\n\nfunction defineTool<S extends TSchema>(tool: Readonly<RegistryTool<S>>): RegistryTool<S> {\n  return tool;\n}\n\nconst tools = [\n  defineTool({\n    name: \"registries_package\",\n    title: \"Get package metadata\",\n    description: \"Fetch normalized metadata for one package URL.\",\n    inputSchema: PURLParams,\n    annotations: REMOTE_READ,\n    execute: packageOperation,\n  }),\n  defineTool({\n    name: \"registries_versions\",\n    title: \"List package versions\",\n    description: \"List normalized versions for one package URL.\",\n    inputSchema: PURLParams,\n    annotations: REMOTE_READ,\n    execute: versionsOperation,\n  }),\n  defineTool({\n    name: \"registries_dependencies\",\n    title: \"List package dependencies\",\n    description: \"List dependencies for a versioned package URL.\",\n    inputSchema: PURLParams,\n    annotations: REMOTE_READ,\n    execute: dependenciesOperation,\n  }),\n  defineTool({\n    name: \"registries_maintainers\",\n    title: \"List package maintainers\",\n    description: \"List normalized maintainers for one package URL.\",\n    inputSchema: PURLParams,\n    annotations: REMOTE_READ,\n    execute: maintainersOperation,\n  }),\n  defineTool({\n    name: \"registries_bulk_packages\",\n    title: \"Get package metadata in bulk\",\n    description: \"Fetch normalized package metadata for up to 50 package URLs.\",\n    inputSchema: BulkPackagesParams,\n    annotations: REMOTE_READ,\n    execute: bulkPackagesOperation,\n  }),\n  defineTool({\n    name: \"registries_ecosystems\",\n    title: \"List registry ecosystems\",\n    description: \"List package ecosystems registered by this package.\",\n    inputSchema: EmptyParams,\n    annotations: LOCAL_READ,\n    execute: ecosystemsOperation,\n  }),\n] as const;\n\ntype AnyRegistryTool = (typeof tools)[number];\n\nfunction errorMessage(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n\nfunction sanitizeField(value: string): string {\n  return Array.from(value)\n    .map((character) => {\n      const code = character.codePointAt(0) ?? 0;\n      return code <= 31 || (code >= 127 && code <= 159) ? \" \" : character;\n    })\n    .join(\"\");\n}\n\nfunction errorResult(text: string): CallToolResult {\n  return { content: [{ type: \"text\", text: sanitizeField(text) }], isError: true };\n}\n\nfunction toCallToolResult(result: ToolResult<unknown>): CallToolResult {\n  return { content: result.content, ...(result.isError ? { isError: true } : {}) };\n}\n\n/**\n * SAFETY: TypeBox schemas conform to the JSON Schema object accepted by MCP.\n *\n * @param schema - TypeBox schema to expose through MCP.\n * @returns {Tool[\"inputSchema\"]} The same schema under the MCP SDK type.\n */\nfunction toMcpSchema(schema: TSchema): Tool[\"inputSchema\"] {\n  return schema as unknown as Tool[\"inputSchema\"];\n}\n\n/** The `tools/list` entries shared by `registries mcp` and the MCP server of the docs site. */\nexport const toolListings: readonly Tool[] = tools.map((tool): Tool => ({\n  name: tool.name,\n  title: tool.title,\n  description: tool.description,\n  inputSchema: toMcpSchema(tool.inputSchema),\n  annotations: tool.annotations,\n}));\n\nconst toolsByName = new Map<string, AnyRegistryTool>(tools.map((tool) => [tool.name, tool]));\n\n/**\n * Runs one tool the way `tools/call` of `registries mcp` does, errors as results, never as a throw.\n *\n * @param {string} name - The tool's name, such as `registries_package`.\n * @param {Readonly<Record<string, unknown>>} args - The arguments the client sent.\n * @param {AbortSignal} [signal] - The request's signal, which stops the registry requests.\n * @param {Client} [client] - HTTP client for the registry requests, the default one when absent.\n * @returns {Promise<CallToolResult>} The tool's text, or the sanitized error.\n */\nexport async function callTool(\n  name: string,\n  args: Readonly<Record<string, unknown>>,\n  signal?: AbortSignal,\n  client?: Client,\n): Promise<CallToolResult> {\n  const tool = toolsByName.get(name);\n  if (!tool) return errorResult(`Unknown registries tool: ${name}`);\n\n  const { Value } = await import(\"typebox/value\");\n  if (!Value.Check(tool.inputSchema, args)) {\n    return errorResult(`Invalid arguments for ${tool.name}`);\n  }\n\n  try {\n    /** SAFETY: Value.Check validated args against the selected tool's schema. */\n    const validatedArgs = args as never;\n    return toCallToolResult(await tool.execute(validatedArgs, signal, client));\n  } catch (error) {\n    return errorResult(`${tool.name} failed: ${errorMessage(error)}`);\n  }\n}\n\nexport function createMcpServer(): Server {\n  const server = new Server({ name: \"registries\", version }, { capabilities: { tools: {} } });\n\n  server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [...toolListings] }));\n\n  server.setRequestHandler(CallToolRequestSchema, (request, extra) =>\n    callTool(request.params.name, request.params.arguments ?? {}, extra.signal),\n  );\n\n  return server;\n}\n"],"mappings":";;;;;AAwBA,MAAM,OAAOA,SAAY;CACvB,WAAW;CACX,WAAW;CACX,aAAa;AACf,CAAC;AAED,MAAM,aAAaC,SAAY,EAAE,MAAM,KAAK,GAAG,EAAE,sBAAsB,MAAM,CAAC;AAC9E,MAAM,qBAAqBA,SACzB;CACE,OAAOC,QAAW,MAAM;EAAE,UAAU;EAAG,UAAA;CAA4B,CAAC;CACpE,aAAaC,SAAcC,QAAa;EAAE,SAAS;EAAG,SAAA;CAA8B,CAAC,CAAC;AACxF,GACA,EAAE,sBAAsB,MAAM,CAChC;AACA,MAAM,cAAcH,SAAY,CAAC,GAAG,EAAE,sBAAsB,MAAM,CAAC;AAEnE,MAAM,cAA+B;CACnC,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,eAAe;AACjB;AACA,MAAM,aAA8B;CAClC,cAAc;CACd,iBAAiB;CACjB,gBAAgB;CAChB,eAAe;AACjB;AAeA,SAAS,WAA8B,MAAkD;CACvF,OAAO;AACT;AAEA,MAAM,QAAQ;CACZ,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;CACD,WAAW;EACT,MAAM;EACN,OAAO;EACP,aAAa;EACb,aAAa;EACb,aAAa;EACb,SAAS;CACX,CAAC;AACH;AAIA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;AAEA,SAAS,cAAc,OAAuB;CAC5C,OAAO,MAAM,KAAK,KAAK,CAAC,CACrB,KAAK,cAAc;EAClB,MAAM,OAAO,UAAU,YAAY,CAAC,KAAK;EACzC,OAAO,QAAQ,MAAO,QAAQ,OAAO,QAAQ,MAAO,MAAM;CAC5D,CAAC,CAAC,CACD,KAAK,EAAE;AACZ;AAEA,SAAS,YAAY,MAA8B;CACjD,OAAO;EAAE,SAAS,CAAC;GAAE,MAAM;GAAQ,MAAM,cAAc,IAAI;EAAE,CAAC;EAAG,SAAS;CAAK;AACjF;AAEA,SAAS,iBAAiB,QAA6C;CACrE,OAAO;EAAE,SAAS,OAAO;EAAS,GAAI,OAAO,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;CAAG;AACjF;;;;;CAQA,MAAA,KAAS;CACP,OAAO,KAAA;CACT,aAAA,KAAA;;CAGA,aAAa,KAAA;AACX,EAAA;AACA,MAAA,cAAY,IAAA,IAAA,MAAA,KAAA,SAAA,CAAA,KAAA,MAAA,IAAA,CAAA,CAAA;AAEZ,eAAa,SAAA,MAAY,MAAK,QAAW,QAAA;CACzC,MAAA,OAAa,YAAK,IAAA,IAAA;CACpB,IAAE,CAAA,MAAA,OAAA,YAAA,4BAAA,MAAA;CAEF,MAAM,EAAA,UAAA,MAAkB,OAA6B;;;;;;;;;AAWrD,SAAA,kBACE;CAKA,MAAM,SAAO,IAAA,OAAY;EACzB,MAAK;EAEL;CACA,GAAA,EAAK,cAAY,EAAA,OAAK,CAAA,EAAA,EAAA,CAAA;CAItB,OAAI,kBAAA,+BAAA,EAAA,OAAA,CAAA,GAAA,YAAA,EAAA,EAAA;;CAEF,OAAM;AACN;AAEA,SAAO,UAAA,iBAAyB"}