@bridgent/source-openapi 0.1.0 → 0.2.1

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/dist/index.d.mts CHANGED
@@ -6,13 +6,20 @@ interface BearerAuth {
6
6
  type: 'bearer';
7
7
  token: string | (() => string | Promise<string>);
8
8
  }
9
+ interface ApiKeyAuth {
10
+ type: 'apiKey';
11
+ in: 'header' | 'query' | 'cookie';
12
+ name: string;
13
+ value: string | (() => string | Promise<string>);
14
+ }
15
+ type OpenApiAuth = BearerAuth | ApiKeyAuth;
9
16
  interface FromOpenApiOptions {
10
17
  /** Spec source: file path, URL, JSON object, or YAML/JSON string. */
11
18
  spec: string | Record<string, unknown>;
12
19
  /** Override `spec.servers[0].url` (e.g. sandbox vs prod). */
13
20
  baseUrl?: string;
14
- /** Authentication. v0.1 supports Bearer only. */
15
- auth?: BearerAuth;
21
+ /** Authentication. Bearer and API-key header/query/cookie are supported. */
22
+ auth?: OpenApiAuth;
16
23
  /** Tool name namespace prefix. e.g. `gh_` to avoid collisions across sources. */
17
24
  namespace?: string;
18
25
  /** Method allowlist. Default: GET/HEAD only (read-only). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/from-openapi.ts","../src/parse-openapi.ts"],"mappings":";;;KAAY,UAAA;AAAA,UAKK,UAAA;EACf,IAAA;EACA,KAAA,2BAAgC,OAAO;AAAA;AAAA,UAGxB,kBAAA;EALA;EAOf,IAAA,WAAe,MAAA;;EAGf,OAAA;EATA;EAYA,IAAA,GAAO,UAAA;EAXyB;EAchC,SAAA;EAduC;EAiBvC,KAAA;IAdiC,uDAgB/B,QAAA,YAda;IAgBb,OAAA,GAAU,UAAA;EAAA;EAUC;EANb,eAAA;EAY+B;EAT/B,cAAA;EAvBA;EA0BA,UAAA,GAAa,MAAA,KAAW,IAAA;EAvBxB;EA0BA,iBAAA;EAvBO;EA0BP,KAAA,UAAe,UAAA,CAAW,KAAA;AAAA;;;;AA5C5B;;;;AAAsB;AAKtB;iBCWsB,WAAA,CACpB,OAAA,EAAS,kBAAA,GACR,OAAA,CAAQ,YAAA;;;cC+BE,iBAAA,SAA0B,KAAA;EAAA,SAInB,MAAA,EAAQ,aAAA;IAAgB,OAAA;IAAiB,IAAA;EAAA;EAHlD,IAAA;cAEP,OAAA,UACgB,MAAA,EAAQ,aAAA;IAAgB,OAAA;IAAiB,IAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/from-openapi.ts","../src/parse-openapi.ts"],"mappings":";;;KAAY,UAAA;AAAA,UAKK,UAAA;EACf,IAAA;EACA,KAAA,2BAAgC,OAAO;AAAA;AAAA,UAGxB,UAAA;EACf,IAAA;EACA,EAAA;EACA,IAAA;EACA,KAAA,2BAAgC,OAAO;AAAA;AAAA,KAG7B,WAAA,GAAc,UAAA,GAAa,UAAU;AAAA,UAEhC,kBAAA;EAZwB;EAcvC,IAAA,WAAe,MAAA;EAXA;EAcf,OAAA;;EAGA,IAAA,GAAO,WAAA;EAhBP;EAmBA,SAAA;EAjBA;EAoBA,KAAA;IAnBgC,uDAqB9B,QAAA,YArBqC;IAuBrC,OAAA,GAAU,UAAA;EAAA;;EAIZ,eAAA;EAxB+C;EA2B/C,cAAA;EAzBiC;EA4BjC,UAAA,GAAa,MAAA,KAAW,IAAA;EA1BT;EA6Bf,iBAAA;EAbY;EAgBZ,KAAA,UAAe,UAAA,CAAW,KAAA;AAAA;;;;AArD5B;;;;AAAsB;AAKtB;iBCWsB,WAAA,CACpB,OAAA,EAAS,kBAAA,GACR,OAAA,CAAQ,YAAA;;;cC+BE,iBAAA,SAA0B,KAAA;EAAA,SAInB,MAAA,EAAQ,aAAA;IAAgB,OAAA;IAAiB,IAAA;EAAA;EAHlD,IAAA;cAEP,OAAA,UACgB,MAAA,EAAQ,aAAA;IAAgB,OAAA;IAAiB,IAAA;EAAA;AAAA"}
package/dist/index.mjs CHANGED
@@ -47,7 +47,7 @@ function buildRequest(op, args, baseUrl) {
47
47
  const queryParams = new URLSearchParams();
48
48
  const headers = { Accept: "application/json" };
49
49
  for (const param of op.parameters) {
50
- const raw = args[param.name];
50
+ const raw = args[param.inputKey ?? param.name];
51
51
  if (raw === void 0 || raw === null) {
52
52
  if (param.required && param.in === "path") throw new Error(`Missing required path param "${param.name}" for ${op.operationId}`);
53
53
  continue;
@@ -85,11 +85,8 @@ function buildRequest(op, args, baseUrl) {
85
85
  /** Send a built request and package the response as a structured result. */
86
86
  async function invokeRequest(built, opts) {
87
87
  const headers = { ...built.headers };
88
- if (opts.auth?.type === "bearer") {
89
- const token = typeof opts.auth.token === "function" ? await opts.auth.token() : opts.auth.token;
90
- if (token) headers.Authorization = `Bearer ${token}`;
91
- }
92
- const response = await opts.fetch(built.url, {
88
+ const url = await applyAuth(built.url, headers, opts.auth);
89
+ const response = await opts.fetch(url, {
93
90
  method: built.method,
94
91
  headers,
95
92
  body: built.body
@@ -114,6 +111,34 @@ async function invokeRequest(built, opts) {
114
111
  headers: responseHeaders
115
112
  };
116
113
  }
114
+ async function applyAuth(rawUrl, headers, auth) {
115
+ if (!auth) return rawUrl;
116
+ if (auth.type === "bearer") {
117
+ const token = await resolveSecret(auth.token);
118
+ if (token) headers.Authorization = `Bearer ${token}`;
119
+ return rawUrl;
120
+ }
121
+ const value = await resolveSecret(auth.value);
122
+ if (!value) return rawUrl;
123
+ switch (auth.in) {
124
+ case "header":
125
+ headers[auth.name] = value;
126
+ return rawUrl;
127
+ case "query": {
128
+ const url = new URL(rawUrl);
129
+ url.searchParams.set(auth.name, value);
130
+ return url.toString();
131
+ }
132
+ case "cookie": {
133
+ const next = `${auth.name}=${value}`;
134
+ headers.Cookie = headers.Cookie ? `${headers.Cookie}; ${next}` : next;
135
+ return rawUrl;
136
+ }
137
+ }
138
+ }
139
+ async function resolveSecret(secret) {
140
+ return typeof secret === "function" ? await secret() : secret;
141
+ }
117
142
  function trimTrailingSlash(url) {
118
143
  return url.endsWith("/") ? url.slice(0, -1) : url;
119
144
  }
@@ -257,6 +282,7 @@ function buildInputSchema(op) {
257
282
  const baseSchema = jsonSchemaToZod(param.schema ?? { type: "string" });
258
283
  const described = param.description ? baseSchema.describe(param.description) : baseSchema;
259
284
  const key = pickInputKey(shape, param.name, param.in);
285
+ param.inputKey = key;
260
286
  shape[key] = param.required ? described : described.optional();
261
287
  }
262
288
  if (op.requestBody) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/types.ts","../src/filter.ts","../src/http.ts","../src/jsonschema-to-zod.ts","../src/operation-to-tool.ts","../src/parse-openapi.ts","../src/slug.ts","../src/from-openapi.ts"],"sourcesContent":["export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS'\n\nexport const SAFE_METHODS: HttpMethod[] = ['GET', 'HEAD']\nexport const MUTATING_METHODS: HttpMethod[] = ['POST', 'PUT', 'PATCH', 'DELETE']\n\nexport interface BearerAuth {\n type: 'bearer'\n token: string | (() => string | Promise<string>)\n}\n\nexport interface FromOpenApiOptions {\n /** Spec source: file path, URL, JSON object, or YAML/JSON string. */\n spec: string | Record<string, unknown>\n\n /** Override `spec.servers[0].url` (e.g. sandbox vs prod). */\n baseUrl?: string\n\n /** Authentication. v0.1 supports Bearer only. */\n auth?: BearerAuth\n\n /** Tool name namespace prefix. e.g. `gh_` to avoid collisions across sources. */\n namespace?: string\n\n /** Method allowlist. Default: GET/HEAD only (read-only). */\n allow?: {\n /** When `true`, also exposes POST/PUT/PATCH/DELETE. */\n mutating?: boolean\n /** Explicit method list. Overrides `mutating` when set. */\n methods?: HttpMethod[]\n }\n\n /** Operation allowlist by `operationId`. When non-empty, ONLY these are exposed. */\n allowOperations?: string[]\n\n /** Operation denylist by `operationId`. Applied after `allowOperations`. */\n denyOperations?: string[]\n\n /** Path filter. Cuts down enormous specs (e.g. GitHub). */\n pathFilter?: RegExp | ((path: string) => boolean)\n\n /** Whether to honor `x-bridgent-allow: false` on operations. Default: true. */\n respectExtensions?: boolean\n\n /** Custom fetch (for testing or proxying). Default: `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch\n}\n\n/** Internal: a normalized operation ready to be transformed into a BridgentTool. */\nexport interface NormalizedOperation {\n operationId: string\n method: HttpMethod\n path: string\n summary?: string\n description?: string\n parameters: ParameterObject[]\n requestBody?: RequestBodyObject\n raw: OperationObject\n}\n\nexport interface ParameterObject {\n name: string\n in: 'path' | 'query' | 'header' | 'cookie'\n required?: boolean\n description?: string\n schema?: Record<string, unknown>\n}\n\nexport interface RequestBodyObject {\n description?: string\n required?: boolean\n content?: Record<string, { schema?: Record<string, unknown> }>\n}\n\nexport interface OperationObject {\n operationId?: string\n summary?: string\n description?: string\n parameters?: ParameterObject[]\n requestBody?: RequestBodyObject\n responses?: Record<string, unknown>\n [extension: `x-${string}`]: unknown\n}\n","import type { FromOpenApiOptions, HttpMethod, OperationObject } from './types'\nimport { MUTATING_METHODS, SAFE_METHODS } from './types'\n\nexport interface FilterContext {\n path: string\n method: HttpMethod\n operation: OperationObject\n}\n\n/**\n * Apply the filtering pipeline:\n * 1. method ∈ allow.methods (default GET/HEAD)\n * 2. pathFilter\n * 3. respectExtensions && op['x-bridgent-allow'] === false → drop\n * 4. denyOperations\n * 5. allowOperations (if non-empty, gate)\n */\nexport function shouldExposeOperation(\n ctx: FilterContext,\n opts: FromOpenApiOptions,\n): boolean {\n const allowedMethods = resolveAllowedMethods(opts)\n if (!allowedMethods.includes(ctx.method))\n return false\n\n if (opts.pathFilter) {\n const passes = typeof opts.pathFilter === 'function'\n ? opts.pathFilter(ctx.path)\n : opts.pathFilter.test(ctx.path)\n if (!passes)\n return false\n }\n\n const respectExt = opts.respectExtensions ?? true\n if (respectExt && ctx.operation['x-bridgent-allow'] === false)\n return false\n\n const opId = ctx.operation.operationId\n if (opId && opts.denyOperations?.includes(opId))\n return false\n\n if (opts.allowOperations && opts.allowOperations.length > 0) {\n if (!opId || !opts.allowOperations.includes(opId))\n return false\n }\n\n return true\n}\n\nexport function resolveAllowedMethods(opts: FromOpenApiOptions): HttpMethod[] {\n if (opts.allow?.methods)\n return opts.allow.methods\n\n if (opts.allow?.mutating)\n return [...SAFE_METHODS, ...MUTATING_METHODS]\n\n return [...SAFE_METHODS]\n}\n","import type { BearerAuth, NormalizedOperation } from './types'\n\nexport interface BuiltRequest {\n url: string\n method: string\n headers: Record<string, string>\n body?: string\n}\n\nexport interface InvokeOptions {\n baseUrl: string\n auth?: BearerAuth\n fetch: typeof globalThis.fetch\n}\n\n/** Build a fetch-ready request from flattened tool args + an OpenAPI operation. */\nexport function buildRequest(\n op: NormalizedOperation,\n args: Record<string, unknown>,\n baseUrl: string,\n): BuiltRequest {\n const pathParams: Record<string, string> = {}\n const queryParams = new URLSearchParams()\n const headers: Record<string, string> = { Accept: 'application/json' }\n\n for (const param of op.parameters) {\n const raw = args[param.name]\n if (raw === undefined || raw === null) {\n if (param.required && param.in === 'path')\n throw new Error(`Missing required path param \"${param.name}\" for ${op.operationId}`)\n continue\n }\n const value = String(raw)\n switch (param.in) {\n case 'path':\n pathParams[param.name] = value\n break\n case 'query':\n if (Array.isArray(raw)) {\n for (const v of raw) queryParams.append(param.name, String(v))\n }\n else {\n queryParams.set(param.name, value)\n }\n break\n case 'header':\n headers[param.name] = value\n break\n case 'cookie':\n // Cookies aren't first-class for v0.1; skip silently.\n break\n }\n }\n\n // Path interpolation\n let path = op.path\n for (const [key, value] of Object.entries(pathParams)) {\n path = path.replace(`{${key}}`, encodeURIComponent(value))\n }\n\n // Body (only when requestBody declared and `body` arg present)\n let body: string | undefined\n if (op.requestBody && args.body !== undefined) {\n body = JSON.stringify(args.body)\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json'\n }\n\n const qs = queryParams.toString()\n const url = `${trimTrailingSlash(baseUrl)}${path}${qs ? `?${qs}` : ''}`\n\n return { url, method: op.method, headers, body }\n}\n\n/** Send a built request and package the response as a structured result. */\nexport async function invokeRequest(\n built: BuiltRequest,\n opts: InvokeOptions,\n): Promise<{\n ok: boolean\n status: number\n statusText: string\n body: unknown\n headers: Record<string, string>\n}> {\n const headers = { ...built.headers }\n if (opts.auth?.type === 'bearer') {\n const token = typeof opts.auth.token === 'function'\n ? await opts.auth.token()\n : opts.auth.token\n if (token)\n headers.Authorization = `Bearer ${token}`\n }\n\n const response = await opts.fetch(built.url, {\n method: built.method,\n headers,\n body: built.body,\n })\n\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n const text = await response.text()\n let parsedBody: unknown\n const contentType = responseHeaders['content-type'] ?? ''\n if (contentType.includes('application/json')) {\n try {\n parsedBody = text.length > 0 ? JSON.parse(text) : null\n }\n catch {\n parsedBody = text\n }\n }\n else {\n // Non-JSON: truncate to ~64KB to avoid blowing up tool responses.\n parsedBody = text.length > 65_536 ? `${text.slice(0, 65_536)}…[truncated]` : text\n }\n\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n body: parsedBody,\n headers: responseHeaders,\n }\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.endsWith('/') ? url.slice(0, -1) : url\n}\n","import { z } from 'zod'\n\ntype JsonSchema = Record<string, unknown> & {\n type?: string | string[]\n enum?: unknown[]\n const?: unknown\n oneOf?: JsonSchema[]\n anyOf?: JsonSchema[]\n allOf?: JsonSchema[]\n nullable?: boolean\n description?: string\n default?: unknown\n format?: string\n pattern?: string\n minLength?: number\n maxLength?: number\n minimum?: number\n maximum?: number\n exclusiveMinimum?: number | boolean\n exclusiveMaximum?: number | boolean\n items?: JsonSchema\n properties?: Record<string, JsonSchema>\n required?: string[]\n additionalProperties?: boolean | JsonSchema\n}\n\n/**\n * Convert a JSON Schema (OpenAPI 3.0/3.1 subset) into a Zod schema.\n *\n * Coverage: object/array/string/number/integer/boolean/enum/const/oneOf/anyOf/\n * allOf-merge/nullable/format(email|uuid|date-time|url)/min-max/required/\n * additionalProperties.\n *\n * Out of scope (v0.1): discriminator (falls back to z.union).\n */\nexport function jsonSchemaToZod(input: JsonSchema | undefined | null): z.ZodTypeAny {\n if (!input || typeof input !== 'object')\n return z.any()\n\n // 3.1: type can be array including 'null'\n if (Array.isArray(input.type) && input.type.includes('null')) {\n const rest = input.type.filter(t => t !== 'null')\n const next: JsonSchema = {\n ...input,\n type: rest.length === 1 ? rest[0] : rest,\n }\n return describe(jsonSchemaToZod(next).nullable(), input.description)\n }\n\n // 3.0: nullable: true\n if (input.nullable === true) {\n const { nullable, ...rest } = input\n return describe(jsonSchemaToZod(rest).nullable(), input.description)\n }\n\n // const literal (3.1)\n if ('const' in input && input.const !== undefined)\n return describe(z.literal(input.const as never), input.description)\n\n // enum\n if (Array.isArray(input.enum) && input.enum.length > 0) {\n const allStrings = input.enum.every(v => typeof v === 'string')\n if (allStrings) {\n const values = input.enum as [string, ...string[]]\n return describe(z.enum(values), input.description)\n }\n // mixed-type enum → union of literals\n const variants = input.enum.map(v => z.literal(v as never)) as unknown as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]\n return describe(z.union(variants), input.description)\n }\n\n // oneOf / anyOf\n if (Array.isArray(input.oneOf) || Array.isArray(input.anyOf)) {\n const variants = (input.oneOf ?? input.anyOf!).map(jsonSchemaToZod)\n if (variants.length === 1)\n return describe(variants[0]!, input.description)\n return describe(\n z.union(variants as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]),\n input.description,\n )\n }\n\n // allOf — shallow object merge (sufficient for v0.1 OpenAPI usage)\n if (Array.isArray(input.allOf) && input.allOf.length > 0) {\n const merged: JsonSchema = { type: 'object', properties: {}, required: [] }\n for (const part of input.allOf) {\n if (part.properties)\n merged.properties = { ...merged.properties, ...part.properties }\n if (Array.isArray(part.required))\n merged.required = [...(merged.required ?? []), ...part.required]\n }\n if (input.description)\n merged.description = input.description\n return jsonSchemaToZod(merged)\n }\n\n const type = Array.isArray(input.type) ? input.type[0] : input.type\n\n switch (type) {\n case 'string':\n return describe(buildString(input), input.description)\n case 'integer':\n case 'number':\n return describe(buildNumber(input, type === 'integer'), input.description)\n case 'boolean':\n return describe(z.boolean(), input.description)\n case 'array':\n return describe(z.array(jsonSchemaToZod(input.items)), input.description)\n case 'object':\n default:\n return describe(buildObject(input), input.description)\n }\n}\n\nfunction buildString(s: JsonSchema): z.ZodTypeAny {\n let zs: z.ZodString = z.string()\n switch (s.format) {\n case 'email':\n zs = zs.email()\n break\n case 'uuid':\n zs = zs.uuid()\n break\n case 'date-time':\n zs = zs.datetime({ offset: true })\n break\n case 'uri':\n case 'url':\n zs = zs.url()\n break\n }\n if (typeof s.minLength === 'number')\n zs = zs.min(s.minLength)\n if (typeof s.maxLength === 'number')\n zs = zs.max(s.maxLength)\n if (typeof s.pattern === 'string') {\n try {\n zs = zs.regex(new RegExp(s.pattern))\n }\n catch {\n // ignore invalid regex; tolerate malformed specs\n }\n }\n return zs\n}\n\nfunction buildNumber(s: JsonSchema, integer: boolean): z.ZodTypeAny {\n let zn: z.ZodNumber = z.number()\n if (integer)\n zn = zn.int()\n if (typeof s.minimum === 'number')\n zn = zn.min(s.minimum)\n if (typeof s.maximum === 'number')\n zn = zn.max(s.maximum)\n if (typeof s.exclusiveMinimum === 'number')\n zn = zn.gt(s.exclusiveMinimum)\n if (typeof s.exclusiveMaximum === 'number')\n zn = zn.lt(s.exclusiveMaximum)\n return zn\n}\n\nfunction buildObject(s: JsonSchema): z.ZodTypeAny {\n const props = s.properties ?? {}\n const required = new Set<string>(s.required ?? [])\n const shape: Record<string, z.ZodTypeAny> = {}\n\n for (const [key, value] of Object.entries(props)) {\n const inner = jsonSchemaToZod(value)\n shape[key] = required.has(key) ? inner : inner.optional()\n }\n\n let obj: z.ZodTypeAny = z.object(shape)\n\n // additionalProperties\n if (s.additionalProperties === true) {\n // passthrough lets unknown keys through verbatim\n obj = (obj as z.ZodObject<z.ZodRawShape>).passthrough()\n }\n else if (typeof s.additionalProperties === 'object' && s.additionalProperties !== null) {\n // allow specific shape for unknown keys; still keep declared props strict\n obj = (obj as z.ZodObject<z.ZodRawShape>).catchall(jsonSchemaToZod(s.additionalProperties))\n }\n\n return obj\n}\n\nfunction describe(schema: z.ZodTypeAny, description: string | undefined): z.ZodTypeAny {\n return description ? schema.describe(description) : schema\n}\n","import type { BridgentTool } from '@bridgent/core'\nimport type { BearerAuth, NormalizedOperation } from './types'\nimport { defineTool } from '@bridgent/core'\nimport { z } from 'zod'\nimport { buildRequest, invokeRequest } from './http'\nimport { jsonSchemaToZod } from './jsonschema-to-zod'\n\nexport interface BuildToolOptions {\n baseUrl: string\n auth?: BearerAuth\n fetch: typeof globalThis.fetch\n toolName: string\n}\n\n/** Convert a normalized OpenAPI operation into a BridgentTool. */\nexport function operationToTool(\n op: NormalizedOperation,\n opts: BuildToolOptions,\n): BridgentTool {\n const inputSchema = buildInputSchema(op)\n const description = op.summary ?? op.description ?? `${op.method} ${op.path}`\n\n return defineTool({\n name: opts.toolName,\n description: description.slice(0, 1024),\n inputSchema,\n run: async (args) => {\n const request = buildRequest(op, args as Record<string, unknown>, opts.baseUrl)\n return invokeRequest(request, {\n baseUrl: opts.baseUrl,\n auth: opts.auth,\n fetch: opts.fetch,\n })\n },\n })\n}\n\n/** Flatten path/query/header params + body into a single z.object(). */\nfunction buildInputSchema(op: NormalizedOperation): z.ZodObject<z.ZodRawShape> {\n const shape: Record<string, z.ZodTypeAny> = {}\n\n for (const param of op.parameters) {\n if (param.in === 'cookie')\n continue\n const baseSchema = jsonSchemaToZod(param.schema ?? { type: 'string' })\n const described = param.description\n ? baseSchema.describe(param.description)\n : baseSchema\n // Avoid name collisions across `in` types: prefix non-path duplicates.\n const key = pickInputKey(shape, param.name, param.in)\n shape[key] = param.required ? described : described.optional()\n }\n\n if (op.requestBody) {\n const json = op.requestBody.content?.['application/json']?.schema\n if (json) {\n const bodySchema = jsonSchemaToZod(json)\n shape.body = op.requestBody.required ? bodySchema : bodySchema.optional()\n }\n }\n\n return z.object(shape)\n}\n\nfunction pickInputKey(\n shape: Record<string, z.ZodTypeAny>,\n name: string,\n location: 'path' | 'query' | 'header' | 'cookie',\n): string {\n if (!(name in shape))\n return name\n // path-collisions are unusual; for query/header collisions, prefix to stay unique.\n return `${location}_${name}`\n}\n","import { dereference, load } from '@scalar/openapi-parser'\nimport { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls'\nimport { readFiles } from '@scalar/openapi-parser/plugins/read-files'\n\nexport interface DereferencedSpec {\n /** Top-level OpenAPI document with all `$ref`s resolved. */\n document: Record<string, any>\n /** Detected version, e.g. '3.0' / '3.1'. */\n version?: string\n}\n\n/**\n * Load + dereference any OpenAPI 3.x source.\n *\n * Accepts:\n * - URL string (https://…)\n * - File path (./openapi.yaml, /abs/path.json)\n * - Inline JSON object\n * - YAML / JSON string\n *\n * Errors during load/dereference are collected; the function throws if the\n * spec cannot be turned into a usable document.\n */\nexport async function parseOpenApi(\n source: string | Record<string, unknown>,\n): Promise<DereferencedSpec> {\n // For object input, dereference accepts it directly.\n if (typeof source !== 'string') {\n const result = dereference(source as Record<string, unknown>)\n if (!result.schema)\n throw new OpenApiParseError('dereference returned no schema', result.errors ?? [])\n return { document: result.schema as Record<string, any>, version: result.version }\n }\n\n // For string input (URL / file path / raw text), let `load` figure it out.\n const loaded = await load(source, {\n plugins: [readFiles(), fetchUrls()],\n })\n\n if (!loaded.specification)\n throw new OpenApiParseError(`Failed to load spec from ${source}`, loaded.errors ?? [])\n\n const result = dereference(loaded.filesystem)\n if (!result.schema)\n throw new OpenApiParseError('dereference returned no schema', result.errors ?? [])\n\n return { document: result.schema as Record<string, any>, version: result.version }\n}\n\nexport class OpenApiParseError extends Error {\n override name = 'OpenApiParseError'\n constructor(\n message: string,\n public readonly errors: ReadonlyArray<{ message: string, path?: string[] }>,\n ) {\n super(`${message}${errors.length ? `: ${errors.map(e => e.message).join('; ')}` : ''}`)\n }\n}\n","/**\n * Generate an MCP-tool-name from an OpenAPI operation.\n *\n * Strategy:\n * 1. Prefer `operationId` (slugified, capped at 64 chars).\n * 2. Fallback: `${method}_${path-with-braces-stripped-and-slashes-as-underscores}`.\n *\n * The result must match `^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$` to play nicely with\n * Anthropic / Claude Code / Cursor / Gemini CLI tool registries.\n */\n\nconst TOOL_NAME_RE = /^[a-z_][\\w-]{0,63}$/i\n\nexport function operationToToolName(opts: {\n operationId?: string\n method: string\n path: string\n namespace?: string\n}): string {\n const namespace = opts.namespace ?? ''\n const base = opts.operationId\n ? slug(opts.operationId)\n : `${opts.method.toLowerCase()}_${slugPath(opts.path)}`\n\n return capName(`${namespace}${base}`)\n}\n\nfunction slug(input: string): string {\n // Replace any disallowed character with `_`, collapse repeats, trim.\n return input\n .replace(/[^\\w-]+/g, '_')\n .replace(/^_+|_+$/g, '')\n .replace(/_{2,}/g, '_')\n}\n\nfunction slugPath(path: string): string {\n return slug(\n path\n .replace(/^\\//, '')\n .replace(/\\{([^}]+)\\}/g, '$1') // {id} -> id\n .replace(/\\//g, '_'),\n )\n}\n\nfunction capName(name: string): string {\n let n = name.slice(0, 64)\n // Ensure it starts with a letter or underscore.\n if (!/^[a-z_]/i.test(n))\n n = `_${n}`.slice(0, 64)\n if (!TOOL_NAME_RE.test(n))\n return slug(n).slice(0, 64) || '_tool'\n return n\n}\n\nexport function isValidToolName(name: string): boolean {\n return TOOL_NAME_RE.test(name)\n}\n","import type { BridgentTool } from '@bridgent/core'\nimport type { FromOpenApiOptions, HttpMethod, NormalizedOperation, OperationObject, ParameterObject, RequestBodyObject } from './types'\nimport { shouldExposeOperation } from './filter'\nimport { operationToTool } from './operation-to-tool'\nimport { parseOpenApi } from './parse-openapi'\nimport { operationToToolName } from './slug'\n\nconst HTTP_METHODS: readonly HttpMethod[] = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'] as const\n\n/**\n * Turn an OpenAPI 3.x spec into a list of BridgentTools, ready to feed into\n * `createStdioServer({ tools })`.\n *\n * Read-only by default — to expose mutating operations, set `allow.mutating: true`\n * (or use `allowOperations` allowlist).\n */\nexport async function fromOpenApi(\n options: FromOpenApiOptions,\n): Promise<BridgentTool[]> {\n const { document } = await parseOpenApi(options.spec)\n\n const baseUrl = options.baseUrl ?? extractBaseUrl(document)\n if (!baseUrl)\n throw new Error('No baseUrl could be determined from the spec; pass `baseUrl` explicitly.')\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl)\n throw new Error('No fetch implementation available. Pass `options.fetch` or run on Node ≥ 22.18.')\n\n const tools: BridgentTool[] = []\n const seenNames = new Set<string>()\n\n const paths = (document.paths ?? {}) as Record<string, Record<string, OperationObject>>\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== 'object')\n continue\n\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method.toLowerCase()] as OperationObject | undefined\n if (!operation)\n continue\n\n const ctx = { path, method, operation }\n if (!shouldExposeOperation(ctx, options))\n continue\n\n const normalized = normalizeOperation(path, method, operation)\n const toolName = operationToToolName({\n operationId: normalized.operationId,\n method: normalized.method,\n path: normalized.path,\n namespace: options.namespace,\n })\n\n if (seenNames.has(toolName)) {\n throw new Error(\n `Duplicate tool name \"${toolName}\" generated. `\n + `Provide a \\`namespace\\` option, or rename the operationId in the spec.`,\n )\n }\n seenNames.add(toolName)\n\n tools.push(operationToTool(normalized, {\n baseUrl,\n auth: options.auth,\n fetch: fetchImpl,\n toolName,\n }))\n }\n }\n\n return tools\n}\n\nfunction normalizeOperation(\n path: string,\n method: HttpMethod,\n raw: OperationObject,\n): NormalizedOperation {\n return {\n operationId: raw.operationId ?? `${method.toLowerCase()}_${path}`,\n method,\n path,\n summary: raw.summary,\n description: raw.description,\n parameters: (raw.parameters ?? []) as ParameterObject[],\n requestBody: raw.requestBody as RequestBodyObject | undefined,\n raw,\n }\n}\n\nfunction extractBaseUrl(document: Record<string, any>): string | undefined {\n const servers = document.servers as Array<{ url?: string }> | undefined\n return servers?.[0]?.url\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/types.ts","../src/filter.ts","../src/http.ts","../src/jsonschema-to-zod.ts","../src/operation-to-tool.ts","../src/parse-openapi.ts","../src/slug.ts","../src/from-openapi.ts"],"sourcesContent":["export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS'\n\nexport const SAFE_METHODS: HttpMethod[] = ['GET', 'HEAD']\nexport const MUTATING_METHODS: HttpMethod[] = ['POST', 'PUT', 'PATCH', 'DELETE']\n\nexport interface BearerAuth {\n type: 'bearer'\n token: string | (() => string | Promise<string>)\n}\n\nexport interface ApiKeyAuth {\n type: 'apiKey'\n in: 'header' | 'query' | 'cookie'\n name: string\n value: string | (() => string | Promise<string>)\n}\n\nexport type OpenApiAuth = BearerAuth | ApiKeyAuth\n\nexport interface FromOpenApiOptions {\n /** Spec source: file path, URL, JSON object, or YAML/JSON string. */\n spec: string | Record<string, unknown>\n\n /** Override `spec.servers[0].url` (e.g. sandbox vs prod). */\n baseUrl?: string\n\n /** Authentication. Bearer and API-key header/query/cookie are supported. */\n auth?: OpenApiAuth\n\n /** Tool name namespace prefix. e.g. `gh_` to avoid collisions across sources. */\n namespace?: string\n\n /** Method allowlist. Default: GET/HEAD only (read-only). */\n allow?: {\n /** When `true`, also exposes POST/PUT/PATCH/DELETE. */\n mutating?: boolean\n /** Explicit method list. Overrides `mutating` when set. */\n methods?: HttpMethod[]\n }\n\n /** Operation allowlist by `operationId`. When non-empty, ONLY these are exposed. */\n allowOperations?: string[]\n\n /** Operation denylist by `operationId`. Applied after `allowOperations`. */\n denyOperations?: string[]\n\n /** Path filter. Cuts down enormous specs (e.g. GitHub). */\n pathFilter?: RegExp | ((path: string) => boolean)\n\n /** Whether to honor `x-bridgent-allow: false` on operations. Default: true. */\n respectExtensions?: boolean\n\n /** Custom fetch (for testing or proxying). Default: `globalThis.fetch`. */\n fetch?: typeof globalThis.fetch\n}\n\n/** Internal: a normalized operation ready to be transformed into a BridgentTool. */\nexport interface NormalizedOperation {\n operationId: string\n method: HttpMethod\n path: string\n summary?: string\n description?: string\n parameters: ParameterObject[]\n requestBody?: RequestBodyObject\n raw: OperationObject\n}\n\nexport interface ParameterObject {\n name: string\n in: 'path' | 'query' | 'header' | 'cookie'\n inputKey?: string\n required?: boolean\n description?: string\n schema?: Record<string, unknown>\n}\n\nexport interface RequestBodyObject {\n description?: string\n required?: boolean\n content?: Record<string, { schema?: Record<string, unknown> }>\n}\n\nexport interface OperationObject {\n operationId?: string\n summary?: string\n description?: string\n parameters?: ParameterObject[]\n requestBody?: RequestBodyObject\n responses?: Record<string, unknown>\n [extension: `x-${string}`]: unknown\n}\n","import type { FromOpenApiOptions, HttpMethod, OperationObject } from './types'\nimport { MUTATING_METHODS, SAFE_METHODS } from './types'\n\nexport interface FilterContext {\n path: string\n method: HttpMethod\n operation: OperationObject\n}\n\n/**\n * Apply the filtering pipeline:\n * 1. method ∈ allow.methods (default GET/HEAD)\n * 2. pathFilter\n * 3. respectExtensions && op['x-bridgent-allow'] === false → drop\n * 4. denyOperations\n * 5. allowOperations (if non-empty, gate)\n */\nexport function shouldExposeOperation(\n ctx: FilterContext,\n opts: FromOpenApiOptions,\n): boolean {\n const allowedMethods = resolveAllowedMethods(opts)\n if (!allowedMethods.includes(ctx.method))\n return false\n\n if (opts.pathFilter) {\n const passes = typeof opts.pathFilter === 'function'\n ? opts.pathFilter(ctx.path)\n : opts.pathFilter.test(ctx.path)\n if (!passes)\n return false\n }\n\n const respectExt = opts.respectExtensions ?? true\n if (respectExt && ctx.operation['x-bridgent-allow'] === false)\n return false\n\n const opId = ctx.operation.operationId\n if (opId && opts.denyOperations?.includes(opId))\n return false\n\n if (opts.allowOperations && opts.allowOperations.length > 0) {\n if (!opId || !opts.allowOperations.includes(opId))\n return false\n }\n\n return true\n}\n\nexport function resolveAllowedMethods(opts: FromOpenApiOptions): HttpMethod[] {\n if (opts.allow?.methods)\n return opts.allow.methods\n\n if (opts.allow?.mutating)\n return [...SAFE_METHODS, ...MUTATING_METHODS]\n\n return [...SAFE_METHODS]\n}\n","import type { NormalizedOperation, OpenApiAuth } from './types'\n\nexport interface BuiltRequest {\n url: string\n method: string\n headers: Record<string, string>\n body?: string\n}\n\nexport interface InvokeOptions {\n baseUrl: string\n auth?: OpenApiAuth\n fetch: typeof globalThis.fetch\n}\n\n/** Build a fetch-ready request from flattened tool args + an OpenAPI operation. */\nexport function buildRequest(\n op: NormalizedOperation,\n args: Record<string, unknown>,\n baseUrl: string,\n): BuiltRequest {\n const pathParams: Record<string, string> = {}\n const queryParams = new URLSearchParams()\n const headers: Record<string, string> = { Accept: 'application/json' }\n\n for (const param of op.parameters) {\n const raw = args[param.inputKey ?? param.name]\n if (raw === undefined || raw === null) {\n if (param.required && param.in === 'path')\n throw new Error(`Missing required path param \"${param.name}\" for ${op.operationId}`)\n continue\n }\n const value = String(raw)\n switch (param.in) {\n case 'path':\n pathParams[param.name] = value\n break\n case 'query':\n if (Array.isArray(raw)) {\n for (const v of raw) queryParams.append(param.name, String(v))\n }\n else {\n queryParams.set(param.name, value)\n }\n break\n case 'header':\n headers[param.name] = value\n break\n case 'cookie':\n // Cookies aren't first-class for v0.1; skip silently.\n break\n }\n }\n\n // Path interpolation\n let path = op.path\n for (const [key, value] of Object.entries(pathParams)) {\n path = path.replace(`{${key}}`, encodeURIComponent(value))\n }\n\n // Body (only when requestBody declared and `body` arg present)\n let body: string | undefined\n if (op.requestBody && args.body !== undefined) {\n body = JSON.stringify(args.body)\n headers['Content-Type'] = headers['Content-Type'] ?? 'application/json'\n }\n\n const qs = queryParams.toString()\n const url = `${trimTrailingSlash(baseUrl)}${path}${qs ? `?${qs}` : ''}`\n\n return { url, method: op.method, headers, body }\n}\n\n/** Send a built request and package the response as a structured result. */\nexport async function invokeRequest(\n built: BuiltRequest,\n opts: InvokeOptions,\n): Promise<{\n ok: boolean\n status: number\n statusText: string\n body: unknown\n headers: Record<string, string>\n}> {\n const headers = { ...built.headers }\n const url = await applyAuth(built.url, headers, opts.auth)\n\n const response = await opts.fetch(url, {\n method: built.method,\n headers,\n body: built.body,\n })\n\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n const text = await response.text()\n let parsedBody: unknown\n const contentType = responseHeaders['content-type'] ?? ''\n if (contentType.includes('application/json')) {\n try {\n parsedBody = text.length > 0 ? JSON.parse(text) : null\n }\n catch {\n parsedBody = text\n }\n }\n else {\n // Non-JSON: truncate to ~64KB to avoid blowing up tool responses.\n parsedBody = text.length > 65_536 ? `${text.slice(0, 65_536)}…[truncated]` : text\n }\n\n return {\n ok: response.ok,\n status: response.status,\n statusText: response.statusText,\n body: parsedBody,\n headers: responseHeaders,\n }\n}\n\nasync function applyAuth(\n rawUrl: string,\n headers: Record<string, string>,\n auth: OpenApiAuth | undefined,\n): Promise<string> {\n if (!auth)\n return rawUrl\n\n if (auth.type === 'bearer') {\n const token = await resolveSecret(auth.token)\n if (token)\n headers.Authorization = `Bearer ${token}`\n return rawUrl\n }\n\n const value = await resolveSecret(auth.value)\n if (!value)\n return rawUrl\n\n switch (auth.in) {\n case 'header':\n headers[auth.name] = value\n return rawUrl\n case 'query': {\n const url = new URL(rawUrl)\n url.searchParams.set(auth.name, value)\n return url.toString()\n }\n case 'cookie': {\n const next = `${auth.name}=${value}`\n headers.Cookie = headers.Cookie ? `${headers.Cookie}; ${next}` : next\n return rawUrl\n }\n }\n}\n\nasync function resolveSecret(secret: string | (() => string | Promise<string>)): Promise<string> {\n return typeof secret === 'function' ? await secret() : secret\n}\n\nfunction trimTrailingSlash(url: string): string {\n return url.endsWith('/') ? url.slice(0, -1) : url\n}\n","import { z } from 'zod'\n\ntype JsonSchema = Record<string, unknown> & {\n type?: string | string[]\n enum?: unknown[]\n const?: unknown\n oneOf?: JsonSchema[]\n anyOf?: JsonSchema[]\n allOf?: JsonSchema[]\n nullable?: boolean\n description?: string\n default?: unknown\n format?: string\n pattern?: string\n minLength?: number\n maxLength?: number\n minimum?: number\n maximum?: number\n exclusiveMinimum?: number | boolean\n exclusiveMaximum?: number | boolean\n items?: JsonSchema\n properties?: Record<string, JsonSchema>\n required?: string[]\n additionalProperties?: boolean | JsonSchema\n}\n\n/**\n * Convert a JSON Schema (OpenAPI 3.0/3.1 subset) into a Zod schema.\n *\n * Coverage: object/array/string/number/integer/boolean/enum/const/oneOf/anyOf/\n * allOf-merge/nullable/format(email|uuid|date-time|url)/min-max/required/\n * additionalProperties.\n *\n * Out of scope (v0.1): discriminator (falls back to z.union).\n */\nexport function jsonSchemaToZod(input: JsonSchema | undefined | null): z.ZodTypeAny {\n if (!input || typeof input !== 'object')\n return z.any()\n\n // 3.1: type can be array including 'null'\n if (Array.isArray(input.type) && input.type.includes('null')) {\n const rest = input.type.filter(t => t !== 'null')\n const next: JsonSchema = {\n ...input,\n type: rest.length === 1 ? rest[0] : rest,\n }\n return describe(jsonSchemaToZod(next).nullable(), input.description)\n }\n\n // 3.0: nullable: true\n if (input.nullable === true) {\n const { nullable, ...rest } = input\n return describe(jsonSchemaToZod(rest).nullable(), input.description)\n }\n\n // const literal (3.1)\n if ('const' in input && input.const !== undefined)\n return describe(z.literal(input.const as never), input.description)\n\n // enum\n if (Array.isArray(input.enum) && input.enum.length > 0) {\n const allStrings = input.enum.every(v => typeof v === 'string')\n if (allStrings) {\n const values = input.enum as [string, ...string[]]\n return describe(z.enum(values), input.description)\n }\n // mixed-type enum → union of literals\n const variants = input.enum.map(v => z.literal(v as never)) as unknown as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]\n return describe(z.union(variants), input.description)\n }\n\n // oneOf / anyOf\n if (Array.isArray(input.oneOf) || Array.isArray(input.anyOf)) {\n const variants = (input.oneOf ?? input.anyOf!).map(jsonSchemaToZod)\n if (variants.length === 1)\n return describe(variants[0]!, input.description)\n return describe(\n z.union(variants as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]),\n input.description,\n )\n }\n\n // allOf — shallow object merge (sufficient for v0.1 OpenAPI usage)\n if (Array.isArray(input.allOf) && input.allOf.length > 0) {\n const merged: JsonSchema = { type: 'object', properties: {}, required: [] }\n for (const part of input.allOf) {\n if (part.properties)\n merged.properties = { ...merged.properties, ...part.properties }\n if (Array.isArray(part.required))\n merged.required = [...(merged.required ?? []), ...part.required]\n }\n if (input.description)\n merged.description = input.description\n return jsonSchemaToZod(merged)\n }\n\n const type = Array.isArray(input.type) ? input.type[0] : input.type\n\n switch (type) {\n case 'string':\n return describe(buildString(input), input.description)\n case 'integer':\n case 'number':\n return describe(buildNumber(input, type === 'integer'), input.description)\n case 'boolean':\n return describe(z.boolean(), input.description)\n case 'array':\n return describe(z.array(jsonSchemaToZod(input.items)), input.description)\n case 'object':\n default:\n return describe(buildObject(input), input.description)\n }\n}\n\nfunction buildString(s: JsonSchema): z.ZodTypeAny {\n let zs: z.ZodString = z.string()\n switch (s.format) {\n case 'email':\n zs = zs.email()\n break\n case 'uuid':\n zs = zs.uuid()\n break\n case 'date-time':\n zs = zs.datetime({ offset: true })\n break\n case 'uri':\n case 'url':\n zs = zs.url()\n break\n }\n if (typeof s.minLength === 'number')\n zs = zs.min(s.minLength)\n if (typeof s.maxLength === 'number')\n zs = zs.max(s.maxLength)\n if (typeof s.pattern === 'string') {\n try {\n zs = zs.regex(new RegExp(s.pattern))\n }\n catch {\n // ignore invalid regex; tolerate malformed specs\n }\n }\n return zs\n}\n\nfunction buildNumber(s: JsonSchema, integer: boolean): z.ZodTypeAny {\n let zn: z.ZodNumber = z.number()\n if (integer)\n zn = zn.int()\n if (typeof s.minimum === 'number')\n zn = zn.min(s.minimum)\n if (typeof s.maximum === 'number')\n zn = zn.max(s.maximum)\n if (typeof s.exclusiveMinimum === 'number')\n zn = zn.gt(s.exclusiveMinimum)\n if (typeof s.exclusiveMaximum === 'number')\n zn = zn.lt(s.exclusiveMaximum)\n return zn\n}\n\nfunction buildObject(s: JsonSchema): z.ZodTypeAny {\n const props = s.properties ?? {}\n const required = new Set<string>(s.required ?? [])\n const shape: Record<string, z.ZodTypeAny> = {}\n\n for (const [key, value] of Object.entries(props)) {\n const inner = jsonSchemaToZod(value)\n shape[key] = required.has(key) ? inner : inner.optional()\n }\n\n let obj: z.ZodTypeAny = z.object(shape)\n\n // additionalProperties\n if (s.additionalProperties === true) {\n // passthrough lets unknown keys through verbatim\n obj = (obj as z.ZodObject<z.ZodRawShape>).passthrough()\n }\n else if (typeof s.additionalProperties === 'object' && s.additionalProperties !== null) {\n // allow specific shape for unknown keys; still keep declared props strict\n obj = (obj as z.ZodObject<z.ZodRawShape>).catchall(jsonSchemaToZod(s.additionalProperties))\n }\n\n return obj\n}\n\nfunction describe(schema: z.ZodTypeAny, description: string | undefined): z.ZodTypeAny {\n return description ? schema.describe(description) : schema\n}\n","import type { BridgentTool } from '@bridgent/core'\nimport type { NormalizedOperation, OpenApiAuth } from './types'\nimport { defineTool } from '@bridgent/core'\nimport { z } from 'zod'\nimport { buildRequest, invokeRequest } from './http'\nimport { jsonSchemaToZod } from './jsonschema-to-zod'\n\nexport interface BuildToolOptions {\n baseUrl: string\n auth?: OpenApiAuth\n fetch: typeof globalThis.fetch\n toolName: string\n}\n\n/** Convert a normalized OpenAPI operation into a BridgentTool. */\nexport function operationToTool(\n op: NormalizedOperation,\n opts: BuildToolOptions,\n): BridgentTool {\n const inputSchema = buildInputSchema(op)\n const description = op.summary ?? op.description ?? `${op.method} ${op.path}`\n\n return defineTool({\n name: opts.toolName,\n description: description.slice(0, 1024),\n inputSchema,\n run: async (args) => {\n const request = buildRequest(op, args as Record<string, unknown>, opts.baseUrl)\n return invokeRequest(request, {\n baseUrl: opts.baseUrl,\n auth: opts.auth,\n fetch: opts.fetch,\n })\n },\n })\n}\n\n/** Flatten path/query/header params + body into a single z.object(). */\nfunction buildInputSchema(op: NormalizedOperation): z.ZodObject<z.ZodRawShape> {\n const shape: Record<string, z.ZodTypeAny> = {}\n\n for (const param of op.parameters) {\n if (param.in === 'cookie')\n continue\n const baseSchema = jsonSchemaToZod(param.schema ?? { type: 'string' })\n const described = param.description\n ? baseSchema.describe(param.description)\n : baseSchema\n // Avoid name collisions across `in` types: prefix non-path duplicates.\n const key = pickInputKey(shape, param.name, param.in)\n param.inputKey = key\n shape[key] = param.required ? described : described.optional()\n }\n\n if (op.requestBody) {\n const json = op.requestBody.content?.['application/json']?.schema\n if (json) {\n const bodySchema = jsonSchemaToZod(json)\n shape.body = op.requestBody.required ? bodySchema : bodySchema.optional()\n }\n }\n\n return z.object(shape)\n}\n\nfunction pickInputKey(\n shape: Record<string, z.ZodTypeAny>,\n name: string,\n location: 'path' | 'query' | 'header' | 'cookie',\n): string {\n if (!(name in shape))\n return name\n // path-collisions are unusual; for query/header collisions, prefix to stay unique.\n return `${location}_${name}`\n}\n","import { dereference, load } from '@scalar/openapi-parser'\nimport { fetchUrls } from '@scalar/openapi-parser/plugins/fetch-urls'\nimport { readFiles } from '@scalar/openapi-parser/plugins/read-files'\n\nexport interface DereferencedSpec {\n /** Top-level OpenAPI document with all `$ref`s resolved. */\n document: Record<string, any>\n /** Detected version, e.g. '3.0' / '3.1'. */\n version?: string\n}\n\n/**\n * Load + dereference any OpenAPI 3.x source.\n *\n * Accepts:\n * - URL string (https://…)\n * - File path (./openapi.yaml, /abs/path.json)\n * - Inline JSON object\n * - YAML / JSON string\n *\n * Errors during load/dereference are collected; the function throws if the\n * spec cannot be turned into a usable document.\n */\nexport async function parseOpenApi(\n source: string | Record<string, unknown>,\n): Promise<DereferencedSpec> {\n // For object input, dereference accepts it directly.\n if (typeof source !== 'string') {\n const result = dereference(source as Record<string, unknown>)\n if (!result.schema)\n throw new OpenApiParseError('dereference returned no schema', result.errors ?? [])\n return { document: result.schema as Record<string, any>, version: result.version }\n }\n\n // For string input (URL / file path / raw text), let `load` figure it out.\n const loaded = await load(source, {\n plugins: [readFiles(), fetchUrls()],\n })\n\n if (!loaded.specification)\n throw new OpenApiParseError(`Failed to load spec from ${source}`, loaded.errors ?? [])\n\n const result = dereference(loaded.filesystem)\n if (!result.schema)\n throw new OpenApiParseError('dereference returned no schema', result.errors ?? [])\n\n return { document: result.schema as Record<string, any>, version: result.version }\n}\n\nexport class OpenApiParseError extends Error {\n override name = 'OpenApiParseError'\n constructor(\n message: string,\n public readonly errors: ReadonlyArray<{ message: string, path?: string[] }>,\n ) {\n super(`${message}${errors.length ? `: ${errors.map(e => e.message).join('; ')}` : ''}`)\n }\n}\n","/**\n * Generate an MCP-tool-name from an OpenAPI operation.\n *\n * Strategy:\n * 1. Prefer `operationId` (slugified, capped at 64 chars).\n * 2. Fallback: `${method}_${path-with-braces-stripped-and-slashes-as-underscores}`.\n *\n * The result must match `^[a-zA-Z_][a-zA-Z0-9_-]{0,63}$` to play nicely with\n * Anthropic / Claude Code / Cursor / Gemini CLI tool registries.\n */\n\nconst TOOL_NAME_RE = /^[a-z_][\\w-]{0,63}$/i\n\nexport function operationToToolName(opts: {\n operationId?: string\n method: string\n path: string\n namespace?: string\n}): string {\n const namespace = opts.namespace ?? ''\n const base = opts.operationId\n ? slug(opts.operationId)\n : `${opts.method.toLowerCase()}_${slugPath(opts.path)}`\n\n return capName(`${namespace}${base}`)\n}\n\nfunction slug(input: string): string {\n // Replace any disallowed character with `_`, collapse repeats, trim.\n return input\n .replace(/[^\\w-]+/g, '_')\n .replace(/^_+|_+$/g, '')\n .replace(/_{2,}/g, '_')\n}\n\nfunction slugPath(path: string): string {\n return slug(\n path\n .replace(/^\\//, '')\n .replace(/\\{([^}]+)\\}/g, '$1') // {id} -> id\n .replace(/\\//g, '_'),\n )\n}\n\nfunction capName(name: string): string {\n let n = name.slice(0, 64)\n // Ensure it starts with a letter or underscore.\n if (!/^[a-z_]/i.test(n))\n n = `_${n}`.slice(0, 64)\n if (!TOOL_NAME_RE.test(n))\n return slug(n).slice(0, 64) || '_tool'\n return n\n}\n\nexport function isValidToolName(name: string): boolean {\n return TOOL_NAME_RE.test(name)\n}\n","import type { BridgentTool } from '@bridgent/core'\nimport type { FromOpenApiOptions, HttpMethod, NormalizedOperation, OperationObject, ParameterObject, RequestBodyObject } from './types'\nimport { shouldExposeOperation } from './filter'\nimport { operationToTool } from './operation-to-tool'\nimport { parseOpenApi } from './parse-openapi'\nimport { operationToToolName } from './slug'\n\nconst HTTP_METHODS: readonly HttpMethod[] = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE'] as const\n\n/**\n * Turn an OpenAPI 3.x spec into a list of BridgentTools, ready to feed into\n * `createStdioServer({ tools })`.\n *\n * Read-only by default — to expose mutating operations, set `allow.mutating: true`\n * (or use `allowOperations` allowlist).\n */\nexport async function fromOpenApi(\n options: FromOpenApiOptions,\n): Promise<BridgentTool[]> {\n const { document } = await parseOpenApi(options.spec)\n\n const baseUrl = options.baseUrl ?? extractBaseUrl(document)\n if (!baseUrl)\n throw new Error('No baseUrl could be determined from the spec; pass `baseUrl` explicitly.')\n\n const fetchImpl = options.fetch ?? globalThis.fetch\n if (!fetchImpl)\n throw new Error('No fetch implementation available. Pass `options.fetch` or run on Node ≥ 22.18.')\n\n const tools: BridgentTool[] = []\n const seenNames = new Set<string>()\n\n const paths = (document.paths ?? {}) as Record<string, Record<string, OperationObject>>\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (!pathItem || typeof pathItem !== 'object')\n continue\n\n for (const method of HTTP_METHODS) {\n const operation = pathItem[method.toLowerCase()] as OperationObject | undefined\n if (!operation)\n continue\n\n const ctx = { path, method, operation }\n if (!shouldExposeOperation(ctx, options))\n continue\n\n const normalized = normalizeOperation(path, method, operation)\n const toolName = operationToToolName({\n operationId: normalized.operationId,\n method: normalized.method,\n path: normalized.path,\n namespace: options.namespace,\n })\n\n if (seenNames.has(toolName)) {\n throw new Error(\n `Duplicate tool name \"${toolName}\" generated. `\n + `Provide a \\`namespace\\` option, or rename the operationId in the spec.`,\n )\n }\n seenNames.add(toolName)\n\n tools.push(operationToTool(normalized, {\n baseUrl,\n auth: options.auth,\n fetch: fetchImpl,\n toolName,\n }))\n }\n }\n\n return tools\n}\n\nfunction normalizeOperation(\n path: string,\n method: HttpMethod,\n raw: OperationObject,\n): NormalizedOperation {\n return {\n operationId: raw.operationId ?? `${method.toLowerCase()}_${path}`,\n method,\n path,\n summary: raw.summary,\n description: raw.description,\n parameters: (raw.parameters ?? []) as ParameterObject[],\n requestBody: raw.requestBody as RequestBodyObject | undefined,\n raw,\n }\n}\n\nfunction extractBaseUrl(document: Record<string, any>): string | undefined {\n const servers = document.servers as Array<{ url?: string }> | undefined\n return servers?.[0]?.url\n}\n"],"mappings":";;;;;;AAEA,MAAa,eAA6B,CAAC,OAAO,MAAM;AACxD,MAAa,mBAAiC;CAAC;CAAQ;CAAO;CAAS;AAAQ;;;;;;;;;;;ACc/E,SAAgB,sBACd,KACA,MACS;CAET,IAAI,CADmB,sBAAsB,IAC3B,CAAC,CAAC,SAAS,IAAI,MAAM,GACrC,OAAO;CAET,IAAI,KAAK;MAIH,EAHW,OAAO,KAAK,eAAe,aACtC,KAAK,WAAW,IAAI,IAAI,IACxB,KAAK,WAAW,KAAK,IAAI,IAAI,IAE/B,OAAO;CAAA;CAIX,KADmB,KAAK,qBAAqB,SAC3B,IAAI,UAAU,wBAAwB,OACtD,OAAO;CAET,MAAM,OAAO,IAAI,UAAU;CAC3B,IAAI,QAAQ,KAAK,gBAAgB,SAAS,IAAI,GAC5C,OAAO;CAET,IAAI,KAAK,mBAAmB,KAAK,gBAAgB,SAAS;MACpD,CAAC,QAAQ,CAAC,KAAK,gBAAgB,SAAS,IAAI,GAC9C,OAAO;CAAA;CAGX,OAAO;AACT;AAEA,SAAgB,sBAAsB,MAAwC;CAC5E,IAAI,KAAK,OAAO,SACd,OAAO,KAAK,MAAM;CAEpB,IAAI,KAAK,OAAO,UACd,OAAO,CAAC,GAAG,cAAc,GAAG,gBAAgB;CAE9C,OAAO,CAAC,GAAG,YAAY;AACzB;;;;ACzCA,SAAgB,aACd,IACA,MACA,SACc;CACd,MAAM,aAAqC,CAAC;CAC5C,MAAM,cAAc,IAAI,gBAAgB;CACxC,MAAM,UAAkC,EAAE,QAAQ,mBAAmB;CAErE,KAAK,MAAM,SAAS,GAAG,YAAY;EACjC,MAAM,MAAM,KAAK,MAAM,YAAY,MAAM;EACzC,IAAI,QAAQ,KAAA,KAAa,QAAQ,MAAM;GACrC,IAAI,MAAM,YAAY,MAAM,OAAO,QACjC,MAAM,IAAI,MAAM,gCAAgC,MAAM,KAAK,QAAQ,GAAG,aAAa;GACrF;EACF;EACA,MAAM,QAAQ,OAAO,GAAG;EACxB,QAAQ,MAAM,IAAd;GACE,KAAK;IACH,WAAW,MAAM,QAAQ;IACzB;GACF,KAAK;IACH,IAAI,MAAM,QAAQ,GAAG,GACnB,KAAK,MAAM,KAAK,KAAK,YAAY,OAAO,MAAM,MAAM,OAAO,CAAC,CAAC;SAG7D,YAAY,IAAI,MAAM,MAAM,KAAK;IAEnC;GACF,KAAK;IACH,QAAQ,MAAM,QAAQ;IACtB;GACF,KAAK,UAEH;EACJ;CACF;CAGA,IAAI,OAAO,GAAG;CACd,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,GAClD,OAAO,KAAK,QAAQ,IAAI,IAAI,IAAI,mBAAmB,KAAK,CAAC;CAI3D,IAAI;CACJ,IAAI,GAAG,eAAe,KAAK,SAAS,KAAA,GAAW;EAC7C,OAAO,KAAK,UAAU,KAAK,IAAI;EAC/B,QAAQ,kBAAkB,QAAQ,mBAAmB;CACvD;CAEA,MAAM,KAAK,YAAY,SAAS;CAGhC,OAAO;EAAE,KAAA,GAFM,kBAAkB,OAAO,IAAI,OAAO,KAAK,IAAI,OAAO;EAErD,QAAQ,GAAG;EAAQ;EAAS;CAAK;AACjD;;AAGA,eAAsB,cACpB,OACA,MAOC;CACD,MAAM,UAAU,EAAE,GAAG,MAAM,QAAQ;CACnC,MAAM,MAAM,MAAM,UAAU,MAAM,KAAK,SAAS,KAAK,IAAI;CAEzD,MAAM,WAAW,MAAM,KAAK,MAAM,KAAK;EACrC,QAAQ,MAAM;EACd;EACA,MAAM,MAAM;CACd,CAAC;CAED,MAAM,kBAA0C,CAAC;CACjD,SAAS,QAAQ,SAAS,OAAO,QAAQ;EACvC,gBAAgB,OAAO;CACzB,CAAC;CAED,MAAM,OAAO,MAAM,SAAS,KAAK;CACjC,IAAI;CAEJ,KADoB,gBAAgB,mBAAmB,GAAA,CACvC,SAAS,kBAAkB,GACzC,IAAI;EACF,aAAa,KAAK,SAAS,IAAI,KAAK,MAAM,IAAI,IAAI;CACpD,QACM;EACJ,aAAa;CACf;MAIA,aAAa,KAAK,SAAS,QAAS,GAAG,KAAK,MAAM,GAAG,KAAM,EAAE,gBAAgB;CAG/E,OAAO;EACL,IAAI,SAAS;EACb,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,MAAM;EACN,SAAS;CACX;AACF;AAEA,eAAe,UACb,QACA,SACA,MACiB;CACjB,IAAI,CAAC,MACH,OAAO;CAET,IAAI,KAAK,SAAS,UAAU;EAC1B,MAAM,QAAQ,MAAM,cAAc,KAAK,KAAK;EAC5C,IAAI,OACF,QAAQ,gBAAgB,UAAU;EACpC,OAAO;CACT;CAEA,MAAM,QAAQ,MAAM,cAAc,KAAK,KAAK;CAC5C,IAAI,CAAC,OACH,OAAO;CAET,QAAQ,KAAK,IAAb;EACE,KAAK;GACH,QAAQ,KAAK,QAAQ;GACrB,OAAO;EACT,KAAK,SAAS;GACZ,MAAM,MAAM,IAAI,IAAI,MAAM;GAC1B,IAAI,aAAa,IAAI,KAAK,MAAM,KAAK;GACrC,OAAO,IAAI,SAAS;EACtB;EACA,KAAK,UAAU;GACb,MAAM,OAAO,GAAG,KAAK,KAAK,GAAG;GAC7B,QAAQ,SAAS,QAAQ,SAAS,GAAG,QAAQ,OAAO,IAAI,SAAS;GACjE,OAAO;EACT;CACF;AACF;AAEA,eAAe,cAAc,QAAoE;CAC/F,OAAO,OAAO,WAAW,aAAa,MAAM,OAAO,IAAI;AACzD;AAEA,SAAS,kBAAkB,KAAqB;CAC9C,OAAO,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,GAAG,EAAE,IAAI;AAChD;;;;;;;;;;;;AClIA,SAAgB,gBAAgB,OAAoD;CAClF,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO,EAAE,IAAI;CAGf,IAAI,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,SAAS,MAAM,GAAG;EAC5D,MAAM,OAAO,MAAM,KAAK,QAAO,MAAK,MAAM,MAAM;EAKhD,OAAO,SAAS,gBAAgB;GAH9B,GAAG;GACH,MAAM,KAAK,WAAW,IAAI,KAAK,KAAK;EAEH,CAAC,CAAC,CAAC,SAAS,GAAG,MAAM,WAAW;CACrE;CAGA,IAAI,MAAM,aAAa,MAAM;EAC3B,MAAM,EAAE,UAAU,GAAG,SAAS;EAC9B,OAAO,SAAS,gBAAgB,IAAI,CAAC,CAAC,SAAS,GAAG,MAAM,WAAW;CACrE;CAGA,IAAI,WAAW,SAAS,MAAM,UAAU,KAAA,GACtC,OAAO,SAAS,EAAE,QAAQ,MAAM,KAAc,GAAG,MAAM,WAAW;CAGpE,IAAI,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,SAAS,GAAG;EAEtD,IADmB,MAAM,KAAK,OAAM,MAAK,OAAO,MAAM,QACzC,GAAG;GACd,MAAM,SAAS,MAAM;GACrB,OAAO,SAAS,EAAE,KAAK,MAAM,GAAG,MAAM,WAAW;EACnD;EAEA,MAAM,WAAW,MAAM,KAAK,KAAI,MAAK,EAAE,QAAQ,CAAU,CAAC;EAC1D,OAAO,SAAS,EAAE,MAAM,QAAQ,GAAG,MAAM,WAAW;CACtD;CAGA,IAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,QAAQ,MAAM,KAAK,GAAG;EAC5D,MAAM,YAAY,MAAM,SAAS,MAAM,MAAA,CAAQ,IAAI,eAAe;EAClE,IAAI,SAAS,WAAW,GACtB,OAAO,SAAS,SAAS,IAAK,MAAM,WAAW;EACjD,OAAO,SACL,EAAE,MAAM,QAA2D,GACnE,MAAM,WACR;CACF;CAGA,IAAI,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM,SAAS,GAAG;EACxD,MAAM,SAAqB;GAAE,MAAM;GAAU,YAAY,CAAC;GAAG,UAAU,CAAC;EAAE;EAC1E,KAAK,MAAM,QAAQ,MAAM,OAAO;GAC9B,IAAI,KAAK,YACP,OAAO,aAAa;IAAE,GAAG,OAAO;IAAY,GAAG,KAAK;GAAW;GACjE,IAAI,MAAM,QAAQ,KAAK,QAAQ,GAC7B,OAAO,WAAW,CAAC,GAAI,OAAO,YAAY,CAAC,GAAI,GAAG,KAAK,QAAQ;EACnE;EACA,IAAI,MAAM,aACR,OAAO,cAAc,MAAM;EAC7B,OAAO,gBAAgB,MAAM;CAC/B;CAEA,MAAM,OAAO,MAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,KAAK,KAAK,MAAM;CAE/D,QAAQ,MAAR;EACE,KAAK,UACH,OAAO,SAAS,YAAY,KAAK,GAAG,MAAM,WAAW;EACvD,KAAK;EACL,KAAK,UACH,OAAO,SAAS,YAAY,OAAO,SAAS,SAAS,GAAG,MAAM,WAAW;EAC3E,KAAK,WACH,OAAO,SAAS,EAAE,QAAQ,GAAG,MAAM,WAAW;EAChD,KAAK,SACH,OAAO,SAAS,EAAE,MAAM,gBAAgB,MAAM,KAAK,CAAC,GAAG,MAAM,WAAW;EAE1E,SACE,OAAO,SAAS,YAAY,KAAK,GAAG,MAAM,WAAW;CACzD;AACF;AAEA,SAAS,YAAY,GAA6B;CAChD,IAAI,KAAkB,EAAE,OAAO;CAC/B,QAAQ,EAAE,QAAV;EACE,KAAK;GACH,KAAK,GAAG,MAAM;GACd;EACF,KAAK;GACH,KAAK,GAAG,KAAK;GACb;EACF,KAAK;GACH,KAAK,GAAG,SAAS,EAAE,QAAQ,KAAK,CAAC;GACjC;EACF,KAAK;EACL,KAAK;GACH,KAAK,GAAG,IAAI;GACZ;CACJ;CACA,IAAI,OAAO,EAAE,cAAc,UACzB,KAAK,GAAG,IAAI,EAAE,SAAS;CACzB,IAAI,OAAO,EAAE,cAAc,UACzB,KAAK,GAAG,IAAI,EAAE,SAAS;CACzB,IAAI,OAAO,EAAE,YAAY,UACvB,IAAI;EACF,KAAK,GAAG,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC;CACrC,QACM,CAEN;CAEF,OAAO;AACT;AAEA,SAAS,YAAY,GAAe,SAAgC;CAClE,IAAI,KAAkB,EAAE,OAAO;CAC/B,IAAI,SACF,KAAK,GAAG,IAAI;CACd,IAAI,OAAO,EAAE,YAAY,UACvB,KAAK,GAAG,IAAI,EAAE,OAAO;CACvB,IAAI,OAAO,EAAE,YAAY,UACvB,KAAK,GAAG,IAAI,EAAE,OAAO;CACvB,IAAI,OAAO,EAAE,qBAAqB,UAChC,KAAK,GAAG,GAAG,EAAE,gBAAgB;CAC/B,IAAI,OAAO,EAAE,qBAAqB,UAChC,KAAK,GAAG,GAAG,EAAE,gBAAgB;CAC/B,OAAO;AACT;AAEA,SAAS,YAAY,GAA6B;CAChD,MAAM,QAAQ,EAAE,cAAc,CAAC;CAC/B,MAAM,WAAW,IAAI,IAAY,EAAE,YAAY,CAAC,CAAC;CACjD,MAAM,QAAsC,CAAC;CAE7C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,MAAM,QAAQ,gBAAgB,KAAK;EACnC,MAAM,OAAO,SAAS,IAAI,GAAG,IAAI,QAAQ,MAAM,SAAS;CAC1D;CAEA,IAAI,MAAoB,EAAE,OAAO,KAAK;CAGtC,IAAI,EAAE,yBAAyB,MAE7B,MAAO,IAAmC,YAAY;MAEnD,IAAI,OAAO,EAAE,yBAAyB,YAAY,EAAE,yBAAyB,MAEhF,MAAO,IAAmC,SAAS,gBAAgB,EAAE,oBAAoB,CAAC;CAG5F,OAAO;AACT;AAEA,SAAS,SAAS,QAAsB,aAA+C;CACrF,OAAO,cAAc,OAAO,SAAS,WAAW,IAAI;AACtD;;;;AC7KA,SAAgB,gBACd,IACA,MACc;CACd,MAAM,cAAc,iBAAiB,EAAE;CACvC,MAAM,cAAc,GAAG,WAAW,GAAG,eAAe,GAAG,GAAG,OAAO,GAAG,GAAG;CAEvE,OAAO,WAAW;EAChB,MAAM,KAAK;EACX,aAAa,YAAY,MAAM,GAAG,IAAI;EACtC;EACA,KAAK,OAAO,SAAS;GAEnB,OAAO,cADS,aAAa,IAAI,MAAiC,KAAK,OAC5C,GAAG;IAC5B,SAAS,KAAK;IACd,MAAM,KAAK;IACX,OAAO,KAAK;GACd,CAAC;EACH;CACF,CAAC;AACH;;AAGA,SAAS,iBAAiB,IAAqD;CAC7E,MAAM,QAAsC,CAAC;CAE7C,KAAK,MAAM,SAAS,GAAG,YAAY;EACjC,IAAI,MAAM,OAAO,UACf;EACF,MAAM,aAAa,gBAAgB,MAAM,UAAU,EAAE,MAAM,SAAS,CAAC;EACrE,MAAM,YAAY,MAAM,cACpB,WAAW,SAAS,MAAM,WAAW,IACrC;EAEJ,MAAM,MAAM,aAAa,OAAO,MAAM,MAAM,MAAM,EAAE;EACpD,MAAM,WAAW;EACjB,MAAM,OAAO,MAAM,WAAW,YAAY,UAAU,SAAS;CAC/D;CAEA,IAAI,GAAG,aAAa;EAClB,MAAM,OAAO,GAAG,YAAY,UAAU,mBAAmB,EAAE;EAC3D,IAAI,MAAM;GACR,MAAM,aAAa,gBAAgB,IAAI;GACvC,MAAM,OAAO,GAAG,YAAY,WAAW,aAAa,WAAW,SAAS;EAC1E;CACF;CAEA,OAAO,EAAE,OAAO,KAAK;AACvB;AAEA,SAAS,aACP,OACA,MACA,UACQ;CACR,IAAI,EAAE,QAAQ,QACZ,OAAO;CAET,OAAO,GAAG,SAAS,GAAG;AACxB;;;;;;;;;;;;;;;ACnDA,eAAsB,aACpB,QAC2B;CAE3B,IAAI,OAAO,WAAW,UAAU;EAC9B,MAAM,SAAS,YAAY,MAAiC;EAC5D,IAAI,CAAC,OAAO,QACV,MAAM,IAAI,kBAAkB,kCAAkC,OAAO,UAAU,CAAC,CAAC;EACnF,OAAO;GAAE,UAAU,OAAO;GAA+B,SAAS,OAAO;EAAQ;CACnF;CAGA,MAAM,SAAS,MAAM,KAAK,QAAQ,EAChC,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC,EACpC,CAAC;CAED,IAAI,CAAC,OAAO,eACV,MAAM,IAAI,kBAAkB,4BAA4B,UAAU,OAAO,UAAU,CAAC,CAAC;CAEvF,MAAM,SAAS,YAAY,OAAO,UAAU;CAC5C,IAAI,CAAC,OAAO,QACV,MAAM,IAAI,kBAAkB,kCAAkC,OAAO,UAAU,CAAC,CAAC;CAEnF,OAAO;EAAE,UAAU,OAAO;EAA+B,SAAS,OAAO;CAAQ;AACnF;AAEA,IAAa,oBAAb,cAAuC,MAAM;CAE3C,YACE,SACA,QACA;EACA,MAAM,GAAG,UAAU,OAAO,SAAS,KAAK,OAAO,KAAI,MAAK,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI,MAAM,IAAI;EAFtE,KAAA,SAAA;cAHF;CAMhB;AACF;;;;;;;;;;;;;AC9CA,MAAM,eAAe;AAErB,SAAgB,oBAAoB,MAKzB;CAMT,OAAO,QAAQ,GALG,KAAK,aAAa,KACvB,KAAK,cACd,KAAK,KAAK,WAAW,IACrB,GAAG,KAAK,OAAO,YAAY,EAAE,GAAG,SAAS,KAAK,IAAI,KAElB;AACtC;AAEA,SAAS,KAAK,OAAuB;CAEnC,OAAO,MACJ,QAAQ,YAAY,GAAG,CAAC,CACxB,QAAQ,YAAY,EAAE,CAAC,CACvB,QAAQ,UAAU,GAAG;AAC1B;AAEA,SAAS,SAAS,MAAsB;CACtC,OAAO,KACL,KACG,QAAQ,OAAO,EAAE,CAAC,CAClB,QAAQ,gBAAgB,IAAI,CAAC,CAC7B,QAAQ,OAAO,GAAG,CACvB;AACF;AAEA,SAAS,QAAQ,MAAsB;CACrC,IAAI,IAAI,KAAK,MAAM,GAAG,EAAE;CAExB,IAAI,CAAC,WAAW,KAAK,CAAC,GACpB,IAAI,IAAI,IAAI,MAAM,GAAG,EAAE;CACzB,IAAI,CAAC,aAAa,KAAK,CAAC,GACtB,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,KAAK;CACjC,OAAO;AACT;;;AC7CA,MAAM,eAAsC;CAAC;CAAO;CAAQ;CAAQ;CAAO;CAAS;AAAQ;;;;;;;;AAS5F,eAAsB,YACpB,SACyB;CACzB,MAAM,EAAE,aAAa,MAAM,aAAa,QAAQ,IAAI;CAEpD,MAAM,UAAU,QAAQ,WAAW,eAAe,QAAQ;CAC1D,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,0EAA0E;CAE5F,MAAM,YAAY,QAAQ,SAAS,WAAW;CAC9C,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,iFAAiF;CAEnG,MAAM,QAAwB,CAAC;CAC/B,MAAM,4BAAY,IAAI,IAAY;CAElC,MAAM,QAAS,SAAS,SAAS,CAAC;CAElC,KAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,KAAK,GAAG;EACpD,IAAI,CAAC,YAAY,OAAO,aAAa,UACnC;EAEF,KAAK,MAAM,UAAU,cAAc;GACjC,MAAM,YAAY,SAAS,OAAO,YAAY;GAC9C,IAAI,CAAC,WACH;GAGF,IAAI,CAAC,sBAAsB;IADb;IAAM;IAAQ;GACC,GAAG,OAAO,GACrC;GAEF,MAAM,aAAa,mBAAmB,MAAM,QAAQ,SAAS;GAC7D,MAAM,WAAW,oBAAoB;IACnC,aAAa,WAAW;IACxB,QAAQ,WAAW;IACnB,MAAM,WAAW;IACjB,WAAW,QAAQ;GACrB,CAAC;GAED,IAAI,UAAU,IAAI,QAAQ,GACxB,MAAM,IAAI,MACR,wBAAwB,SAAS,oFAEnC;GAEF,UAAU,IAAI,QAAQ;GAEtB,MAAM,KAAK,gBAAgB,YAAY;IACrC;IACA,MAAM,QAAQ;IACd,OAAO;IACP;GACF,CAAC,CAAC;EACJ;CACF;CAEA,OAAO;AACT;AAEA,SAAS,mBACP,MACA,QACA,KACqB;CACrB,OAAO;EACL,aAAa,IAAI,eAAe,GAAG,OAAO,YAAY,EAAE,GAAG;EAC3D;EACA;EACA,SAAS,IAAI;EACb,aAAa,IAAI;EACjB,YAAa,IAAI,cAAc,CAAC;EAChC,aAAa,IAAI;EACjB;CACF;AACF;AAEA,SAAS,eAAe,UAAmD;CAEzE,OADgB,SAAS,UACR,EAAE,EAAE;AACvB"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bridgent/source-openapi",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.1",
5
5
  "description": "Bridgent AI — expose any OpenAPI 3.x spec as MCP tools. Read-only by default, with Bearer auth, path filtering, and a Zod-typed bridge.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://bridgent.ai",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@scalar/openapi-parser": "^0.28.5",
46
- "@bridgent/core": "0.1.0"
46
+ "@bridgent/core": "0.2.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^25.9.1",