@frontmcp/adapters 0.1.3 → 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/package.json CHANGED
@@ -1,19 +1,20 @@
1
1
  {
2
2
  "name": "@frontmcp/adapters",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "type": "commonjs",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "exports": {
8
8
  "./package.json": "./package.json",
9
- "./openapi": {
10
- "types": "./src/openapi/index.d.ts",
11
- "import": "./src/openapi/index.js",
12
- "default": "./src/openapi/index.js"
9
+ ".": {
10
+ "types": "./src/index.d.ts",
11
+ "import": "./src/index.js",
12
+ "default": "./src/index.js"
13
13
  }
14
14
  },
15
15
  "dependencies": {
16
16
  "tslib": "^2.3.0",
17
+ "@frontmcp/sdk": "^0.2.1",
17
18
  "openapi-mcp-generator": "^3.2.0",
18
19
  "json-schema-to-zod": "^2.6.1"
19
20
  }
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default as OpenapiAdapter } from './openapi';
2
+ export * from './openapi';
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenapiAdapter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ var openapi_1 = require("./openapi");
6
+ Object.defineProperty(exports, "OpenapiAdapter", { enumerable: true, get: function () { return tslib_1.__importDefault(openapi_1).default; } });
7
+ tslib_1.__exportStar(require("./openapi"), exports);
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAAA,qCAAmD;AAA3C,kIAAA,OAAO,OAAkB;AACjC,oDAAyB","sourcesContent":["export {default as OpenapiAdapter} from './openapi'\nexport * from './openapi'"]}
@@ -5,12 +5,4 @@ export default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions
5
5
  constructor(options: OpenApiAdapterOptions);
6
6
  fetch(): Promise<FrontMcpAdapterResponse>;
7
7
  private parseTools;
8
- /**
9
- * Converts a JSON Schema to a Zod schema for runtime validation
10
- *
11
- * @param jsonSchema JSON Schema
12
- * @param toolName Tool name for error reporting
13
- * @returns Zod schema
14
- */
15
- private getZodSchemaFromJsonSchema;
16
8
  }
@@ -2,9 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const sdk_1 = require("@frontmcp/sdk");
5
- const zod_1 = require("zod");
6
5
  const openapi_mcp_generator_1 = require("openapi-mcp-generator");
