api2mcp 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -166,6 +166,7 @@ LLM 调用流程:
166
166
  | `API_BASE_URL` | API 基础 URL |
167
167
  | `API_TIMEOUT` | 请求超时时间 (毫秒) |
168
168
  | `API_HEADERS` | 自定义请求头 (JSON 字符串) |
169
+ | `API_FIXED_PARAMS` | 固定参数 (JSON 字符串),这些参数会注入到每个 API 请求中,但不会暴露给 LLM |
169
170
  | `DEBUG` | 启用调试模式 |
170
171
 
171
172
  ### 在 Claude Desktop 中使用
@@ -188,6 +189,31 @@ LLM 调用流程:
188
189
 
189
190
  > **注意**: 使用 `-y` 参数可以自动确认 npx 的安装提示,避免交互式确认。
190
191
 
192
+ ### 使用环境变量传递敏感参数
193
+
194
+ 当 API 需要认证密钥等敏感参数时,推荐使用 MCP 客户端的 `env` 字段通过环境变量传递,而非 `--fixed-params` CLI 参数。这样可以避免密钥以明文形式出现在进程参数中(进程参数可通过 `ps` 等命令被其他用户查看)。
195
+
196
+ ```json
197
+ {
198
+ "mcpServers": {
199
+ "my-api": {
200
+ "command": "npx",
201
+ "args": [
202
+ "-y",
203
+ "api2mcp",
204
+ "--url",
205
+ "https://api.example.com/openapi.json"
206
+ ],
207
+ "env": {
208
+ "API_FIXED_PARAMS": "{\"appKey\":\"YOUR_APP_KEY\"}"
209
+ }
210
+ }
211
+ }
212
+ }
213
+ ```
214
+
215
+ `API_FIXED_PARAMS` 的值为 JSON 字符串,其中的键值对会作为固定参数注入到每个 API 请求中。这些参数对 LLM 不可见,适合传递 API 密钥、token 等敏感信息。
216
+
191
217
  ## 配置优先级
192
218
 
193
219
  配置加载优先级 (从高到低):
@@ -95,6 +95,20 @@ function parseHeaders(headersStr) {
95
95
  );
96
96
  }
97
97
  }
98
+ function parseFixedParams(paramsStr) {
99
+ if (!paramsStr) return void 0;
100
+ try {
101
+ const parsed = JSON.parse(paramsStr);
102
+ if (typeof parsed === "object" && parsed !== null) {
103
+ return parsed;
104
+ }
105
+ throw new Error("Fixed params must be a JSON object");
106
+ } catch (error) {
107
+ throw new ConfigurationError(
108
+ `Invalid fixedParams JSON: ${error instanceof Error ? error.message : "Unknown error"}`
109
+ );
110
+ }
111
+ }
98
112
  function loadFromEnv(env) {
99
113
  const config = {};
100
114
  if (env.OPENAPI_URL) {
@@ -112,6 +126,9 @@ function loadFromEnv(env) {
112
126
  if (env.API_HEADERS) {
113
127
  config.headers = parseHeaders(env.API_HEADERS);
114
128
  }
129
+ if (env.API_FIXED_PARAMS) {
130
+ config.fixedParams = parseFixedParams(env.API_FIXED_PARAMS);
131
+ }
115
132
  if (env.DEBUG) {
116
133
  config.debug = env.DEBUG === "true" || env.DEBUG === "1";
117
134
  }
@@ -130,6 +147,7 @@ function loadFromFile(workingDir = process.cwd()) {
130
147
  baseUrl: parsed.baseUrl,
131
148
  timeout: parsed.timeout,
132
149
  headers: parsed.headers,
150
+ fixedParams: parsed.fixedParams,
133
151
  toolPrefix: parsed.toolPrefix,
134
152
  debug: parsed.debug,
135
153
  mode: parsed.mode
@@ -157,6 +175,9 @@ function loadFromCli(args) {
157
175
  if (args.headers) {
158
176
  config.headers = parseHeaders(args.headers);
159
177
  }
178
+ if (args.fixedParams) {
179
+ config.fixedParams = parseFixedParams(args.fixedParams);
180
+ }
160
181
  if (args.prefix) {
161
182
  config.toolPrefix = args.prefix;
162
183
  }
@@ -178,6 +199,7 @@ function mergeConfigs(...configs) {
178
199
  if (config.baseUrl !== void 0) merged.baseUrl = config.baseUrl;
179
200
  if (config.timeout !== void 0) merged.timeout = config.timeout;
180
201
  if (config.headers !== void 0) merged.headers = config.headers;
202
+ if (config.fixedParams !== void 0) merged.fixedParams = config.fixedParams;
181
203
  if (config.toolPrefix !== void 0) merged.toolPrefix = config.toolPrefix;
182
204
  if (config.debug !== void 0) merged.debug = config.debug;
183
205
  if (config.mode !== void 0) merged.mode = config.mode;
@@ -434,11 +456,14 @@ Tags: ${operation.tags.join(", ")}`);
434
456
  }
435
457
  return parts.join("\n");
436
458
  }
437
- function buildParametersSchema(operation, refResolver) {
459
+ function buildParametersSchema(operation, refResolver, fixedParams) {
438
460
  const shape = {};
439
461
  if (operation.parameters) {
440
462
  for (const param of operation.parameters) {
441
463
  const paramName = param.name;
464
+ if (fixedParams && paramName in fixedParams) {
465
+ continue;
466
+ }
442
467
  let paramSchema = convertSchema(param.schema, refResolver);
443
468
  if (param.description) {
444
469
  paramSchema = paramSchema.describe(param.description);
@@ -479,11 +504,11 @@ function buildParametersSchema(operation, refResolver) {
479
504
  shape._baseUrl = z2.string().url().optional().describe("API base URL (overrides the default). Example: https://api.example.com");
480
505
  return shape;
481
506
  }
482
- function generateTool(operation, components, toolPrefix) {
507
+ function generateTool(operation, components, toolPrefix, fixedParams) {
483
508
  const refResolver = createRefResolver(components);
484
509
  const name = generateToolName(operation, toolPrefix);
485
510
  const description = generateToolDescription(operation);
486
- const parametersShape = buildParametersSchema(operation, refResolver);
511
+ const parametersShape = buildParametersSchema(operation, refResolver, fixedParams);
487
512
  const inputSchema = z2.object(parametersShape);
488
513
  logger.debug(`Generated tool: ${name}`);
489
514
  return {
@@ -493,11 +518,11 @@ function generateTool(operation, components, toolPrefix) {
493
518
  operation
494
519
  };
495
520
  }
496
- function generateTools(operations, components, toolPrefix) {
521
+ function generateTools(operations, components, toolPrefix, fixedParams) {
497
522
  const tools = [];
498
523
  const usedNames = /* @__PURE__ */ new Set();
499
524
  for (const operation of operations) {
500
- const tool = generateTool(operation, components, toolPrefix);
525
+ const tool = generateTool(operation, components, toolPrefix, fixedParams);
501
526
  if (usedNames.has(tool.name)) {
502
527
  let counter = 1;
503
528
  let newName = `${tool.name}_${counter}`;
@@ -530,11 +555,11 @@ function groupParametersByLocation(parameters) {
530
555
  }
531
556
  return groups;
532
557
  }
533
- function buildRequest(operation, input, defaultHeaders = {}) {
558
+ function buildRequest(operation, input, defaultHeaders = {}, fixedParams = {}) {
534
559
  const groupedParams = groupParametersByLocation(operation.parameters);
535
560
  let path = operation.path;
536
561
  for (const param of groupedParams.path) {
537
- const value = input[param.name];
562
+ const value = input[param.name] ?? fixedParams[param.name];
538
563
  if (value !== void 0) {
539
564
  path = path.replace(`{${param.name}}`, String(value));
540
565
  } else if (param.required) {
@@ -543,7 +568,7 @@ function buildRequest(operation, input, defaultHeaders = {}) {
543
568
  }
544
569
  const query = {};
545
570
  for (const param of groupedParams.query) {
546
- const value = input[param.name];
571
+ const value = input[param.name] ?? fixedParams[param.name];
547
572
  if (value !== void 0) {
548
573
  if (Array.isArray(value)) {
549
574
  query[param.name] = value.map(String);
@@ -614,7 +639,7 @@ async function executeRequest(operation, input, config) {
614
639
  );
615
640
  }
616
641
  try {
617
- const built = buildRequest(operation, input, config.headers || {});
642
+ const built = buildRequest(operation, input, config.headers || {}, config.fixedParams || {});
618
643
  let url = `${baseUrl}${built.path}`;
619
644
  url = appendQueryString(url, built.query);
620
645
  logger.info(`Executing: ${operation.method} ${url}`);
@@ -1643,7 +1668,7 @@ async function createServer(config) {
1643
1668
  logger.info(`Mode: ${config.mode || "default"}`);
1644
1669
  const server = new McpServer({
1645
1670
  name: "api2mcp",
1646
- version: "0.1.0"
1671
+ version: "0.6.0"
1647
1672
  });
1648
1673
  const openApiDoc = await parseOpenApi(config.openapiUrl);
1649
1674
  const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
@@ -1654,7 +1679,8 @@ async function createServer(config) {
1654
1679
  const tools = generateTools(
1655
1680
  openApiDoc.operations,
1656
1681
  openApiDoc.components?.schemas,
1657
- config.toolPrefix
1682
+ config.toolPrefix,
1683
+ effectiveConfig.fixedParams
1658
1684
  );
1659
1685
  if (config.mode === "ondemand") {
1660
1686
  const registry = createRegistry(tools, openApiDoc.components?.schemas);
@@ -1709,4 +1735,4 @@ export {
1709
1735
  createServer,
1710
1736
  startServer
1711
1737
  };
1712
- //# sourceMappingURL=chunk-UQT2XNCH.mjs.map
1738
+ //# sourceMappingURL=chunk-6YWTIHKQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/error.ts","../src/utils/logger.ts","../src/config/loader.ts","../src/converter/schema-converter.ts","../src/converter/tool-generator.ts","../src/executor/request-builder.ts","../src/executor/http-client.ts","../src/parser/swagger.ts","../src/registry/api-registry.ts","../src/tools/discovery/api-detail.ts","../src/tools/discovery/api-execute.ts","../src/tools/discovery/api-list.ts","../src/tools/discovery/api-search.ts","../src/server/tool-manager.ts","../src/server/index.ts"],"sourcesContent":["/**\n * 错误类定义\n */\n\nexport class Api2McpError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'Api2McpError';\n }\n}\n\nexport class ConfigurationError extends Api2McpError {\n constructor(message: string, cause?: Error) {\n super(message, 'CONFIGURATION_ERROR', cause);\n this.name = 'ConfigurationError';\n }\n}\n\nexport class OpenApiParseError extends Api2McpError {\n constructor(message: string, cause?: Error) {\n super(message, 'OPENAPI_PARSE_ERROR', cause);\n this.name = 'OpenApiParseError';\n }\n}\n\nexport class ToolExecutionError extends Api2McpError {\n constructor(\n message: string,\n public readonly toolName: string,\n cause?: Error\n ) {\n super(message, 'TOOL_EXECUTION_ERROR', cause);\n this.name = 'ToolExecutionError';\n }\n}\n\nexport class HttpError extends Api2McpError {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly responseBody?: string,\n cause?: Error\n ) {\n super(message, 'HTTP_ERROR', cause);\n this.name = 'HttpError';\n }\n}\n","/**\n * 简单日志工具\n * 所有日志输出到 stderr,避免干扰 MCP stdio 协议\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\ninterface Logger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n setLevel: (level: LogLevel) => void;\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nlet currentLevel: LogLevel = 'info';\n\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];\n}\n\nfunction formatMessage(level: LogLevel, message: string): string {\n const timestamp = new Date().toISOString();\n return `[${timestamp}] [${level.toUpperCase()}] ${message}`;\n}\n\nexport const logger: Logger = {\n debug(message: string, ...args: unknown[]): void {\n if (shouldLog('debug')) {\n console.error(formatMessage('debug', message), ...args);\n }\n },\n\n info(message: string, ...args: unknown[]): void {\n if (shouldLog('info')) {\n console.error(formatMessage('info', message), ...args);\n }\n },\n\n warn(message: string, ...args: unknown[]): void {\n if (shouldLog('warn')) {\n console.error(formatMessage('warn', message), ...args);\n }\n },\n\n error(message: string, ...args: unknown[]): void {\n if (shouldLog('error')) {\n console.error(formatMessage('error', message), ...args);\n }\n },\n\n setLevel(level: LogLevel): void {\n currentLevel = level;\n },\n};\n\nexport default logger;\n","/**\n * 配置加载器\n * 优先级: CLI 参数 > 环境变量 > 配置文件\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport { ConfigurationError } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\nimport type { CliArgs, Config, ConfigFile, EnvConfig } from './types.js';\n\nconst DEFAULT_TIMEOUT = 30000;\nconst CONFIG_FILE_NAMES = ['api2mcp.json', 'api2mcp.config.json', '.api2mcp.json'];\n\n/**\n * 解析 JSON 格式的请求头字符串\n */\nfunction parseHeaders(headersStr: string | undefined): Record<string, string> | undefined {\n if (!headersStr) return undefined;\n\n try {\n const parsed = JSON.parse(headersStr);\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed as Record<string, string>;\n }\n throw new Error('Headers must be a JSON object');\n } catch (error) {\n throw new ConfigurationError(\n `Invalid headers JSON: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n}\n\n/**\n * 解析 JSON 格式的固定参数字符串\n */\nfunction parseFixedParams(paramsStr: string | undefined): Record<string, string> | undefined {\n if (!paramsStr) return undefined;\n\n try {\n const parsed = JSON.parse(paramsStr);\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed as Record<string, string>;\n }\n throw new Error('Fixed params must be a JSON object');\n } catch (error) {\n throw new ConfigurationError(\n `Invalid fixedParams JSON: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n}\n\n/**\n * 从环境变量加载配置\n */\nfunction loadFromEnv(env: EnvConfig): Partial<Config> {\n const config: Partial<Config> = {};\n\n if (env.OPENAPI_URL) {\n config.openapiUrl = env.OPENAPI_URL;\n }\n\n if (env.API_BASE_URL) {\n config.baseUrl = env.API_BASE_URL;\n }\n\n if (env.API_TIMEOUT) {\n const timeout = parseInt(env.API_TIMEOUT, 10);\n if (!Number.isNaN(timeout) && timeout > 0) {\n config.timeout = timeout;\n }\n }\n\n if (env.API_HEADERS) {\n config.headers = parseHeaders(env.API_HEADERS);\n }\n\n if (env.API_FIXED_PARAMS) {\n config.fixedParams = parseFixedParams(env.API_FIXED_PARAMS);\n }\n\n if (env.DEBUG) {\n config.debug = env.DEBUG === 'true' || env.DEBUG === '1';\n }\n\n return config;\n}\n\n/**\n * 从配置文件加载配置\n */\nfunction loadFromFile(workingDir: string = process.cwd()): Partial<Config> | null {\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = resolve(workingDir, fileName);\n if (existsSync(filePath)) {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(content) as ConfigFile;\n logger.info(`Loaded configuration from ${filePath}`);\n return {\n openapiUrl: parsed.openapiUrl,\n baseUrl: parsed.baseUrl,\n timeout: parsed.timeout,\n headers: parsed.headers,\n fixedParams: parsed.fixedParams,\n toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\n mode: parsed.mode,\n };\n } catch (error) {\n throw new ConfigurationError(\n `Failed to load config file ${filePath}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n }\n return null;\n}\n\n/**\n * 从 CLI 参数加载配置\n */\nfunction loadFromCli(args: CliArgs): Partial<Config> {\n const config: Partial<Config> = {};\n\n if (args.url) {\n config.openapiUrl = args.url;\n }\n\n if (args.baseUrl) {\n config.baseUrl = args.baseUrl;\n }\n\n if (args.timeout) {\n config.timeout = args.timeout;\n }\n\n if (args.headers) {\n config.headers = parseHeaders(args.headers);\n }\n\n if (args.fixedParams) {\n config.fixedParams = parseFixedParams(args.fixedParams);\n }\n\n if (args.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\n }\n\n if (args.mode) {\n config.mode = args.mode;\n }\n\n return config;\n}\n\n/**\n * 合并配置(后面的配置覆盖前面的)\n */\nfunction mergeConfigs(...configs: Array<Partial<Config>>): Config {\n const merged: Config = {\n openapiUrl: '',\n debug: false,\n };\n\n for (const config of configs) {\n if (config.openapiUrl !== undefined) merged.openapiUrl = config.openapiUrl;\n if (config.baseUrl !== undefined) merged.baseUrl = config.baseUrl;\n if (config.timeout !== undefined) merged.timeout = config.timeout;\n if (config.headers !== undefined) merged.headers = config.headers;\n if (config.fixedParams !== undefined) merged.fixedParams = config.fixedParams;\n if (config.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\n if (config.mode !== undefined) merged.mode = config.mode;\n }\n\n // 设置默认值\n if (merged.timeout === undefined) {\n merged.timeout = DEFAULT_TIMEOUT;\n }\n\n return merged;\n}\n\n/**\n * 加载配置\n * 优先级: CLI 参数 > 环境变量 > 配置文件\n */\nexport function loadConfig(cliArgs: CliArgs = {}, env: EnvConfig = process.env): Config {\n const fileConfig = loadFromFile() ?? {};\n const envConfig = loadFromEnv(env);\n const cliConfig = loadFromCli(cliArgs);\n\n const config = mergeConfigs(cliConfig, envConfig, fileConfig);\n\n // 验证必要配置\n if (!config.openapiUrl) {\n throw new ConfigurationError(\n 'OpenAPI URL is required. Provide it via --url, OPENAPI_URL env, or config file.'\n );\n }\n\n // 设置日志级别\n if (config.debug) {\n logger.setLevel('debug');\n }\n\n logger.debug('Loaded configuration:', {\n openapiUrl: config.openapiUrl,\n baseUrl: config.baseUrl,\n timeout: config.timeout,\n toolPrefix: config.toolPrefix,\n mode: config.mode,\n debug: config.debug,\n });\n\n return config;\n}\n\nexport default loadConfig;\n","/**\n * OpenAPI Schema 到 Zod Schema 转换器\n */\n\nimport { z } from 'zod';\nimport type { OpenApiSchema } from '../parser/types.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * Schema 引用解析函数类型\n */\ntype RefResolver = (ref: string) => OpenApiSchema | undefined;\n\n/**\n * 默认引用解析器(不支持 $ref)\n */\nconst defaultRefResolver: RefResolver = () => undefined;\n\n/**\n * 将 OpenAPI Schema 转换为 Zod Schema\n */\nexport function convertSchema(\n schema: OpenApiSchema | undefined,\n refResolver: RefResolver = defaultRefResolver\n): z.ZodType {\n if (!schema) {\n return z.unknown();\n }\n\n // 处理 $ref\n if (schema.$ref) {\n const resolved = refResolver(schema.$ref);\n if (resolved) {\n return convertSchema(resolved, refResolver);\n }\n logger.warn(`Unresolved $ref: ${schema.$ref}`);\n return z.unknown();\n }\n\n // 处理 allOf\n if (schema.allOf && schema.allOf.length > 0) {\n const schemas = schema.allOf.map((s) => convertSchema(s, refResolver));\n // allOf 表示所有 schema 的交集,这里用 intersection 实现\n if (schemas.length === 1) {\n return schemas[0];\n }\n return schemas.reduce((acc, s) => acc.and(s));\n }\n\n // 处理 oneOf\n if (schema.oneOf && schema.oneOf.length > 0) {\n const schemas = schema.oneOf.map((s) => convertSchema(s, refResolver));\n return z.union([schemas[0], schemas[1] || schemas[0], ...schemas.slice(2)] as [\n z.ZodType,\n z.ZodType,\n ...z.ZodType[],\n ]);\n }\n\n // 处理 anyOf\n if (schema.anyOf && schema.anyOf.length > 0) {\n const schemas = schema.anyOf.map((s) => convertSchema(s, refResolver));\n // anyOf 表示至少匹配一个,用 union 实现\n if (schemas.length === 1) {\n return schemas[0].optional();\n }\n return z.union([schemas[0], schemas[1] || schemas[0], ...schemas.slice(2)] as [\n z.ZodType,\n z.ZodType,\n ...z.ZodType[],\n ]);\n }\n\n // 处理 nullable\n const nullable = schema.nullable === true;\n\n // 根据 type 处理\n let zodSchema: z.ZodType;\n\n switch (schema.type) {\n case 'string':\n zodSchema = convertStringSchema(schema);\n break;\n\n case 'number':\n case 'integer':\n zodSchema = convertNumberSchema(schema);\n break;\n\n case 'boolean':\n zodSchema = z.boolean();\n break;\n\n case 'array':\n zodSchema = convertArraySchema(schema, refResolver);\n break;\n\n case 'object':\n zodSchema = convertObjectSchema(schema, refResolver);\n break;\n\n default:\n // 如果没有指定 type,但有 properties,当作 object 处理\n if (schema.properties) {\n zodSchema = convertObjectSchema(schema, refResolver);\n } else {\n zodSchema = z.unknown();\n }\n }\n\n // 处理 nullable\n if (nullable) {\n zodSchema = zodSchema.nullable();\n }\n\n // 处理默认值\n if (schema.default !== undefined) {\n zodSchema = zodSchema.default(schema.default);\n }\n\n // 添加描述\n if (schema.description) {\n zodSchema = zodSchema.describe(schema.description);\n }\n\n return zodSchema;\n}\n\n/**\n * 转换字符串 Schema\n */\nfunction convertStringSchema(schema: OpenApiSchema): z.ZodString {\n let zodSchema = z.string();\n\n if (schema.minLength !== undefined) {\n zodSchema = zodSchema.min(schema.minLength);\n }\n\n if (schema.maxLength !== undefined) {\n zodSchema = zodSchema.max(schema.maxLength);\n }\n\n if (schema.pattern) {\n zodSchema = zodSchema.regex(new RegExp(schema.pattern));\n }\n\n if (schema.format) {\n switch (schema.format) {\n case 'email':\n zodSchema = zodSchema.email();\n break;\n case 'uri':\n case 'url':\n zodSchema = zodSchema.url();\n break;\n case 'uuid':\n zodSchema = zodSchema.uuid();\n break;\n case 'date':\n zodSchema = zodSchema.date();\n break;\n case 'date-time':\n zodSchema = zodSchema.datetime();\n break;\n // 其他 format 不特殊处理\n }\n }\n\n if (schema.enum) {\n // 使用 const assertion 确保 TypeScript 正确推断类型\n const enumValues = schema.enum as [string, ...string[]];\n zodSchema = z.enum(enumValues) as unknown as z.ZodString;\n }\n\n return zodSchema;\n}\n\n/**\n * 转换数字 Schema\n */\nfunction convertNumberSchema(schema: OpenApiSchema): z.ZodNumber {\n let zodSchema = schema.type === 'integer' ? z.number().int() : z.number();\n\n if (schema.minimum !== undefined) {\n zodSchema = zodSchema.min(schema.minimum);\n }\n\n if (schema.maximum !== undefined) {\n zodSchema = zodSchema.max(schema.maximum);\n }\n\n if (schema.exclusiveMinimum === true && schema.minimum !== undefined) {\n zodSchema = zodSchema.min(schema.minimum + (schema.type === 'integer' ? 1 : Number.MIN_VALUE));\n } else if (typeof schema.exclusiveMinimum === 'number') {\n zodSchema = zodSchema.min(\n schema.exclusiveMinimum + (schema.type === 'integer' ? 1 : Number.MIN_VALUE)\n );\n }\n\n if (schema.exclusiveMaximum === true && schema.maximum !== undefined) {\n zodSchema = zodSchema.max(schema.maximum - (schema.type === 'integer' ? 1 : Number.MIN_VALUE));\n } else if (typeof schema.exclusiveMaximum === 'number') {\n zodSchema = zodSchema.max(\n schema.exclusiveMaximum - (schema.type === 'integer' ? 1 : Number.MIN_VALUE)\n );\n }\n\n if (schema.enum) {\n const enumValues = schema.enum as [number, ...number[]];\n zodSchema = z.enum(enumValues.map(String) as [string, ...string[]]) as unknown as z.ZodNumber;\n }\n\n return zodSchema;\n}\n\n/**\n * 转换数组 Schema\n */\nfunction convertArraySchema(\n schema: OpenApiSchema,\n refResolver: RefResolver\n): z.ZodArray<z.ZodType> {\n const itemSchema = schema.items ? convertSchema(schema.items, refResolver) : z.unknown();\n\n let zodSchema = z.array(itemSchema);\n\n if (schema.minItems !== undefined) {\n zodSchema = zodSchema.min(schema.minItems);\n }\n\n if (schema.maxItems !== undefined) {\n zodSchema = zodSchema.max(schema.maxItems);\n }\n\n return zodSchema;\n}\n\n/**\n * 转换对象 Schema\n */\nfunction convertObjectSchema(schema: OpenApiSchema, refResolver: RefResolver): z.ZodType {\n const properties = schema.properties || {};\n const required = new Set(schema.required || []);\n\n if (Object.keys(properties).length === 0) {\n // 空 object 或 additionalProperties\n if (schema.additionalProperties) {\n if (typeof schema.additionalProperties === 'boolean') {\n return z.record(z.unknown());\n }\n return z.record(convertSchema(schema.additionalProperties, refResolver));\n }\n return z.record(z.unknown());\n }\n\n const zodProperties: Record<string, z.ZodType> = {};\n\n for (const [name, prop] of Object.entries(properties)) {\n let propSchema = convertSchema(prop, refResolver);\n\n if (!required.has(name)) {\n propSchema = propSchema.optional();\n }\n\n zodProperties[name] = propSchema;\n }\n\n let zodSchema: z.ZodType = z.object(zodProperties);\n\n // 处理 additionalProperties\n if (schema.additionalProperties) {\n if (typeof schema.additionalProperties === 'boolean') {\n zodSchema = z.object(zodProperties).passthrough();\n } else {\n // Zod 不直接支持 typed additionalProperties,这里用 passthrough 并记录日志\n logger.debug('Typed additionalProperties is not fully supported, using passthrough');\n zodSchema = z.object(zodProperties).passthrough();\n }\n } else {\n zodSchema = z.object(zodProperties).strict();\n }\n\n return zodSchema;\n}\n\n/**\n * 创建引用解析器\n */\nexport function createRefResolver(\n components: Record<string, OpenApiSchema> | undefined\n): RefResolver {\n return (ref: string): OpenApiSchema | undefined => {\n // 解析 #/components/schemas/XXX 格式的引用\n const match = ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n if (match && components) {\n return components[match[1]];\n }\n return undefined;\n };\n}\n\nexport default {\n convertSchema,\n createRefResolver,\n};\n","/**\n * MCP 工具生成器\n */\n\nimport { z } from 'zod';\nimport type { OpenApiOperation, OpenApiSchema } from '../parser/types.js';\nimport { logger } from '../utils/logger.js';\nimport { convertSchema, createRefResolver } from './schema-converter.js';\n\n/**\n * 生成的工具定义\n */\nexport interface GeneratedTool {\n /** 工具名称 */\n name: string;\n /** 工具描述 */\n description: string;\n /** 输入参数 Schema */\n inputSchema: z.ZodObject<z.ZodRawShape>;\n /** 原始操作定义 */\n operation: OpenApiOperation;\n}\n\n/**\n * 生成工具名称\n */\nfunction generateToolName(operation: OpenApiOperation, prefix?: string): string {\n // 优先使用 operationId\n if (operation.operationId) {\n const name = sanitizeToolName(operation.operationId);\n return prefix ? `${prefix}_${name}` : name;\n }\n\n // 否则使用 method + path\n const pathParts = operation.path\n .split('/')\n .filter(Boolean)\n .map((part) => part.replace(/[{}]/g, ''));\n\n const name = sanitizeToolName(`${operation.method.toLowerCase()}_${pathParts.join('_')}`);\n return prefix ? `${prefix}_${name}` : name;\n}\n\n/**\n * 清理工具名称\n */\nfunction sanitizeToolName(name: string): string {\n // 替换非法字符为下划线\n return name\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_|_$/g, '')\n .toLowerCase();\n}\n\n/**\n * 生成工具描述\n */\nfunction generateToolDescription(operation: OpenApiOperation): string {\n const parts: string[] = [];\n\n if (operation.summary) {\n parts.push(operation.summary);\n }\n\n if (operation.description) {\n parts.push(operation.description);\n }\n\n if (operation.deprecated) {\n parts.push('[DEPRECATED]');\n }\n\n // 添加方法和路径信息\n parts.push(`\\n\\nHTTP ${operation.method} ${operation.path}`);\n\n // 添加标签\n if (operation.tags && operation.tags.length > 0) {\n parts.push(`\\nTags: ${operation.tags.join(', ')}`);\n }\n\n return parts.join('\\n');\n}\n\n/**\n * 构建参数 Schema\n */\nfunction buildParametersSchema(\n operation: OpenApiOperation,\n refResolver: ReturnType<typeof createRefResolver>,\n fixedParams?: Record<string, string>\n): z.ZodRawShape {\n const shape: z.ZodRawShape = {};\n\n // 处理路径参数、查询参数、头参数\n if (operation.parameters) {\n for (const param of operation.parameters) {\n const paramName = param.name;\n\n // 跳过固定参数(不暴露给 LLM)\n if (fixedParams && paramName in fixedParams) {\n continue;\n }\n let paramSchema = convertSchema(param.schema, refResolver);\n\n // 添加描述\n if (param.description) {\n paramSchema = paramSchema.describe(param.description);\n }\n\n // 处理可选参数\n if (!param.required) {\n paramSchema = paramSchema.optional();\n }\n\n // 使用参数名作为键,添加位置信息\n const key = paramName;\n shape[key] = paramSchema;\n }\n }\n\n // 处理请求体\n if (operation.requestBody) {\n // 优先使用 application/json\n const jsonContent = operation.requestBody.content['application/json'];\n if (jsonContent?.schema) {\n const bodySchema = convertSchema(jsonContent.schema, refResolver);\n\n if (operation.requestBody.description) {\n shape.body = bodySchema.describe(operation.requestBody.description);\n } else {\n shape.body = bodySchema.describe('Request body');\n }\n\n if (!operation.requestBody.required) {\n shape.body = shape.body.optional();\n }\n } else {\n // 尝试其他内容类型\n const contentTypes = Object.keys(operation.requestBody.content);\n if (contentTypes.length > 0) {\n const firstContent = operation.requestBody.content[contentTypes[0]];\n if (firstContent?.schema) {\n const bodySchema = convertSchema(firstContent.schema, refResolver);\n shape.body = bodySchema.describe(`Request body (${contentTypes[0]})`);\n\n if (!operation.requestBody.required) {\n shape.body = shape.body.optional();\n }\n }\n }\n }\n }\n\n // 添加可选的 _baseUrl 参数\n shape._baseUrl = z\n .string()\n .url()\n .optional()\n .describe('API base URL (overrides the default). Example: https://api.example.com');\n\n return shape;\n}\n\n/**\n * 从 OpenAPI 操作生成 MCP 工具\n */\nexport function generateTool(\n operation: OpenApiOperation,\n components?: Record<string, OpenApiSchema>,\n toolPrefix?: string,\n fixedParams?: Record<string, string>\n): GeneratedTool {\n const refResolver = createRefResolver(components);\n\n const name = generateToolName(operation, toolPrefix);\n const description = generateToolDescription(operation);\n const parametersShape = buildParametersSchema(operation, refResolver, fixedParams);\n const inputSchema = z.object(parametersShape);\n\n logger.debug(`Generated tool: ${name}`);\n\n return {\n name,\n description,\n inputSchema,\n operation,\n };\n}\n\n/**\n * 批量生成工具\n */\nexport function generateTools(\n operations: OpenApiOperation[],\n components?: Record<string, OpenApiSchema>,\n toolPrefix?: string,\n fixedParams?: Record<string, string>\n): GeneratedTool[] {\n const tools: GeneratedTool[] = [];\n const usedNames = new Set<string>();\n\n for (const operation of operations) {\n const tool = generateTool(operation, components, toolPrefix, fixedParams);\n\n // 处理名称冲突\n if (usedNames.has(tool.name)) {\n let counter = 1;\n let newName = `${tool.name}_${counter}`;\n while (usedNames.has(newName)) {\n counter++;\n newName = `${tool.name}_${counter}`;\n }\n logger.warn(`Tool name conflict: ${tool.name} renamed to ${newName}`);\n tool.name = newName;\n }\n\n usedNames.add(tool.name);\n tools.push(tool);\n }\n\n logger.info(`Generated ${tools.length} tools`);\n return tools;\n}\n\nexport default {\n generateTool,\n generateTools,\n};\n","/**\n * HTTP 请求构建器\n */\n\nimport type { OpenApiOperation, OpenApiParameter, ParameterLocation } from '../parser/types.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * 构建后的请求参数\n */\nexport interface BuiltRequest {\n /** 请求路径(已替换路径参数) */\n path: string;\n /** 查询参数 */\n query: Record<string, string | string[]>;\n /** 请求头 */\n headers: Record<string, string>;\n /** 请求体 */\n body?: unknown;\n}\n\n/**\n * 根据参数位置分组\n */\nfunction groupParametersByLocation(\n parameters: OpenApiParameter[] | undefined\n): Record<ParameterLocation, OpenApiParameter[]> {\n const groups: Record<ParameterLocation, OpenApiParameter[]> = {\n path: [],\n query: [],\n header: [],\n cookie: [],\n };\n\n if (parameters) {\n for (const param of parameters) {\n groups[param.in].push(param);\n }\n }\n\n return groups;\n}\n\n/**\n * 构建请求\n */\nexport function buildRequest(\n operation: OpenApiOperation,\n input: Record<string, unknown>,\n defaultHeaders: Record<string, string> = {},\n fixedParams: Record<string, string> = {}\n): BuiltRequest {\n const groupedParams = groupParametersByLocation(operation.parameters);\n\n // 构建路径\n let path = operation.path;\n for (const param of groupedParams.path) {\n const value = input[param.name] ?? fixedParams[param.name];\n if (value !== undefined) {\n path = path.replace(`{${param.name}}`, String(value));\n } else if (param.required) {\n throw new Error(`Missing required path parameter: ${param.name}`);\n }\n }\n\n // 构建查询参数\n const query: Record<string, string | string[]> = {};\n for (const param of groupedParams.query) {\n const value = input[param.name] ?? fixedParams[param.name];\n if (value !== undefined) {\n if (Array.isArray(value)) {\n query[param.name] = value.map(String);\n } else {\n query[param.name] = String(value);\n }\n } else if (param.required) {\n throw new Error(`Missing required query parameter: ${param.name}`);\n }\n }\n\n // 构建请求头\n const headers: Record<string, string> = { ...defaultHeaders };\n for (const param of groupedParams.header) {\n const value = input[param.name];\n if (value !== undefined) {\n headers[param.name] = String(value);\n } else if (param.required) {\n throw new Error(`Missing required header parameter: ${param.name}`);\n }\n }\n\n // 处理请求体\n const body = input.body;\n\n // 设置 Content-Type(如果有请求体)\n if (body !== undefined && !headers['Content-Type']) {\n if (operation.requestBody?.content) {\n // 使用 OpenAPI 文档中定义的第一个内容类型\n const contentTypes = Object.keys(operation.requestBody.content);\n if (contentTypes.length > 0) {\n headers['Content-Type'] = contentTypes[0];\n }\n } else {\n headers['Content-Type'] = 'application/json';\n }\n }\n\n logger.debug(`Built request: ${operation.method} ${path}`, {\n query,\n headers,\n body: body ? '(body present)' : '(no body)',\n });\n\n return {\n path,\n query,\n headers,\n body,\n };\n}\n\n/**\n * 将查询参数追加到 URL\n */\nexport function appendQueryString(url: string, query: Record<string, string | string[]>): string {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (const v of value) {\n params.append(key, v);\n }\n } else {\n params.append(key, value);\n }\n }\n\n const queryString = params.toString();\n if (queryString) {\n return `${url}?${queryString}`;\n }\n\n return url;\n}\n\nexport default {\n buildRequest,\n appendQueryString,\n};\n","/**\n * HTTP 客户端\n */\n\nimport type { Config } from '../config/types.js';\nimport type { OpenApiOperation } from '../parser/types.js';\nimport { HttpError, ToolExecutionError } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\nimport { appendQueryString, buildRequest } from './request-builder.js';\n\n/**\n * HTTP 响应\n */\nexport interface HttpResponse {\n status: number;\n statusText: string;\n headers: Record<string, string>;\n body: unknown;\n}\n\n/**\n * 执行 HTTP 请求\n */\nexport async function executeRequest(\n operation: OpenApiOperation,\n input: Record<string, unknown>,\n config: Config\n): Promise<HttpResponse> {\n const baseUrl = config.baseUrl;\n\n // 如果没有 base URL,提供友好的错误提示\n if (!baseUrl) {\n throw new ToolExecutionError(\n 'No base URL configured. Please specify --base-url when starting the server, or provide _baseUrl parameter when calling the tool.',\n operation.operationId || operation.path\n );\n }\n\n try {\n // 构建请求\n const built = buildRequest(operation, input, config.headers || {}, config.fixedParams || {});\n\n // 构建完整 URL\n let url = `${baseUrl}${built.path}`;\n url = appendQueryString(url, built.query);\n\n logger.info(`Executing: ${operation.method} ${url}`);\n\n // 构建请求选项\n const requestInit: RequestInit = {\n method: operation.method,\n headers: built.headers,\n };\n\n // 添加请求体\n if (built.body !== undefined && !['GET', 'HEAD'].includes(operation.method.toUpperCase())) {\n requestInit.body = typeof built.body === 'string' ? built.body : JSON.stringify(built.body);\n }\n\n // 创建 AbortController 用于超时控制\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), config.timeout);\n requestInit.signal = controller.signal;\n\n // 执行请求\n const response = await fetch(url, requestInit);\n clearTimeout(timeoutId);\n\n // 解析响应头\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n\n // 解析响应体\n let body: unknown;\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n try {\n body = await response.json();\n } catch {\n body = await response.text();\n }\n } else if (contentType.includes('text/')) {\n body = await response.text();\n } else {\n // 尝试解析为 JSON,失败则返回文本\n try {\n body = await response.json();\n } catch {\n body = await response.text();\n }\n }\n\n logger.debug(`Response status: ${response.status}`);\n\n // 检查 HTTP 错误\n if (!response.ok) {\n throw new HttpError(\n `HTTP ${response.status} ${response.statusText}`,\n response.status,\n typeof body === 'string' ? body : JSON.stringify(body)\n );\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body,\n };\n } catch (error) {\n if (error instanceof HttpError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new ToolExecutionError(\n `Request timeout after ${config.timeout}ms`,\n operation.operationId || operation.path\n );\n }\n throw new ToolExecutionError(\n `Request failed: ${error.message}`,\n operation.operationId || operation.path,\n error\n );\n }\n\n throw new ToolExecutionError(\n 'Unknown error during request execution',\n operation.operationId || operation.path\n );\n }\n}\n\n/**\n * 格式化响应为字符串\n */\nexport function formatResponse(response: HttpResponse): string {\n const lines: string[] = [];\n\n lines.push(`Status: ${response.status} ${response.statusText}`);\n\n if (Object.keys(response.headers).length > 0) {\n lines.push('Headers:');\n for (const [key, value] of Object.entries(response.headers)) {\n lines.push(` ${key}: ${value}`);\n }\n }\n\n lines.push('Body:');\n if (typeof response.body === 'object' && response.body !== null) {\n lines.push(JSON.stringify(response.body, null, 2));\n } else {\n lines.push(String(response.body));\n }\n\n return lines.join('\\n');\n}\n\nexport default {\n executeRequest,\n formatResponse,\n};\n","/**\n * OpenAPI 解析器\n */\n\nimport SwaggerParser from '@apidevtools/swagger-parser';\nimport type { OpenAPI, OpenAPIV3 } from 'openapi-types';\nimport { OpenApiParseError } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\nimport type {\n OpenApiOperation,\n OpenApiParameter,\n OpenApiRequestBody,\n OpenApiSchema,\n ParameterLocation,\n ParsedOpenApiDoc,\n} from './types.js';\n\n/**\n * 判断是否为 OpenAPI v3 文档\n */\nfunction isOpenAPIV3(doc: OpenAPI.Document): doc is OpenAPIV3.Document {\n return 'openapi' in doc;\n}\n\n/**\n * 转换 OpenAPI 参数\n */\nfunction convertParameter(param: OpenAPIV3.ParameterObject): OpenApiParameter {\n return {\n name: param.name,\n in: param.in as ParameterLocation,\n required: param.required,\n description: param.description,\n schema: param.schema as OpenApiSchema | undefined,\n deprecated: param.deprecated,\n };\n}\n\n/**\n * 转换 OpenAPI Schema\n */\nfunction convertSchema(schema: OpenAPIV3.SchemaObject | undefined): OpenApiSchema | undefined {\n if (!schema) return undefined;\n return schema as OpenApiSchema;\n}\n\n/**\n * 转换请求体\n */\nfunction convertRequestBody(\n requestBody: OpenAPIV3.RequestBodyObject | OpenAPIV3.ReferenceObject | undefined\n): OpenApiRequestBody | undefined {\n if (!requestBody) return undefined;\n\n // 处理 $ref\n if ('$ref' in requestBody) {\n return undefined; // $ref 将在解析后被解析\n }\n\n const content: OpenApiRequestBody['content'] = {};\n for (const [contentType, mediaType] of Object.entries(requestBody.content || {})) {\n const mt = mediaType as OpenAPIV3.MediaTypeObject;\n content[contentType] = {\n schema: convertSchema(mt.schema as OpenAPIV3.SchemaObject | undefined),\n example: mt.example,\n };\n }\n\n return {\n description: requestBody.description,\n required: requestBody.required,\n content,\n };\n}\n\n/**\n * 提取 API 操作\n */\nfunction extractOperations(doc: OpenAPIV3.Document): OpenApiOperation[] {\n const operations: OpenApiOperation[] = [];\n\n if (!doc.paths) return operations;\n\n const methods = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] as const;\n\n for (const [path, pathItem] of Object.entries(doc.paths)) {\n if (!pathItem) continue;\n\n for (const method of methods) {\n const operation = pathItem[method];\n if (!operation) continue;\n\n // 收集参数(路径级 + 操作级)\n const parameters: OpenApiParameter[] = [];\n\n // 路径级参数\n if (pathItem.parameters) {\n for (const param of pathItem.parameters) {\n if (!('$ref' in param)) {\n parameters.push(convertParameter(param));\n }\n }\n }\n\n // 操作级参数\n if (operation.parameters) {\n for (const param of operation.parameters) {\n if (!('$ref' in param)) {\n parameters.push(convertParameter(param));\n }\n }\n }\n\n const op: OpenApiOperation = {\n method: method.toUpperCase(),\n path,\n operationId: operation.operationId,\n summary: operation.summary,\n description: operation.description,\n tags: operation.tags,\n parameters: parameters.length > 0 ? parameters : undefined,\n requestBody: convertRequestBody(\n operation.requestBody as\n | OpenAPIV3.RequestBodyObject\n | OpenAPIV3.ReferenceObject\n | undefined\n ),\n deprecated: operation.deprecated,\n };\n\n operations.push(op);\n }\n }\n\n return operations;\n}\n\n/**\n * 解析 OpenAPI 文档\n */\nexport async function parseOpenApi(source: string): Promise<ParsedOpenApiDoc> {\n try {\n logger.info(`Parsing OpenAPI document from: ${source}`);\n\n // 使用 SwaggerParser 解析和验证\n const api = await SwaggerParser.validate(source);\n\n // 检查版本\n if (!isOpenAPIV3(api)) {\n // 尝试转换 v2 到 v3\n if ('swagger' in api) {\n throw new OpenApiParseError(\n 'OpenAPI v2 (Swagger) is not supported. Please convert to OpenAPI v3 first.'\n );\n }\n throw new OpenApiParseError('Unsupported OpenAPI format');\n }\n\n const info: ParsedOpenApiDoc['info'] = {\n title: api.info.title,\n version: api.info.version,\n description: api.info.description,\n };\n\n const servers: ParsedOpenApiDoc['servers'] = api.servers?.map((s) => ({\n url: s.url,\n description: s.description,\n variables: s.variables,\n }));\n\n const operations = extractOperations(api);\n\n const components = api.components\n ? {\n schemas: api.components.schemas as Record<string, OpenApiSchema> | undefined,\n parameters: api.components.parameters as Record<string, OpenApiParameter> | undefined,\n requestBodies: api.components.requestBodies as\n | Record<string, OpenApiRequestBody>\n | undefined,\n }\n : undefined;\n\n logger.info(`Parsed ${operations.length} API operations`);\n\n return {\n openapi: api.openapi,\n info,\n servers,\n operations,\n components,\n };\n } catch (error) {\n if (error instanceof OpenApiParseError) {\n throw error;\n }\n throw new OpenApiParseError(\n `Failed to parse OpenAPI document: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error instanceof Error ? error : undefined\n );\n }\n}\n\n/**\n * 获取基础 URL\n */\nexport function getBaseUrl(doc: ParsedOpenApiDoc, overrideUrl?: string): string | undefined {\n if (overrideUrl) {\n logger.debug(`Using override base URL: ${overrideUrl}`);\n return overrideUrl;\n }\n\n if (doc.servers && doc.servers.length > 0) {\n const server = doc.servers[0];\n let url = server.url;\n\n // 处理变量替换\n if (server.variables) {\n for (const [name, variable] of Object.entries(server.variables)) {\n url = url.replace(`{${name}}`, variable.default);\n }\n }\n\n logger.debug(`Using base URL from OpenAPI servers: ${url}`);\n return url;\n }\n\n // 不再抛出错误,返回 undefined 并打印警告\n logger.warn(\n 'No base URL found in OpenAPI document. You may need to specify --base-url or provide _baseUrl when calling tools.'\n );\n return undefined;\n}\n\n/**\n * 获取所有 API 操作\n */\nexport function getOperations(doc: ParsedOpenApiDoc): OpenApiOperation[] {\n return doc.operations;\n}\n\nexport default {\n parseOpenApi,\n getBaseUrl,\n getOperations,\n};\n","/**\n * API 注册表\n * 用于存储、搜索和管理 API\n */\n\nimport { logger } from '../utils/logger.js';\nimport type {\n ApiDetail,\n ApiEntry,\n ListItem,\n ListOptions,\n ListResult,\n RegistryStats,\n SearchOptions,\n SearchResultItem,\n} from './types.js';\n\n/**\n * 默认每页数量\n */\nconst DEFAULT_PAGE_SIZE = 20;\n\n/**\n * 默认搜索限制\n */\nconst DEFAULT_SEARCH_LIMIT = 50;\n\n/**\n * API 注册表实现\n */\nexport class ApiRegistry {\n private apis: Map<string, ApiEntry> = new Map();\n private nameIndex: Map<string, string> = new Map(); // name -> id\n private tagIndex: Map<string, Set<string>> = new Map(); // tag -> set of ids\n\n /**\n * 注册 API\n */\n register(entry: ApiEntry): void {\n if (this.apis.has(entry.id)) {\n logger.warn(`API already registered: ${entry.id}, overwriting`);\n }\n\n this.apis.set(entry.id, entry);\n this.nameIndex.set(entry.name, entry.id);\n\n // 更新标签索引\n if (entry.tags) {\n for (const tag of entry.tags) {\n if (!this.tagIndex.has(tag)) {\n this.tagIndex.set(tag, new Set());\n }\n this.tagIndex.get(tag)?.add(entry.id);\n }\n }\n\n logger.debug(`Registered API: ${entry.id}`);\n }\n\n /**\n * 批量注册 API\n */\n registerAll(entries: ApiEntry[]): void {\n for (const entry of entries) {\n this.register(entry);\n }\n logger.info(`Registered ${entries.length} APIs in registry`);\n }\n\n /**\n * 获取单个 API\n */\n get(id: string): ApiEntry | undefined {\n return this.apis.get(id);\n }\n\n /**\n * 通过名称获取 API\n */\n getByName(name: string): ApiEntry | undefined {\n const id = this.nameIndex.get(name);\n return id ? this.apis.get(id) : undefined;\n }\n\n /**\n * 检查 API 是否存在\n */\n has(id: string): boolean {\n return this.apis.has(id);\n }\n\n /**\n * 搜索 API\n */\n search(options: SearchOptions): SearchResultItem[] {\n const {\n query,\n searchIn = ['name', 'summary', 'description', 'path'],\n limit = DEFAULT_SEARCH_LIMIT,\n } = options;\n\n const normalizedQuery = query.toLowerCase().trim();\n const results: SearchResultItem[] = [];\n\n for (const entry of this.apis.values()) {\n const matchedFields: string[] = [];\n let score = 0;\n\n // 搜索名称\n if (searchIn.includes('name') && entry.name) {\n const nameLower = entry.name.toLowerCase();\n if (nameLower.includes(normalizedQuery)) {\n matchedFields.push('name');\n // 精确匹配得分更高\n score += nameLower === normalizedQuery ? 1.0 : 0.8;\n }\n }\n\n // 搜索摘要\n if (searchIn.includes('summary') && entry.summary) {\n const summaryLower = entry.summary.toLowerCase();\n if (summaryLower.includes(normalizedQuery)) {\n matchedFields.push('summary');\n score += 0.6;\n }\n }\n\n // 搜索描述\n if (searchIn.includes('description') && entry.description) {\n const descLower = entry.description.toLowerCase();\n if (descLower.includes(normalizedQuery)) {\n matchedFields.push('description');\n score += 0.4;\n }\n }\n\n // 搜索路径\n if (searchIn.includes('path') && entry.path) {\n const pathLower = entry.path.toLowerCase();\n if (pathLower.includes(normalizedQuery)) {\n matchedFields.push('path');\n score += 0.5;\n }\n }\n\n if (matchedFields.length > 0) {\n results.push({\n id: entry.id,\n name: entry.name,\n method: entry.method,\n path: entry.path,\n summary: entry.summary,\n matchedFields,\n score: Math.min(score, 1.0),\n });\n }\n }\n\n // 按分数排序并限制数量\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n }\n\n /**\n * 分页列出 API\n */\n list(options: ListOptions = {}): ListResult {\n const { page = 1, pageSize = DEFAULT_PAGE_SIZE, tag } = options;\n\n // 获取过滤后的 API 列表\n let entries: ApiEntry[];\n if (tag) {\n const ids = this.tagIndex.get(tag);\n entries = ids\n ? Array.from(ids)\n .map((id) => this.apis.get(id))\n .filter((entry): entry is ApiEntry => entry !== undefined)\n : [];\n } else {\n entries = Array.from(this.apis.values());\n }\n\n const total = entries.length;\n const totalPages = Math.ceil(total / pageSize);\n const startIndex = (page - 1) * pageSize;\n const endIndex = startIndex + pageSize;\n\n // 分页\n const pageEntries = entries.slice(startIndex, endIndex);\n\n const items: ListItem[] = pageEntries.map((entry) => ({\n id: entry.id,\n name: entry.name,\n method: entry.method,\n path: entry.path,\n summary: entry.summary,\n tags: entry.tags,\n deprecated: entry.deprecated,\n }));\n\n return {\n page,\n pageSize,\n total,\n totalPages,\n items,\n };\n }\n\n /**\n * 获取所有标签\n */\n getTags(): string[] {\n return Array.from(this.tagIndex.keys()).sort();\n }\n\n /**\n * 获取 API 详情\n */\n getDetail(id: string): ApiDetail | undefined {\n const entry = this.apis.get(id);\n if (!entry) {\n return undefined;\n }\n\n return {\n ...entry,\n parameterSchema: this.buildParameterSchema(entry),\n requestBodySchema: this.buildRequestBodySchema(entry),\n responseSchemas: this.buildResponseSchemas(entry),\n };\n }\n\n /**\n * 获取统计信息\n */\n getStats(): RegistryStats {\n const byMethod: Record<string, number> = {};\n const byTag: Record<string, number> = {};\n\n for (const entry of this.apis.values()) {\n // 按方法统计\n const method = entry.method.toUpperCase();\n byMethod[method] = (byMethod[method] || 0) + 1;\n\n // 按标签统计\n if (entry.tags) {\n for (const tag of entry.tags) {\n byTag[tag] = (byTag[tag] || 0) + 1;\n }\n }\n }\n\n return {\n totalApis: this.apis.size,\n tags: this.getTags(),\n byMethod,\n byTag,\n };\n }\n\n /**\n * 获取 API 数量\n */\n get size(): number {\n return this.apis.size;\n }\n\n /**\n * 构建参数 Schema\n */\n private buildParameterSchema(entry: ApiEntry): Record<string, unknown> | undefined {\n const { operation } = entry;\n if (!operation.parameters || operation.parameters.length === 0) {\n return undefined;\n }\n\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const param of operation.parameters) {\n const paramName = param.name;\n properties[paramName] = {\n ...param.schema,\n description: param.description,\n in: param.in,\n };\n\n if (param.required) {\n required.push(paramName);\n }\n }\n\n return {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n };\n }\n\n /**\n * 构建请求体 Schema\n */\n private buildRequestBodySchema(entry: ApiEntry): Record<string, unknown> | undefined {\n const { operation } = entry;\n if (!operation.requestBody) {\n return undefined;\n }\n\n const jsonContent = operation.requestBody.content['application/json'];\n if (!jsonContent?.schema) {\n return undefined;\n }\n\n return {\n ...jsonContent.schema,\n description: operation.requestBody.description,\n bodyRequired: operation.requestBody.required,\n };\n }\n\n /**\n * 构建响应 Schema\n */\n private buildResponseSchemas(\n entry: ApiEntry\n ): Record<string, { description?: string; schema?: Record<string, unknown> }> | undefined {\n const { operation } = entry;\n if (!operation.responses) {\n return undefined;\n }\n\n const schemas: Record<string, { description?: string; schema?: Record<string, unknown> }> = {};\n\n for (const [status, response] of Object.entries(operation.responses)) {\n const jsonContent = response.content?.['application/json'];\n schemas[status] = {\n description: response.description,\n schema: jsonContent?.schema as Record<string, unknown> | undefined,\n };\n }\n\n return schemas;\n }\n}\n\nexport default ApiRegistry;\n","/**\n * api_detail 工具\n * 获取 API 详情\n */\n\nimport { z } from 'zod';\nimport type { ApiRegistry } from '../../registry/api-registry.js';\nimport { logger } from '../../utils/logger.js';\n\n/**\n * 输入参数 Schema\n */\nexport const apiDetailSchema = z.object({\n id: z.string().min(1).describe('API ID(operationId 或工具名称)'),\n});\n\nexport type ApiDetailInput = z.infer<typeof apiDetailSchema>;\n\n/**\n * 工具定义\n */\nexport const apiDetailTool = {\n name: 'api_detail',\n description: `获取 API 的详细信息。\n\n使用场景:\n- 查看某个 API 的完整参数定义\n- 了解请求体和响应的结构\n- 在调用 API 前了解需要哪些参数\n\n返回内容包括:\n- API 基本信息(方法、路径、描述)\n- 参数 Schema(路径参数、查询参数、头参数)\n- 请求体 Schema\n- 响应 Schema`,\n inputSchema: apiDetailSchema,\n};\n\n/**\n * 格式化 JSON Schema 为可读文本\n */\nfunction formatSchema(schema: Record<string, unknown> | undefined, indent = 0): string {\n if (!schema) return '无';\n\n const spaces = ' '.repeat(indent);\n const lines: string[] = [];\n\n if (schema.type) {\n lines.push(`${spaces}类型: ${schema.type}`);\n }\n\n if (schema.description) {\n lines.push(`${spaces}描述: ${schema.description}`);\n }\n\n if (schema.properties) {\n lines.push(`${spaces}属性:`);\n const props = schema.properties as Record<string, Record<string, unknown>>;\n const required = (schema.required as string[]) || [];\n\n for (const [name, prop] of Object.entries(props)) {\n const isRequired = required.includes(name);\n const reqTag = isRequired ? ' (必填)' : ' (可选)';\n const propType = (prop.type as string) || 'unknown';\n const propDesc = prop.description ? ` - ${prop.description as string}` : '';\n lines.push(`${spaces} - ${name}${reqTag}: ${propType}${propDesc}`);\n\n // 如果是嵌套对象,递归处理\n if (prop.properties) {\n lines.push(formatSchema(prop, indent + 2));\n }\n }\n }\n\n if (schema.enum) {\n lines.push(`${spaces}枚举值: ${(schema.enum as string[]).join(', ')}`);\n }\n\n if (schema.example !== undefined) {\n lines.push(`${spaces}示例: ${JSON.stringify(schema.example)}`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * 执行 api_detail 工具\n */\nexport function executeApiDetail(registry: ApiRegistry, input: ApiDetailInput): string {\n const { id } = input;\n\n logger.debug(`Executing api_detail: id=${id}`);\n\n const detail = registry.getDetail(id);\n\n if (!detail) {\n // 尝试通过名称查找\n const byName = registry.getByName(id);\n if (byName) {\n return executeApiDetail(registry, { id: byName.id });\n }\n\n return `错误: 找不到 API \"${id}\"\\n\\n请使用 api_search 搜索可用的 API。`;\n }\n\n const lines: string[] = [];\n\n // 基本信息\n lines.push(`## API: ${detail.name}`);\n lines.push('');\n\n const methodBadge = `[${detail.method.toUpperCase()}]`;\n const deprecatedTag = detail.deprecated ? ' ⚠️ 已废弃' : '';\n lines.push(`**${methodBadge}** \\`${detail.path}\\`${deprecatedTag}`);\n lines.push('');\n\n if (detail.summary) {\n lines.push(`**摘要**: ${detail.summary}`);\n lines.push('');\n }\n\n if (detail.description) {\n lines.push(`**描述**: ${detail.description}`);\n lines.push('');\n }\n\n if (detail.tags && detail.tags.length > 0) {\n lines.push(`**标签**: ${detail.tags.map((t) => `\\`${t}\\``).join(', ')}`);\n lines.push('');\n }\n\n // 参数\n lines.push('### 参数');\n lines.push('');\n if (detail.parameterSchema) {\n lines.push(formatSchema(detail.parameterSchema));\n } else {\n lines.push('无参数');\n }\n lines.push('');\n\n // 请求体\n if (detail.requestBodySchema) {\n const bodyRequired = detail.requestBodySchema.bodyRequired;\n lines.push('### 请求体');\n lines.push('');\n if (bodyRequired) {\n lines.push('**必填**: 是');\n lines.push('');\n }\n lines.push(formatSchema(detail.requestBodySchema));\n lines.push('');\n }\n\n // 响应\n if (detail.responseSchemas && Object.keys(detail.responseSchemas).length > 0) {\n lines.push('### 响应');\n lines.push('');\n for (const [status, resp] of Object.entries(detail.responseSchemas)) {\n lines.push(`#### 状态码: ${status}`);\n if (resp.description) {\n lines.push(`${resp.description}`);\n }\n if (resp.schema) {\n lines.push(formatSchema(resp.schema, 1));\n }\n lines.push('');\n }\n }\n\n // 使用提示\n lines.push('---');\n lines.push('### 调用方式');\n lines.push('');\n lines.push('使用 api_execute 工具调用此 API:');\n lines.push('```');\n lines.push(`api_execute(operationId=\"${detail.id}\", parameters={...})`);\n lines.push('```');\n\n return lines.join('\\n');\n}\n\nexport default {\n tool: apiDetailTool,\n execute: executeApiDetail,\n schema: apiDetailSchema,\n};\n","/**\n * api_execute 工具\n * 直接执行 API 调用\n */\n\nimport { z } from 'zod';\nimport type { Config } from '../../config/types.js';\nimport { executeRequest, formatResponse } from '../../executor/http-client.js';\nimport type { ApiRegistry } from '../../registry/api-registry.js';\nimport { ToolExecutionError } from '../../utils/error.js';\nimport { logger } from '../../utils/logger.js';\n\n/**\n * 输入参数 Schema\n */\nexport const apiExecuteSchema = z.object({\n operationId: z.string().min(1).describe('API ID(operationId 或工具名称)'),\n parameters: z.record(z.unknown()).optional().describe('API 参数(路径参数、查询参数、请求体等)'),\n _baseUrl: z.string().url().optional().describe('API base URL(可选,覆盖默认配置)'),\n});\n\nexport type ApiExecuteInput = z.infer<typeof apiExecuteSchema>;\n\n/**\n * 工具定义\n */\nexport const apiExecuteTool = {\n name: 'api_execute',\n description: `执行 API 调用。\n\n使用场景:\n- 直接调用已知的 API\n- 使用 api_search 或 api_list 找到 API 后执行调用\n\n使用步骤:\n1. 先使用 api_search 或 api_list 找到需要的 API\n2. 使用 api_detail 查看参数要求\n3. 使用 api_execute 执行调用\n\n参数说明:\n- operationId: API 的唯一标识符\n- parameters: 包含路径参数、查询参数、请求体等\n - 路径参数: URL 路径中的参数 (如 /users/{id} 中的 id)\n - 查询参数: URL 问号后的参数\n - body: 请求体(JSON 对象)`,\n inputSchema: apiExecuteSchema,\n};\n\n/**\n * 执行 api_execute 工具\n */\nexport async function executeApiExecute(\n registry: ApiRegistry,\n config: Config,\n input: ApiExecuteInput\n): Promise<string> {\n const { operationId, parameters = {}, _baseUrl } = input;\n\n logger.debug(`Executing api_execute: operationId=${operationId}`);\n\n // 从 Registry 获取 API 定义\n let apiEntry = registry.get(operationId);\n\n // 尝试通过名称查找\n if (!apiEntry) {\n apiEntry = registry.getByName(operationId);\n }\n\n if (!apiEntry) {\n return `错误: 找不到 API \"${operationId}\"\\n\\n请使用 api_search 搜索可用的 API。`;\n }\n\n // 检查是否废弃\n if (apiEntry.deprecated) {\n logger.warn(`API ${operationId} is deprecated`);\n }\n\n try {\n // 创建临时配置,优先使用参数中的 _baseUrl\n const executionConfig: Config = {\n ...config,\n baseUrl: _baseUrl || config.baseUrl,\n };\n\n // 检查是否有 base URL\n if (!executionConfig.baseUrl) {\n return `错误: 没有配置 base URL\n\n请通过以下方式之一提供 base URL:\n1. 在配置文件中设置 baseUrl\n2. 启动时使用 --base-url 参数\n3. 调用时提供 _baseUrl 参数`;\n }\n\n logger.info(`Executing API: ${apiEntry.method} ${apiEntry.path}`);\n\n // 执行请求\n const response = await executeRequest(apiEntry.operation, parameters, executionConfig);\n const formattedResponse = formatResponse(response);\n\n return formattedResponse;\n } catch (error) {\n const errorMessage =\n error instanceof ToolExecutionError\n ? `错误: ${error.message}`\n : `错误: ${error instanceof Error ? error.message : '未知错误'}`;\n\n logger.error(`API execution failed: ${operationId}`, error);\n\n return errorMessage;\n }\n}\n\nexport default {\n tool: apiExecuteTool,\n execute: executeApiExecute,\n schema: apiExecuteSchema,\n};\n","/**\n * api_list 工具\n * 分页浏览所有 API\n */\n\nimport { z } from 'zod';\nimport type { ApiRegistry } from '../../registry/api-registry.js';\nimport { logger } from '../../utils/logger.js';\n\n/**\n * 输入参数 Schema\n */\nexport const apiListSchema = z.object({\n page: z.number().int().min(1).default(1).describe('页码(从 1 开始)'),\n pageSize: z.number().int().min(1).max(100).default(20).describe('每页数量(1-100)'),\n tag: z.string().optional().describe('按标签过滤'),\n});\n\nexport type ApiListInput = z.infer<typeof apiListSchema>;\n\n/**\n * 工具定义\n */\nexport const apiListTool = {\n name: 'api_list',\n description: `分页浏览所有可用的 API。\n\n使用场景:\n- 查看有哪些 API 可用\n- 按标签过滤 API\n- 浏览 API 列表以找到需要的接口\n\n返回内容包括:API ID、名称、HTTP 方法、路径、摘要、标签等。`,\n inputSchema: apiListSchema,\n};\n\n/**\n * 执行 api_list 工具\n */\nexport function executeApiList(registry: ApiRegistry, input: ApiListInput): string {\n const { page, pageSize, tag } = input;\n\n logger.debug(`Executing api_list: page=${page}, pageSize=${pageSize}, tag=${tag}`);\n\n const result = registry.list({ page, pageSize, tag });\n\n const lines: string[] = [];\n\n // 添加统计信息\n lines.push(`## API 列表 (${result.total} 个 API)`);\n lines.push(`页码: ${result.page}/${result.totalPages}`);\n if (tag) {\n lines.push(`标签过滤: ${tag}`);\n }\n lines.push('');\n\n if (result.items.length === 0) {\n lines.push('没有找到匹配的 API。');\n return lines.join('\\n');\n }\n\n // 列出 API\n for (const item of result.items) {\n const methodBadge = `[${item.method.toUpperCase().padEnd(6)}]`;\n const deprecatedTag = item.deprecated ? ' [已废弃]' : '';\n const tags = item.tags ? ` (${item.tags.join(', ')})` : '';\n\n lines.push(`### ${item.id}`);\n lines.push(`${methodBadge} ${item.path}${deprecatedTag}${tags}`);\n if (item.summary) {\n lines.push(`${item.summary}`);\n }\n lines.push('');\n }\n\n // 添加分页提示\n if (result.totalPages > 1) {\n lines.push('---');\n if (result.page < result.totalPages) {\n lines.push(`使用 page=${result.page + 1} 查看下一页`);\n }\n }\n\n return lines.join('\\n');\n}\n\nexport default {\n tool: apiListTool,\n execute: executeApiList,\n schema: apiListSchema,\n};\n","/**\n * api_search 工具\n * 模糊搜索 API\n */\n\nimport { z } from 'zod';\nimport type { ApiRegistry } from '../../registry/api-registry.js';\nimport { logger } from '../../utils/logger.js';\n\n/**\n * 输入参数 Schema\n */\nexport const apiSearchSchema = z.object({\n query: z.string().min(1).describe('搜索关键词'),\n searchIn: z\n .array(z.enum(['name', 'summary', 'description', 'path']))\n .optional()\n .default(['name', 'summary', 'description', 'path'])\n .describe('搜索范围(默认搜索所有字段)'),\n limit: z.number().int().min(1).max(100).optional().default(20).describe('最大返回数量(1-100)'),\n});\n\nexport type ApiSearchInput = z.infer<typeof apiSearchSchema>;\n\n/**\n * 工具定义\n */\nexport const apiSearchTool = {\n name: 'api_search',\n description: `搜索 API。\n\n使用场景:\n- 根据关键词快速找到相关 API\n- 搜索特定功能或资源的接口\n- 查找包含特定路径段的 API\n\n搜索范围包括:API 名称、摘要、描述、路径。\n结果按匹配度排序,最匹配的排在前面。`,\n inputSchema: apiSearchSchema,\n};\n\n/**\n * 执行 api_search 工具\n */\nexport function executeApiSearch(registry: ApiRegistry, input: ApiSearchInput): string {\n const { query, searchIn, limit } = input;\n\n logger.debug(\n `Executing api_search: query=\"${query}\", searchIn=${searchIn?.join(',')}, limit=${limit}`\n );\n\n const results = registry.search({ query, searchIn, limit });\n\n const lines: string[] = [];\n\n lines.push(`## 搜索结果: \"${query}\"`);\n lines.push(`找到 ${results.length} 个匹配的 API`);\n lines.push('');\n\n if (results.length === 0) {\n lines.push('没有找到匹配的 API。');\n lines.push('');\n lines.push('建议:');\n lines.push('- 尝试使用不同的关键词');\n lines.push('- 检查拼写是否正确');\n lines.push('- 使用更通用的搜索词');\n return lines.join('\\n');\n }\n\n // 列出搜索结果\n for (const item of results) {\n const methodBadge = `[${item.method.toUpperCase().padEnd(6)}]`;\n const matchInfo = `匹配字段: ${item.matchedFields.join(', ')}`;\n\n lines.push(`### ${item.id}`);\n lines.push(`${methodBadge} ${item.path}`);\n if (item.summary) {\n lines.push(`${item.summary}`);\n }\n lines.push(`_${matchInfo}_ (相关度: ${Math.round(item.score * 100)}%)`);\n lines.push('');\n }\n\n lines.push('---');\n lines.push('使用 api_detail <id> 查看 API 详情');\n lines.push('使用 api_execute <id> <parameters> 执行 API');\n\n return lines.join('\\n');\n}\n\nexport default {\n tool: apiSearchTool,\n execute: executeApiSearch,\n schema: apiSearchSchema,\n};\n","/**\n * MCP 工具管理器\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { Config } from '../config/types.js';\nimport type { GeneratedTool } from '../converter/tool-generator.js';\nimport { executeRequest, formatResponse } from '../executor/http-client.js';\nimport type { OpenApiOperation } from '../parser/types.js';\nimport { ToolExecutionError } from '../utils/error.js';\nimport { logger } from '../utils/logger.js';\n\n/**\n * 工具管理器\n */\nexport class ToolManager {\n private tools: Map<string, GeneratedTool> = new Map();\n private config: Config;\n private server: McpServer;\n\n constructor(server: McpServer, config: Config) {\n this.server = server;\n this.config = config;\n }\n\n /**\n * 注册工具\n */\n registerTool(tool: GeneratedTool): void {\n if (this.tools.has(tool.name)) {\n logger.warn(`Tool already registered: ${tool.name}, overwriting`);\n }\n\n this.tools.set(tool.name, tool);\n\n // 使用 server.tool() 注册工具\n this.server.tool(\n tool.name,\n tool.description,\n tool.inputSchema.shape,\n async (args: Record<string, unknown>) => {\n return this.executeTool(tool.name, args);\n }\n );\n\n logger.debug(`Registered tool: ${tool.name}`);\n }\n\n /**\n * 批量注册工具\n */\n registerTools(tools: GeneratedTool[]): void {\n for (const tool of tools) {\n this.registerTool(tool);\n }\n logger.info(`Registered ${tools.length} tools`);\n }\n\n /**\n * 获取工具\n */\n getTool(name: string): GeneratedTool | undefined {\n return this.tools.get(name);\n }\n\n /**\n * 通过 operationId 获取工具\n */\n getToolByOperationId(operationId: string): GeneratedTool | undefined {\n for (const tool of this.tools.values()) {\n if (tool.operation.operationId === operationId) {\n return tool;\n }\n }\n return undefined;\n }\n\n /**\n * 执行工具\n */\n private async executeTool(\n toolName: string,\n args: Record<string, unknown>\n ): Promise<{ content: Array<{ type: 'text'; text: string }> }> {\n const tool = this.tools.get(toolName);\n\n if (!tool) {\n return {\n content: [\n {\n type: 'text',\n text: `Error: Tool not found: ${toolName}`,\n },\n ],\n };\n }\n\n try {\n logger.debug(`Executing tool: ${toolName}`, args);\n\n // 提取 _baseUrl 参数\n const { _baseUrl, ...restArgs } = args;\n\n // 创建临时配置,优先使用参数中的 _baseUrl\n const executionConfig = {\n ...this.config,\n baseUrl: typeof _baseUrl === 'string' ? _baseUrl : this.config.baseUrl,\n };\n\n const response = await executeRequest(tool.operation, restArgs, executionConfig);\n const formattedResponse = formatResponse(response);\n\n return {\n content: [\n {\n type: 'text',\n text: formattedResponse,\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof ToolExecutionError\n ? `Error: ${error.message}`\n : `Error: ${error instanceof Error ? error.message : 'Unknown error'}`;\n\n logger.error(`Tool execution failed: ${toolName}`, error);\n\n return {\n content: [\n {\n type: 'text',\n text: errorMessage,\n },\n ],\n };\n }\n }\n\n /**\n * 通过 operation 直接执行(用于 ondemand 模式)\n */\n async executeByOperation(\n operation: OpenApiOperation,\n args: Record<string, unknown>\n ): Promise<{ content: Array<{ type: 'text'; text: string }> }> {\n try {\n logger.debug(`Executing operation: ${operation.operationId || operation.path}`, args);\n\n // 提取 _baseUrl 参数\n const { _baseUrl, ...restArgs } = args;\n\n // 创建临时配置,优先使用参数中的 _baseUrl\n const executionConfig = {\n ...this.config,\n baseUrl: typeof _baseUrl === 'string' ? _baseUrl : this.config.baseUrl,\n };\n\n const response = await executeRequest(operation, restArgs, executionConfig);\n const formattedResponse = formatResponse(response);\n\n return {\n content: [\n {\n type: 'text',\n text: formattedResponse,\n },\n ],\n };\n } catch (error) {\n const errorMessage =\n error instanceof ToolExecutionError\n ? `Error: ${error.message}`\n : `Error: ${error instanceof Error ? error.message : 'Unknown error'}`;\n\n logger.error(`Operation execution failed: ${operation.operationId || operation.path}`, error);\n\n return {\n content: [\n {\n type: 'text',\n text: errorMessage,\n },\n ],\n };\n }\n }\n\n /**\n * 获取所有已注册的工具名称\n */\n getToolNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /**\n * 获取工具数量\n */\n getToolCount(): number {\n return this.tools.size;\n }\n\n /**\n * 获取配置\n */\n getConfig(): Config {\n return this.config;\n }\n}\n\nexport default ToolManager;\n","/**\n * MCP 服务器\n */\n\ndeclare const VERSION: string;\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { Config } from '../config/types.js';\nimport { generateTools } from '../converter/tool-generator.js';\nimport { getBaseUrl, parseOpenApi } from '../parser/swagger.js';\nimport { ApiRegistry } from '../registry/api-registry.js';\nimport type { ApiEntry } from '../registry/types.js';\nimport {\n apiDetailSchema,\n apiDetailTool,\n apiExecuteSchema,\n apiExecuteTool,\n apiListSchema,\n apiListTool,\n apiSearchSchema,\n apiSearchTool,\n executeApiDetail,\n executeApiExecute,\n executeApiList,\n executeApiSearch,\n} from '../tools/discovery/index.js';\nimport { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建 API Registry 并注册所有 API\n */\nfunction createRegistry(\n operations: ReturnType<typeof generateTools>,\n components?: Record<string, unknown>\n): ApiRegistry {\n const registry = new ApiRegistry();\n\n for (const tool of operations) {\n const entry: ApiEntry = {\n id: tool.operation.operationId || tool.name,\n name: tool.name,\n method: tool.operation.method,\n path: tool.operation.path,\n summary: tool.operation.summary,\n description: tool.operation.description,\n tags: tool.operation.tags,\n deprecated: tool.operation.deprecated,\n operation: tool.operation,\n components: components as\n | Record<string, import('../parser/types.js').OpenApiSchema>\n | undefined,\n };\n registry.register(entry);\n }\n\n return registry;\n}\n\n/**\n * 注册按需模式的 discovery tools\n */\nfunction registerOndemandTools(server: McpServer, registry: ApiRegistry, config: Config): void {\n // api_list\n server.tool(\n apiListTool.name,\n apiListTool.description,\n apiListSchema.shape,\n async (args: Record<string, unknown>) => {\n const result = executeApiList(registry, args as Parameters<typeof executeApiList>[1]);\n return { content: [{ type: 'text', text: result }] };\n }\n );\n\n // api_search\n server.tool(\n apiSearchTool.name,\n apiSearchTool.description,\n apiSearchSchema.shape,\n async (args: Record<string, unknown>) => {\n const result = executeApiSearch(registry, args as Parameters<typeof executeApiSearch>[1]);\n return { content: [{ type: 'text', text: result }] };\n }\n );\n\n // api_detail\n server.tool(\n apiDetailTool.name,\n apiDetailTool.description,\n apiDetailSchema.shape,\n async (args: Record<string, unknown>) => {\n const result = executeApiDetail(registry, args as Parameters<typeof executeApiDetail>[1]);\n return { content: [{ type: 'text', text: result }] };\n }\n );\n\n // api_execute\n server.tool(\n apiExecuteTool.name,\n apiExecuteTool.description,\n apiExecuteSchema.shape,\n async (args: Record<string, unknown>) => {\n const result = await executeApiExecute(\n registry,\n config,\n args as Parameters<typeof executeApiExecute>[2]\n );\n return { content: [{ type: 'text', text: result }] };\n }\n );\n\n logger.info('Registered 4 discovery tools (ondemand mode)');\n}\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n logger.info(`Mode: ${config.mode || 'default'}`);\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: VERSION,\n });\n\n // 解析 OpenAPI 文档\n const openApiDoc = await parseOpenApi(config.openapiUrl);\n\n // 获取基础 URL(可能为 undefined)\n const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);\n\n // 更新配置中的 baseUrl\n const effectiveConfig: Config = {\n ...config,\n baseUrl,\n };\n\n // 生成工具(用于获取操作定义)\n const tools = generateTools(\n openApiDoc.operations,\n openApiDoc.components?.schemas,\n config.toolPrefix,\n effectiveConfig.fixedParams\n );\n\n // 根据模式选择初始化路径\n if (config.mode === 'ondemand') {\n // 按需模式:创建 Registry,注册 discovery tools\n const registry = createRegistry(tools, openApiDoc.components?.schemas);\n registerOndemandTools(server, registry, effectiveConfig);\n\n const stats = registry.getStats();\n logger.info(`Server ready with ${stats.totalApis} APIs in registry`);\n logger.info(`Tags: ${stats.tags.slice(0, 5).join(', ')}${stats.tags.length > 5 ? '...' : ''}`);\n } else {\n // 默认模式:直接注册所有工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\n }\n\n return server;\n}\n\n/**\n * 启动服务器(使用 stdio 传输)\n */\nexport async function startServer(config: Config): Promise<void> {\n const server = await createServer(config);\n\n // 使用 stdio 传输\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n logger.info('Server started (stdio mode)');\n}\n\nexport default {\n createServer,\n startServer,\n};\n"],"mappings":"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","names":["z","name","z","convertSchema","z","z","z","z","z","z","z","z"]}
package/dist/cli.js CHANGED
@@ -125,6 +125,20 @@ function parseHeaders(headersStr) {
125
125
  );
126
126
  }
127
127
  }
128
+ function parseFixedParams(paramsStr) {
129
+ if (!paramsStr) return void 0;
130
+ try {
131
+ const parsed = JSON.parse(paramsStr);
132
+ if (typeof parsed === "object" && parsed !== null) {
133
+ return parsed;
134
+ }
135
+ throw new Error("Fixed params must be a JSON object");
136
+ } catch (error) {
137
+ throw new ConfigurationError(
138
+ `Invalid fixedParams JSON: ${error instanceof Error ? error.message : "Unknown error"}`
139
+ );
140
+ }
141
+ }
128
142
  function loadFromEnv(env) {
129
143
  const config = {};
130
144
  if (env.OPENAPI_URL) {
@@ -142,6 +156,9 @@ function loadFromEnv(env) {
142
156
  if (env.API_HEADERS) {
143
157
  config.headers = parseHeaders(env.API_HEADERS);
144
158
  }
159
+ if (env.API_FIXED_PARAMS) {
160
+ config.fixedParams = parseFixedParams(env.API_FIXED_PARAMS);
161
+ }
145
162
  if (env.DEBUG) {
146
163
  config.debug = env.DEBUG === "true" || env.DEBUG === "1";
147
164
  }
@@ -160,6 +177,7 @@ function loadFromFile(workingDir = process.cwd()) {
160
177
  baseUrl: parsed.baseUrl,
161
178
  timeout: parsed.timeout,
162
179
  headers: parsed.headers,
180
+ fixedParams: parsed.fixedParams,
163
181
  toolPrefix: parsed.toolPrefix,
164
182
  debug: parsed.debug,
165
183
  mode: parsed.mode
@@ -187,6 +205,9 @@ function loadFromCli(args) {
187
205
  if (args.headers) {
188
206
  config.headers = parseHeaders(args.headers);
189
207
  }
208
+ if (args.fixedParams) {
209
+ config.fixedParams = parseFixedParams(args.fixedParams);
210
+ }
190
211
  if (args.prefix) {
191
212
  config.toolPrefix = args.prefix;
192
213
  }
@@ -208,6 +229,7 @@ function mergeConfigs(...configs) {
208
229
  if (config.baseUrl !== void 0) merged.baseUrl = config.baseUrl;
209
230
  if (config.timeout !== void 0) merged.timeout = config.timeout;
210
231
  if (config.headers !== void 0) merged.headers = config.headers;
232
+ if (config.fixedParams !== void 0) merged.fixedParams = config.fixedParams;
211
233
  if (config.toolPrefix !== void 0) merged.toolPrefix = config.toolPrefix;
212
234
  if (config.debug !== void 0) merged.debug = config.debug;
213
235
  if (config.mode !== void 0) merged.mode = config.mode;
@@ -470,11 +492,14 @@ Tags: ${operation.tags.join(", ")}`);
470
492
  }
471
493
  return parts.join("\n");
472
494
  }
473
- function buildParametersSchema(operation, refResolver) {
495
+ function buildParametersSchema(operation, refResolver, fixedParams) {
474
496
  const shape = {};
475
497
  if (operation.parameters) {
476
498
  for (const param of operation.parameters) {
477
499
  const paramName = param.name;
500
+ if (fixedParams && paramName in fixedParams) {
501
+ continue;
502
+ }
478
503
  let paramSchema = convertSchema(param.schema, refResolver);
479
504
  if (param.description) {
480
505
  paramSchema = paramSchema.describe(param.description);
@@ -515,11 +540,11 @@ function buildParametersSchema(operation, refResolver) {
515
540
  shape._baseUrl = import_zod2.z.string().url().optional().describe("API base URL (overrides the default). Example: https://api.example.com");
516
541
  return shape;
517
542
  }
518
- function generateTool(operation, components, toolPrefix) {
543
+ function generateTool(operation, components, toolPrefix, fixedParams) {
519
544
  const refResolver = createRefResolver(components);
520
545
  const name = generateToolName(operation, toolPrefix);
521
546
  const description = generateToolDescription(operation);
522
- const parametersShape = buildParametersSchema(operation, refResolver);
547
+ const parametersShape = buildParametersSchema(operation, refResolver, fixedParams);
523
548
  const inputSchema = import_zod2.z.object(parametersShape);
524
549
  logger.debug(`Generated tool: ${name}`);
525
550
  return {
@@ -529,11 +554,11 @@ function generateTool(operation, components, toolPrefix) {
529
554
  operation
530
555
  };
531
556
  }
532
- function generateTools(operations, components, toolPrefix) {
557
+ function generateTools(operations, components, toolPrefix, fixedParams) {
533
558
  const tools = [];
534
559
  const usedNames = /* @__PURE__ */ new Set();
535
560
  for (const operation of operations) {
536
- const tool = generateTool(operation, components, toolPrefix);
561
+ const tool = generateTool(operation, components, toolPrefix, fixedParams);
537
562
  if (usedNames.has(tool.name)) {
538
563
  let counter = 1;
539
564
  let newName = `${tool.name}_${counter}`;
@@ -1107,11 +1132,11 @@ function groupParametersByLocation(parameters) {
1107
1132
  }
1108
1133
  return groups;
1109
1134
  }
1110
- function buildRequest(operation, input, defaultHeaders = {}) {
1135
+ function buildRequest(operation, input, defaultHeaders = {}, fixedParams = {}) {
1111
1136
  const groupedParams = groupParametersByLocation(operation.parameters);
1112
1137
  let path = operation.path;
1113
1138
  for (const param of groupedParams.path) {
1114
- const value = input[param.name];
1139
+ const value = input[param.name] ?? fixedParams[param.name];
1115
1140
  if (value !== void 0) {
1116
1141
  path = path.replace(`{${param.name}}`, String(value));
1117
1142
  } else if (param.required) {
@@ -1120,7 +1145,7 @@ function buildRequest(operation, input, defaultHeaders = {}) {
1120
1145
  }
1121
1146
  const query = {};
1122
1147
  for (const param of groupedParams.query) {
1123
- const value = input[param.name];
1148
+ const value = input[param.name] ?? fixedParams[param.name];
1124
1149
  if (value !== void 0) {
1125
1150
  if (Array.isArray(value)) {
1126
1151
  query[param.name] = value.map(String);
@@ -1191,7 +1216,7 @@ async function executeRequest(operation, input, config) {
1191
1216
  );
1192
1217
  }
1193
1218
  try {
1194
- const built = buildRequest(operation, input, config.headers || {});
1219
+ const built = buildRequest(operation, input, config.headers || {}, config.fixedParams || {});
1195
1220
  let url = `${baseUrl}${built.path}`;
1196
1221
  url = appendQueryString(url, built.query);
1197
1222
  logger.info(`Executing: ${operation.method} ${url}`);
@@ -1679,7 +1704,7 @@ async function createServer(config) {
1679
1704
  logger.info(`Mode: ${config.mode || "default"}`);
1680
1705
  const server = new import_mcp.McpServer({
1681
1706
  name: "api2mcp",
1682
- version: "0.1.0"
1707
+ version: "0.6.0"
1683
1708
  });
1684
1709
  const openApiDoc = await parseOpenApi(config.openapiUrl);
1685
1710
  const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
@@ -1690,7 +1715,8 @@ async function createServer(config) {
1690
1715
  const tools = generateTools(
1691
1716
  openApiDoc.operations,
1692
1717
  openApiDoc.components?.schemas,
1693
- config.toolPrefix
1718
+ config.toolPrefix,
1719
+ effectiveConfig.fixedParams
1694
1720
  );
1695
1721
  if (config.mode === "ondemand") {
1696
1722
  const registry = createRegistry(tools, openApiDoc.components?.schemas);
@@ -1714,7 +1740,10 @@ async function startServer(config) {
1714
1740
 
1715
1741
  // src/cli.ts
1716
1742
  var program = new import_commander.Command();
1717
- program.name("api2mcp").description("Convert OpenAPI specifications to MCP tools").version("0.1.0").option("-u, --url <url>", "OpenAPI document URL or file path").option("-b, --base-url <url>", "API base URL (overrides OpenAPI servers)").option("-t, --timeout <ms>", "Request timeout in milliseconds", parseInt).option("-h, --headers <json>", "Custom headers as JSON string").option("-p, --prefix <prefix>", "Tool name prefix").option(
1743
+ program.name("api2mcp").description("Convert OpenAPI specifications to MCP tools").version("0.6.0").option("-u, --url <url>", "OpenAPI document URL or file path").option("-b, --base-url <url>", "API base URL (overrides OpenAPI servers)").option("-t, --timeout <ms>", "Request timeout in milliseconds", parseInt).option("-h, --headers <json>", "Custom headers as JSON string").option(
1744
+ "-f, --fixed-params <json>",
1745
+ "Fixed parameters as JSON string (pre-filled, hidden from LLM)"
1746
+ ).option("-p, --prefix <prefix>", "Tool name prefix").option(
1718
1747
  "-m, --mode <mode>",
1719
1748
  "Working mode: default (all APIs as tools) or ondemand (discovery tools)",
1720
1749
  "default"
@@ -1726,6 +1755,7 @@ program.name("api2mcp").description("Convert OpenAPI specifications to MCP tools
1726
1755
  baseUrl: options.baseUrl,
1727
1756
  timeout: options.timeout,
1728
1757
  headers: options.headers,
1758
+ fixedParams: options.fixedParams,
1729
1759
  prefix: options.prefix,
1730
1760
  mode: options.mode,
1731
1761
  debug: options.debug