7
- const zod_from_json_schema_1 = require("zod-from-json-schema");
6
+ const openapi_tool_1 = require("./openapi.tool");
8
7
  let OpenapiAdapter = class OpenapiAdapter extends sdk_1.DynamicAdapter {
9
8
  constructor(options) {
10
9
  super();
@@ -12,57 +11,23 @@ let OpenapiAdapter = class OpenapiAdapter extends sdk_1.DynamicAdapter {
12
11
  }
13
12
  async fetch() {
14
13
  const openapiLink = this.options.url;
15
- const openApiTools = await withSilencedConsole((0, openapi_mcp_generator_1.getToolsFromOpenApi)(openapiLink, {
14
+ const { baseUrl, filterFn, defaultInclude, excludeOperationIds } = this.options;
15
+ const openApiTools = await (0, openapi_mcp_generator_1.getToolsFromOpenApi)(openapiLink, {
16
+ baseUrl,
17
+ filterFn,
18
+ defaultInclude,
19
+ excludeOperationIds,
16
20
  dereference: false,
17
- }));
21
+ });
18
22
  return {
19
23
  tools: this.parseTools(openApiTools),
20
24
  };
21
25
  }
22
26
  parseTools(openApiTools) {
23
- return openApiTools.map(oTool => {
24
- const inputSchema = this.getZodSchemaFromJsonSchema(oTool.inputSchema, oTool.name);
25
- // const outputSchema = this.getZodSchemaFromJsonSchema(oTool.outputSchema, oTool.name);
26
- return (0, sdk_1.tool)({
27
- id: oTool.name,
28
- name: oTool.name,
29
- description: oTool.description,
30
- inputSchema: inputSchema.shape,
31
- rawInputSchema: oTool.inputSchema,
32
- // outputSchema: outputSchema.shape
33
- })((input, ctx) => {
34
- return {
35
- data: {
36
- id: '1',
37
- name: 'test',
38
- },
39
- };
40
- });
27
+ return openApiTools.map(tool => {
28
+ return (0, openapi_tool_1.createOpenApiTool)(tool, this.options);
41
29
  });
42
30
  }
43
- /**
44
- * Converts a JSON Schema to a Zod schema for runtime validation
45
- *
46
- * @param jsonSchema JSON Schema
47
- * @param toolName Tool name for error reporting
48
- * @returns Zod schema
49
- */
50
- getZodSchemaFromJsonSchema(jsonSchema, toolName) {
51
- if (typeof jsonSchema !== 'object' || jsonSchema === null) {
52
- return zod_1.z.object({}).passthrough();
53
- }
54
- try {
55
- const zodSchema = (0, zod_from_json_schema_1.convertJsonSchemaToZod)(jsonSchema);
56
- if (typeof zodSchema?.parse !== 'function') {
57
- throw new Error('Eval did not produce a valid Zod schema.');
58
- }
59
- return zodSchema;
60
- }
61
- catch (err) {
62
- console.error(`Failed to generate/evaluate Zod schema for '${toolName}':`, err);
63
- return zod_1.z.object({}).passthrough();
64
- }
65
- }
66
31
  };
67
32
  OpenapiAdapter = tslib_1.__decorate([
68
33
  (0, sdk_1.Adapter)({
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Adapter,\n DynamicAdapter,\n FrontMcpAdapterResponse,\n tool,\n} from '@frontmcp/sdk';\nimport {OpenApiAdapterOptions} from './openapi.types';\nimport {z} from 'zod';\nimport {getToolsFromOpenApi, McpToolDefinition} from 'openapi-mcp-generator';\nimport {convertJsonSchemaToZod} from 'zod-from-json-schema';\n\n\n@Adapter({\n name: 'openapi',\n description: 'OpenAPI adapter that plugin for expense-mcp',\n})\nexport default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {\n options: OpenApiAdapterOptions;\n\n constructor(options: OpenApiAdapterOptions) {\n super();\n this.options = options;\n }\n\n\n async fetch(): Promise<FrontMcpAdapterResponse> {\n const openapiLink = this.options.url\n const openApiTools = await withSilencedConsole(getToolsFromOpenApi(openapiLink, {\n dereference: false,\n }));\n\n return {\n tools: this.parseTools(openApiTools),\n };\n }\n\n private parseTools(openApiTools: McpToolDefinition[]) {\n return openApiTools.map(oTool => {\n const inputSchema = this.getZodSchemaFromJsonSchema(oTool.inputSchema, oTool.name);\n // const outputSchema = this.getZodSchemaFromJsonSchema(oTool.outputSchema, oTool.name);\n\n return tool({\n id: oTool.name,\n name: oTool.name,\n description: oTool.description,\n inputSchema: inputSchema.shape,\n rawInputSchema: oTool.inputSchema as any,\n // outputSchema: outputSchema.shape\n })((input, ctx) => {\n return {\n data: {\n id: '1',\n name: 'test',\n },\n };\n });\n });\n }\n\n\n /**\n * Converts a JSON Schema to a Zod schema for runtime validation\n *\n * @param jsonSchema JSON Schema\n * @param toolName Tool name for error reporting\n * @returns Zod schema\n */\n private getZodSchemaFromJsonSchema(jsonSchema: any, toolName: string): z.ZodObject<any> {\n if (typeof jsonSchema !== 'object' || jsonSchema === null) {\n return z.object({}).passthrough();\n }\n try {\n const zodSchema = convertJsonSchemaToZod(jsonSchema);\n if (typeof zodSchema?.parse !== 'function') {\n throw new Error('Eval did not produce a valid Zod schema.');\n }\n return zodSchema as any;\n } catch (err: any) {\n console.error(`Failed to generate/evaluate Zod schema for '${toolName}':`, err);\n return z.object({}).passthrough();\n }\n }\n}\n\nasync function withSilencedConsole(fn: Promise<any>) {\n const methods = ['log', 'info', 'debug', 'warn', 'error', 'table', 'group', 'groupCollapsed', 'groupEnd', 'dir'];\n const originals = {};\n try {\n for (const m of methods) {\n originals[m] = console[m];\n console[m] = () => {\n };\n }\n return await fn;\n } finally {\n for (const m of Object.keys(originals)) console[m] = originals[m];\n }\n}\n"]}
1
+ {"version":3,"file":"openapi.adapter.js","sourceRoot":"","sources":["../../../src/openapi/openapi.adapter.ts"],"names":[],"mappings":";;;AAAA,uCAIuB;AAEvB,iEAA6E;AAC7E,iDAAiD;AAOlC,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,oBAAqC;IAG/E,YAAY,OAA8B;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAGD,KAAK,CAAC,KAAK;QACT,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAA;QACpC,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,mBAAmB,EAAC,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9E,MAAM,YAAY,GAAG,MAAM,IAAA,2CAAmB,EAAC,WAAW,EAAE;YAC1D,OAAO;YACP,QAAQ;YACR,cAAc;YACd,mBAAmB;YACnB,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;SACrC,CAAC;IACJ,CAAC;IAEO,UAAU,CAAC,YAAiC;QAClD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC7B,OAAO,IAAA,gCAAiB,EAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC;CAGF,CAAA;AAhCoB,cAAc;IAJlC,IAAA,aAAO,EAAC;QACP,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,8CAA8C;KAC5D,CAAC;;GACmB,cAAc,CAgClC;kBAhCoB,cAAc;AAkCnC,KAAK,UAAU,mBAAmB,CAAC,EAAgB;IACjD,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IACjH,MAAM,SAAS,GAAG,EAAE,CAAC;IACrB,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE;YAClB,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,EAAE,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;AACH,CAAC","sourcesContent":["import {\n Adapter,\n DynamicAdapter,\n FrontMcpAdapterResponse,\n} from '@frontmcp/sdk';\nimport {OpenApiAdapterOptions} from './openapi.types';\nimport {getToolsFromOpenApi, McpToolDefinition} from 'openapi-mcp-generator';\nimport {createOpenApiTool} from \"./openapi.tool\";\n\n\n@Adapter({\n name: 'openapi',\n description: 'OpenAPI adapter that plugin for expense-mcp',\n})\nexport default class OpenapiAdapter extends DynamicAdapter<OpenApiAdapterOptions> {\n options: OpenApiAdapterOptions;\n\n constructor(options: OpenApiAdapterOptions) {\n super();\n this.options = options;\n }\n\n\n async fetch(): Promise<FrontMcpAdapterResponse> {\n const openapiLink = this.options.url\n const {baseUrl, filterFn, defaultInclude, excludeOperationIds} = this.options;\n const openApiTools = await getToolsFromOpenApi(openapiLink, {\n baseUrl,\n filterFn,\n defaultInclude,\n excludeOperationIds,\n dereference: false,\n });\n\n return {\n tools: this.parseTools(openApiTools),\n };\n }\n\n private parseTools(openApiTools: McpToolDefinition[]) {\n return openApiTools.map(tool => {\n return createOpenApiTool(tool, this.options);\n });\n }\n\n\n}\n\nasync function withSilencedConsole(fn: Promise<any>) {\n const methods = ['log', 'info', 'debug', 'warn', 'error', 'table', 'group', 'groupCollapsed', 'groupEnd', 'dir'];\n const originals = {};\n try {\n for (const m of methods) {\n originals[m] = console[m];\n console[m] = () => {\n };\n }\n return await fn;\n } finally {\n for (const m of Object.keys(originals)) console[m] = originals[m];\n }\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { McpToolDefinition } from "openapi-mcp-generator";
2
+ import { OpenApiAdapterOptions } from "./openapi.types";
3
+ export declare const createOpenApiTool: (oTool: McpToolDefinition, options: OpenApiAdapterOptions) => () => void;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOpenApiTool = void 0;
4
+ const zod_1 = require("zod");
5
+ const sdk_1 = require("@frontmcp/sdk");
6
+ const zod_from_json_schema_1 = require("zod-from-json-schema");
7
+ const createOpenApiTool = (oTool, options) => {
8
+ const inputSchema = getZodSchemaFromJsonSchema(oTool.inputSchema, oTool.name);
9
+ const { additionalHeaders, headersMapper } = options;
10
+ return (0, sdk_1.tool)({
11
+ id: oTool.name,
12
+ name: oTool.name,
13
+ description: oTool.description,
14
+ inputSchema: inputSchema,
15
+ rawInputSchema: oTool.inputSchema,
16
+ // outputSchema: outputSchema.shape
17
+ })(async (input, ctx) => {
18
+ let { urlPath, headers, queryParams } = prepareUrl(oTool, input);
19
+ let requestBodyData = undefined;
20
+ if (additionalHeaders) {
21
+ for (const [key, value] of Object.entries(additionalHeaders)) {
22
+ headers.append(key, value);
23
+ }
24
+ }
25
+ if (typeof headersMapper === 'function') {
26
+ headers = headersMapper(ctx.authInfo, headers);
27
+ }
28
+ if (!['HEAD', 'GET', 'OPTIONS'].includes(oTool.method)) {
29
+ // prepare body
30
+ if (oTool.requestBodyContentType && typeof input['requestBody'] !== 'undefined') {
31
+ requestBodyData = input['requestBody'];
32
+ headers.set('content-type', oTool.requestBodyContentType);
33
+ }
34
+ }
35
+ const query = queryParams.toString();
36
+ const url = `${options.baseUrl}${urlPath}${query ? `?${query}` : ''}`;
37
+ const res = await fetch(url, {
38
+ method: oTool.method,
39
+ headers,
40
+ body: requestBodyData,
41
+ });
42
+ const data = await res.text();
43
+ let result = { data };
44
+ if (res.headers.get('content-type')?.includes('application/json')) {
45
+ try {
46
+ result.data = JSON.parse(data);
47
+ }
48
+ catch (e) {
49
+ console.error("failed to parse api response"); // migrate to logger
50
+ result.data = data;
51
+ }
52
+ }
53
+ return result;
54
+ });
55
+ };
56
+ exports.createOpenApiTool = createOpenApiTool;
57
+ /**
58
+ * Converts a JSON Schema to a Zod schema for runtime validation
59
+ *
60
+ * @param jsonSchema JSON Schema
61
+ * @param toolName Tool name for error reporting
62
+ * @returns Zod schema
63
+ */
64
+ function getZodSchemaFromJsonSchema(jsonSchema, toolName) {
65
+ if (typeof jsonSchema !== 'object' || jsonSchema === null) {
66
+ return zod_1.z.object({}).passthrough();
67
+ }
68
+ try {
69
+ const zodSchema = (0, zod_from_json_schema_1.convertJsonSchemaToZod)(jsonSchema);
70
+ if (typeof zodSchema?.parse !== 'function') {
71
+ throw new Error('Eval did not produce a valid Zod schema.');
72
+ }
73
+ return zodSchema;
74
+ }
75
+ catch (err) {
76
+ console.error(`Failed to generate/evaluate Zod schema for '${toolName}':`, err);
77
+ return zod_1.z.object({}).passthrough();
78
+ }
79
+ }
80
+ const prepareUrl = (definition, validatedArgs) => {
81
+ // Prepare URL, query parameters, headers, and request body
82
+ let urlPath = definition.pathTemplate;
83
+ const queryParams = new URLSearchParams({ "v": '1' });
84
+ const headers = new Headers({ 'accept': 'application/json' });
85
+ // Apply parameters to the URL path, query, or headers
86
+ definition.executionParameters.forEach((param) => {
87
+ const value = validatedArgs[param.name];
88
+ if (typeof value !== 'undefined' && value !== null) {
89
+ if (param.in === 'path') {
90
+ urlPath = urlPath.replace(`{${param.name}}`, encodeURIComponent(String(value)));
91
+ }
92
+ else if (param.in === 'query') {
93
+ queryParams.set(param.name, value);
94
+ }
95
+ else if (param.in === 'header') {
96
+ headers.append(param.name.toLowerCase(), String(value));
97
+ }
98
+ }
99
+ });
100
+ // Ensure all path parameters are resolved
101
+ if (urlPath.includes('{')) {
102
+ throw new Error(`Failed to resolve path parameters: ${urlPath}`);
103
+ }
104
+ return { urlPath, headers, queryParams };
105
+ };
106
+ //# sourceMappingURL=openapi.tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.tool.js","sourceRoot":"","sources":["../../../src/openapi/openapi.tool.ts"],"names":[],"mappings":"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","sourcesContent":["import {z} from \"zod\";\nimport {McpToolDefinition} from \"openapi-mcp-generator\";\nimport {tool} from \"@frontmcp/sdk\";\nimport {convertJsonSchemaToZod} from \"zod-from-json-schema\";\nimport {OpenApiAdapterOptions} from \"./openapi.types\";\n\n\nexport const createOpenApiTool = (oTool: McpToolDefinition, options: OpenApiAdapterOptions) => {\n const inputSchema = getZodSchemaFromJsonSchema(oTool.inputSchema, oTool.name);\n\n const {additionalHeaders, headersMapper} = options;\n return tool({\n id: oTool.name,\n name: oTool.name,\n description: oTool.description,\n inputSchema: inputSchema as any,\n rawInputSchema: oTool.inputSchema as any,\n // outputSchema: outputSchema.shape\n })(async (input, ctx) => {\n\n let {urlPath, headers, queryParams} = prepareUrl(oTool, input);\n let requestBodyData: any = undefined;\n\n if (additionalHeaders) {\n for (const [key, value] of Object.entries(additionalHeaders)) {\n headers.append(key, value);\n }\n }\n if (typeof headersMapper === 'function') {\n headers = headersMapper(ctx.authInfo, headers)\n }\n\n if (!['HEAD', 'GET', 'OPTIONS'].includes(oTool.method)) {\n // prepare body\n if (oTool.requestBodyContentType && typeof input['requestBody'] !== 'undefined') {\n requestBodyData = input['requestBody'];\n headers.set('content-type', oTool.requestBodyContentType);\n }\n }\n\n const query = queryParams.toString()\n const url = `${options.baseUrl}${urlPath}${query ? `?${query}` : ''}`;\n const res = await fetch(url, {\n method: oTool.method,\n headers,\n body: requestBodyData,\n });\n const data = await res.text()\n let result = {data}\n if (res.headers.get('content-type')?.includes('application/json')) {\n try {\n result.data = JSON.parse(data)\n } catch (e) {\n console.error(\"failed to parse api response\")// migrate to logger\n result.data = data\n }\n }\n return result\n });\n};\n\n\n/**\n * Converts a JSON Schema to a Zod schema for runtime validation\n *\n * @param jsonSchema JSON Schema\n * @param toolName Tool name for error reporting\n * @returns Zod schema\n */\nfunction getZodSchemaFromJsonSchema(jsonSchema: any, toolName: string): z.ZodObject<any> {\n if (typeof jsonSchema !== 'object' || jsonSchema === null) {\n return z.object({}).passthrough();\n }\n try {\n const zodSchema = convertJsonSchemaToZod(jsonSchema);\n if (typeof zodSchema?.parse !== 'function') {\n throw new Error('Eval did not produce a valid Zod schema.');\n }\n return zodSchema as any;\n } catch (err: any) {\n console.error(`Failed to generate/evaluate Zod schema for '${toolName}':`, err);\n return z.object({}).passthrough();\n }\n}\n\nconst prepareUrl = (definition: McpToolDefinition, validatedArgs: any) => {\n // Prepare URL, query parameters, headers, and request body\n let urlPath = definition.pathTemplate;\n const queryParams = new URLSearchParams({\"v\": '1'})\n const headers = new Headers({'accept': 'application/json'})\n\n\n // Apply parameters to the URL path, query, or headers\n definition.executionParameters.forEach((param) => {\n const value = validatedArgs[param.name];\n if (typeof value !== 'undefined' && value !== null) {\n if (param.in === 'path') {\n urlPath = urlPath.replace(`{${param.name}}`, encodeURIComponent(String(value)));\n } else if (param.in === 'query') {\n queryParams.set(param.name, value)\n } else if (param.in === 'header') {\n headers.append(param.name.toLowerCase(), String(value));\n }\n }\n });\n\n // Ensure all path parameters are resolved\n if (urlPath.includes('{')) {\n throw new Error(`Failed to resolve path parameters: ${urlPath}`);\n }\n\n return {urlPath, headers, queryParams};\n}"]}
@@ -1,9 +1,10 @@
1
1
  import { AuthInfo } from "@modelcontextprotocol/sdk/server/auth/types.js";
2
- export interface OpenApiAdapterOptions {
2
+ import { GetToolsOptions } from "openapi-mcp-generator/dist/api";
3
+ export interface OpenApiAdapterOptions extends Omit<GetToolsOptions, 'dereference'> {
3
4
  name: string;
4
5
  url: string;
5
6
  additionalHeaders?: Record<string, string>;
6
- headersMapper?: (authInfo: AuthInfo, headers: Record<string, string>) => Record<string, string>;
7
+ headersMapper?: (authInfo: AuthInfo, headers: Headers) => Headers;
7
8
  bodyMapper?: (authInfo: AuthInfo, body: any) => any;
8
9
  /**
9
10
  * This can be used to map request information to specific
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.types.js","sourceRoot":"","sources":["../../../src/openapi/openapi.types.ts"],"names":[],"mappings":"","sourcesContent":["import {AuthInfo} from \"@modelcontextprotocol/sdk/server/auth/types.js\";\n\nexport interface OpenApiAdapterOptions {\n name: string;\n url: string;\n\n additionalHeaders?: Record<string, string>;\n headersMapper?: (authInfo: AuthInfo, headers: Record<string, string>) => Record<string, string>;\n bodyMapper?: (authInfo: AuthInfo, body: any) => any;\n\n /**\n * This can be used to map request information to specific\n * input schema values as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific proprty in the input schema, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n * @param authInfo\n * @param request\n */\n inputSchemaMapper?: (inputSchema: any) => any;\n}\n"]}
1
+ {"version":3,"file":"openapi.types.js","sourceRoot":"","sources":["../../../src/openapi/openapi.types.ts"],"names":[],"mappings":"","sourcesContent":["import {AuthInfo} from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport {GetToolsOptions} from \"openapi-mcp-generator/dist/api\";\n\nexport interface OpenApiAdapterOptions extends Omit<GetToolsOptions, 'dereference'> {\n name: string;\n url: string;\n\n additionalHeaders?: Record<string, string>;\n headersMapper?: (authInfo: AuthInfo, headers: Headers) => Headers;\n bodyMapper?: (authInfo: AuthInfo, body: any) => any;\n /**\n * This can be used to map request information to specific\n * input schema values as required by the API.\n * For example, mapping tenantId from authenticated session payload to\n * a specific proprty in the input schema, this key will be hidden to mcp clients\n * and filled by the adapter before sending the request to the API.\n * @param authInfo\n * @param request\n */\n inputSchemaMapper?: (inputSchema: any) => any;\n}\n"]}