api2mcp 0.2.0 → 0.3.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/dist/{chunk-CVWZJCLP.mjs → chunk-YPGEM247.mjs} +20 -14
- package/dist/chunk-YPGEM247.mjs.map +1 -0
- package/dist/cli.js +19 -13
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-CVWZJCLP.mjs.map +0 -1
|
@@ -470,6 +470,7 @@ function buildParametersSchema(operation, refResolver) {
|
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
|
+
shape._baseUrl = z2.string().url().optional().describe("API base URL (overrides the default). Example: https://api.example.com");
|
|
473
474
|
return shape;
|
|
474
475
|
}
|
|
475
476
|
function generateTool(operation, components, toolPrefix) {
|
|
@@ -599,7 +600,13 @@ function appendQueryString(url, query) {
|
|
|
599
600
|
|
|
600
601
|
// src/executor/http-client.ts
|
|
601
602
|
async function executeRequest(operation, input, config) {
|
|
602
|
-
const baseUrl = config.baseUrl
|
|
603
|
+
const baseUrl = config.baseUrl;
|
|
604
|
+
if (!baseUrl) {
|
|
605
|
+
throw new ToolExecutionError(
|
|
606
|
+
"No base URL configured. Please specify --base-url when starting the server, or provide _baseUrl parameter when calling the tool.",
|
|
607
|
+
operation.operationId || operation.path
|
|
608
|
+
);
|
|
609
|
+
}
|
|
603
610
|
try {
|
|
604
611
|
const built = buildRequest(operation, input, config.headers || {});
|
|
605
612
|
let url = `${baseUrl}${built.path}`;
|
|
@@ -835,7 +842,10 @@ function getBaseUrl(doc, overrideUrl) {
|
|
|
835
842
|
logger.debug(`Using base URL from OpenAPI servers: ${url}`);
|
|
836
843
|
return url;
|
|
837
844
|
}
|
|
838
|
-
|
|
845
|
+
logger.warn(
|
|
846
|
+
"No base URL found in OpenAPI document. You may need to specify --base-url or provide _baseUrl when calling tools."
|
|
847
|
+
);
|
|
848
|
+
return void 0;
|
|
839
849
|
}
|
|
840
850
|
|
|
841
851
|
// src/server/tool-manager.ts
|
|
@@ -891,7 +901,12 @@ var ToolManager = class {
|
|
|
891
901
|
}
|
|
892
902
|
try {
|
|
893
903
|
logger.debug(`Executing tool: ${toolName}`, args);
|
|
894
|
-
const
|
|
904
|
+
const { _baseUrl, ...restArgs } = args;
|
|
905
|
+
const executionConfig = {
|
|
906
|
+
...this.config,
|
|
907
|
+
baseUrl: typeof _baseUrl === "string" ? _baseUrl : this.config.baseUrl
|
|
908
|
+
};
|
|
909
|
+
const response = await executeRequest(tool.operation, restArgs, executionConfig);
|
|
895
910
|
const formattedResponse = formatResponse(response);
|
|
896
911
|
return {
|
|
897
912
|
content: [
|
|
@@ -938,16 +953,7 @@ async function createServer(config) {
|
|
|
938
953
|
version: "0.1.0"
|
|
939
954
|
});
|
|
940
955
|
const openApiDoc = await parseOpenApi(config.openapiUrl);
|
|
941
|
-
|
|
942
|
-
try {
|
|
943
|
-
baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
944
|
-
} catch (error) {
|
|
945
|
-
if (config.baseUrl) {
|
|
946
|
-
baseUrl = config.baseUrl;
|
|
947
|
-
} else {
|
|
948
|
-
throw error;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
956
|
+
const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
951
957
|
const effectiveConfig = {
|
|
952
958
|
...config,
|
|
953
959
|
baseUrl
|
|
@@ -989,4 +995,4 @@ export {
|
|
|
989
995
|
createServer,
|
|
990
996
|
startServer
|
|
991
997
|
};
|
|
992
|
-
//# sourceMappingURL=chunk-
|
|
998
|
+
//# sourceMappingURL=chunk-YPGEM247.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/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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 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): 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 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): GeneratedTool {\n const refResolver = createRefResolver(components);\n\n const name = generateToolName(operation, toolPrefix);\n const description = generateToolDescription(operation);\n const parametersShape = buildParametersSchema(operation, refResolver);\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): 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);\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): 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];\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];\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 || {});\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 * 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 { 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 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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n","/**\n * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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"]}
|
package/dist/cli.js
CHANGED
|
@@ -506,6 +506,7 @@ function buildParametersSchema(operation, refResolver) {
|
|
|
506
506
|
}
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
|
+
shape._baseUrl = import_zod2.z.string().url().optional().describe("API base URL (overrides the default). Example: https://api.example.com");
|
|
509
510
|
return shape;
|
|
510
511
|
}
|
|
511
512
|
function generateTool(operation, components, toolPrefix) {
|
|
@@ -686,7 +687,10 @@ function getBaseUrl(doc, overrideUrl) {
|
|
|
686
687
|
logger.debug(`Using base URL from OpenAPI servers: ${url}`);
|
|
687
688
|
return url;
|
|
688
689
|
}
|
|
689
|
-
|
|
690
|
+
logger.warn(
|
|
691
|
+
"No base URL found in OpenAPI document. You may need to specify --base-url or provide _baseUrl when calling tools."
|
|
692
|
+
);
|
|
693
|
+
return void 0;
|
|
690
694
|
}
|
|
691
695
|
|
|
692
696
|
// src/executor/request-builder.ts
|
|
@@ -780,7 +784,13 @@ function appendQueryString(url, query) {
|
|
|
780
784
|
|
|
781
785
|
// src/executor/http-client.ts
|
|
782
786
|
async function executeRequest(operation, input, config) {
|
|
783
|
-
const baseUrl = config.baseUrl
|
|
787
|
+
const baseUrl = config.baseUrl;
|
|
788
|
+
if (!baseUrl) {
|
|
789
|
+
throw new ToolExecutionError(
|
|
790
|
+
"No base URL configured. Please specify --base-url when starting the server, or provide _baseUrl parameter when calling the tool.",
|
|
791
|
+
operation.operationId || operation.path
|
|
792
|
+
);
|
|
793
|
+
}
|
|
784
794
|
try {
|
|
785
795
|
const built = buildRequest(operation, input, config.headers || {});
|
|
786
796
|
let url = `${baseUrl}${built.path}`;
|
|
@@ -927,7 +937,12 @@ var ToolManager = class {
|
|
|
927
937
|
}
|
|
928
938
|
try {
|
|
929
939
|
logger.debug(`Executing tool: ${toolName}`, args);
|
|
930
|
-
const
|
|
940
|
+
const { _baseUrl, ...restArgs } = args;
|
|
941
|
+
const executionConfig = {
|
|
942
|
+
...this.config,
|
|
943
|
+
baseUrl: typeof _baseUrl === "string" ? _baseUrl : this.config.baseUrl
|
|
944
|
+
};
|
|
945
|
+
const response = await executeRequest(tool.operation, restArgs, executionConfig);
|
|
931
946
|
const formattedResponse = formatResponse(response);
|
|
932
947
|
return {
|
|
933
948
|
content: [
|
|
@@ -972,16 +987,7 @@ async function createServer(config) {
|
|
|
972
987
|
version: "0.1.0"
|
|
973
988
|
});
|
|
974
989
|
const openApiDoc = await parseOpenApi(config.openapiUrl);
|
|
975
|
-
|
|
976
|
-
try {
|
|
977
|
-
baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
978
|
-
} catch (error) {
|
|
979
|
-
if (config.baseUrl) {
|
|
980
|
-
baseUrl = config.baseUrl;
|
|
981
|
-
} else {
|
|
982
|
-
throw error;
|
|
983
|
-
}
|
|
984
|
-
}
|
|
990
|
+
const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
985
991
|
const effectiveConfig = {
|
|
986
992
|
...config,
|
|
987
993
|
baseUrl
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/config/loader.ts","../src/utils/error.ts","../src/utils/logger.ts","../src/server/index.ts","../src/converter/tool-generator.ts","../src/converter/schema-converter.ts","../src/parser/swagger.ts","../src/executor/request-builder.ts","../src/executor/http-client.ts","../src/server/tool-manager.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * CLI 入口\n */\n\nimport { Command } from 'commander';\nimport { loadConfig } from './config/loader.js';\nimport type { Config } from './config/types.js';\nimport { startServer } from './server/index.js';\nimport { ConfigurationError, OpenApiParseError } from './utils/error.js';\nimport { logger } from './utils/logger.js';\n\nconst program = new Command();\n\nprogram\n .name('api2mcp')\n .description('Convert OpenAPI specifications to MCP tools')\n .version('0.1.0')\n .option('-u, --url <url>', 'OpenAPI document URL or file path')\n .option('-b, --base-url <url>', 'API base URL (overrides OpenAPI servers)')\n .option('-t, --timeout <ms>', 'Request timeout in milliseconds', parseInt)\n .option('-h, --headers <json>', 'Custom headers as JSON string')\n .option('-p, --prefix <prefix>', 'Tool name prefix')\n .option('-d, --debug', 'Enable debug mode', false)\n .action(async (options) => {\n let config: Config | undefined;\n try {\n // 加载配置\n config = loadConfig({\n url: options.url,\n baseUrl: options.baseUrl,\n timeout: options.timeout,\n headers: options.headers,\n prefix: options.prefix,\n debug: options.debug,\n });\n\n logger.info(`Starting api2mcp...`);\n logger.info(`OpenAPI URL: ${config.openapiUrl}`);\n if (config.baseUrl) {\n logger.info(`Base URL: ${config.baseUrl}`);\n }\n\n // 启动服务器\n await startServer(config);\n } catch (error) {\n if (error instanceof ConfigurationError) {\n console.error(`Configuration error: ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof OpenApiParseError) {\n console.error(`OpenAPI parse error: ${error.message}`);\n process.exit(1);\n }\n\n console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);\n if (config?.debug && error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n });\n\n// 解析命令行参数\nprogram.parse();\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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 debug: config.debug,\n });\n\n return config;\n}\n\nexport default loadConfig;\n","/**\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 * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\n });\n\n // 解析 OpenAPI 文档\n const openApiDoc = await parseOpenApi(config.openapiUrl);\n\n // 获取基础 URL\n let baseUrl: string;\n try {\n baseUrl = getBaseUrl(openApiDoc, config.baseUrl);\n } catch (error) {\n if (config.baseUrl) {\n baseUrl = config.baseUrl;\n } else {\n throw error;\n }\n }\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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","/**\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): 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 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 return shape;\n}\n\n/**\n * 从 OpenAPI 操作生成 MCP 工具\n */\nexport function generateTool(\n operation: OpenApiOperation,\n components?: Record<string, OpenApiSchema>,\n toolPrefix?: 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);\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): 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);\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 * 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 * 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 {\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 throw new OpenApiParseError('No base URL found in OpenAPI document. Please specify --base-url.');\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 * 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): 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];\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];\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 try {\n // 构建请求\n const built = buildRequest(operation, input, config.headers || {});\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 * 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 { 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 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 const response = await executeRequest(tool.operation, args, this.config);\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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n"],"mappings":"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","names":["import_zod","name","convertSchema","SwaggerParser"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/config/loader.ts","../src/utils/error.ts","../src/utils/logger.ts","../src/server/index.ts","../src/converter/tool-generator.ts","../src/converter/schema-converter.ts","../src/parser/swagger.ts","../src/executor/request-builder.ts","../src/executor/http-client.ts","../src/server/tool-manager.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * CLI 入口\n */\n\nimport { Command } from 'commander';\nimport { loadConfig } from './config/loader.js';\nimport type { Config } from './config/types.js';\nimport { startServer } from './server/index.js';\nimport { ConfigurationError, OpenApiParseError } from './utils/error.js';\nimport { logger } from './utils/logger.js';\n\nconst program = new Command();\n\nprogram\n .name('api2mcp')\n .description('Convert OpenAPI specifications to MCP tools')\n .version('0.1.0')\n .option('-u, --url <url>', 'OpenAPI document URL or file path')\n .option('-b, --base-url <url>', 'API base URL (overrides OpenAPI servers)')\n .option('-t, --timeout <ms>', 'Request timeout in milliseconds', parseInt)\n .option('-h, --headers <json>', 'Custom headers as JSON string')\n .option('-p, --prefix <prefix>', 'Tool name prefix')\n .option('-d, --debug', 'Enable debug mode', false)\n .action(async (options) => {\n let config: Config | undefined;\n try {\n // 加载配置\n config = loadConfig({\n url: options.url,\n baseUrl: options.baseUrl,\n timeout: options.timeout,\n headers: options.headers,\n prefix: options.prefix,\n debug: options.debug,\n });\n\n logger.info(`Starting api2mcp...`);\n logger.info(`OpenAPI URL: ${config.openapiUrl}`);\n if (config.baseUrl) {\n logger.info(`Base URL: ${config.baseUrl}`);\n }\n\n // 启动服务器\n await startServer(config);\n } catch (error) {\n if (error instanceof ConfigurationError) {\n console.error(`Configuration error: ${error.message}`);\n process.exit(1);\n }\n\n if (error instanceof OpenApiParseError) {\n console.error(`OpenAPI parse error: ${error.message}`);\n process.exit(1);\n }\n\n console.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);\n if (config?.debug && error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n });\n\n// 解析命令行参数\nprogram.parse();\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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 debug: config.debug,\n });\n\n return config;\n}\n\nexport default loadConfig;\n","/**\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 * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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","/**\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): 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 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): GeneratedTool {\n const refResolver = createRefResolver(components);\n\n const name = generateToolName(operation, toolPrefix);\n const description = generateToolDescription(operation);\n const parametersShape = buildParametersSchema(operation, refResolver);\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): 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);\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 * 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 * 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 * 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): 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];\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];\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 || {});\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 * 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 { 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 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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n"],"mappings":"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","names":["import_zod","name","convertSchema","SwaggerParser"]}
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -288,7 +288,7 @@ declare function parseOpenApi(source: string): Promise<ParsedOpenApiDoc>;
|
|
|
288
288
|
/**
|
|
289
289
|
* 获取基础 URL
|
|
290
290
|
*/
|
|
291
|
-
declare function getBaseUrl(doc: ParsedOpenApiDoc, overrideUrl?: string): string;
|
|
291
|
+
declare function getBaseUrl(doc: ParsedOpenApiDoc, overrideUrl?: string): string | undefined;
|
|
292
292
|
|
|
293
293
|
/**
|
|
294
294
|
* MCP 服务器
|
package/dist/index.d.ts
CHANGED
|
@@ -288,7 +288,7 @@ declare function parseOpenApi(source: string): Promise<ParsedOpenApiDoc>;
|
|
|
288
288
|
/**
|
|
289
289
|
* 获取基础 URL
|
|
290
290
|
*/
|
|
291
|
-
declare function getBaseUrl(doc: ParsedOpenApiDoc, overrideUrl?: string): string;
|
|
291
|
+
declare function getBaseUrl(doc: ParsedOpenApiDoc, overrideUrl?: string): string | undefined;
|
|
292
292
|
|
|
293
293
|
/**
|
|
294
294
|
* MCP 服务器
|
package/dist/index.js
CHANGED
|
@@ -525,6 +525,7 @@ function buildParametersSchema(operation, refResolver) {
|
|
|
525
525
|
}
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
|
+
shape._baseUrl = import_zod2.z.string().url().optional().describe("API base URL (overrides the default). Example: https://api.example.com");
|
|
528
529
|
return shape;
|
|
529
530
|
}
|
|
530
531
|
function generateTool(operation, components, toolPrefix) {
|
|
@@ -654,7 +655,13 @@ function appendQueryString(url, query) {
|
|
|
654
655
|
|
|
655
656
|
// src/executor/http-client.ts
|
|
656
657
|
async function executeRequest(operation, input, config) {
|
|
657
|
-
const baseUrl = config.baseUrl
|
|
658
|
+
const baseUrl = config.baseUrl;
|
|
659
|
+
if (!baseUrl) {
|
|
660
|
+
throw new ToolExecutionError(
|
|
661
|
+
"No base URL configured. Please specify --base-url when starting the server, or provide _baseUrl parameter when calling the tool.",
|
|
662
|
+
operation.operationId || operation.path
|
|
663
|
+
);
|
|
664
|
+
}
|
|
658
665
|
try {
|
|
659
666
|
const built = buildRequest(operation, input, config.headers || {});
|
|
660
667
|
let url = `${baseUrl}${built.path}`;
|
|
@@ -890,7 +897,10 @@ function getBaseUrl(doc, overrideUrl) {
|
|
|
890
897
|
logger.debug(`Using base URL from OpenAPI servers: ${url}`);
|
|
891
898
|
return url;
|
|
892
899
|
}
|
|
893
|
-
|
|
900
|
+
logger.warn(
|
|
901
|
+
"No base URL found in OpenAPI document. You may need to specify --base-url or provide _baseUrl when calling tools."
|
|
902
|
+
);
|
|
903
|
+
return void 0;
|
|
894
904
|
}
|
|
895
905
|
|
|
896
906
|
// src/server/index.ts
|
|
@@ -950,7 +960,12 @@ var ToolManager = class {
|
|
|
950
960
|
}
|
|
951
961
|
try {
|
|
952
962
|
logger.debug(`Executing tool: ${toolName}`, args);
|
|
953
|
-
const
|
|
963
|
+
const { _baseUrl, ...restArgs } = args;
|
|
964
|
+
const executionConfig = {
|
|
965
|
+
...this.config,
|
|
966
|
+
baseUrl: typeof _baseUrl === "string" ? _baseUrl : this.config.baseUrl
|
|
967
|
+
};
|
|
968
|
+
const response = await executeRequest(tool.operation, restArgs, executionConfig);
|
|
954
969
|
const formattedResponse = formatResponse(response);
|
|
955
970
|
return {
|
|
956
971
|
content: [
|
|
@@ -995,16 +1010,7 @@ async function createServer(config) {
|
|
|
995
1010
|
version: "0.1.0"
|
|
996
1011
|
});
|
|
997
1012
|
const openApiDoc = await parseOpenApi(config.openapiUrl);
|
|
998
|
-
|
|
999
|
-
try {
|
|
1000
|
-
baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
1001
|
-
} catch (error) {
|
|
1002
|
-
if (config.baseUrl) {
|
|
1003
|
-
baseUrl = config.baseUrl;
|
|
1004
|
-
} else {
|
|
1005
|
-
throw error;
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1013
|
+
const baseUrl = getBaseUrl(openApiDoc, config.baseUrl);
|
|
1008
1014
|
const effectiveConfig = {
|
|
1009
1015
|
...config,
|
|
1010
1016
|
baseUrl
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config/loader.ts","../src/utils/error.ts","../src/utils/logger.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/server/index.ts","../src/server/tool-manager.ts"],"sourcesContent":["/**\n * 入口导出\n */\n\nexport { loadConfig } from './config/loader.js';\nexport type { ApiHeaders, ApiSourceConfig, Config } from './config/types.js';\nexport { convertSchema, createRefResolver } from './converter/schema-converter.js';\nexport type { GeneratedTool } from './converter/tool-generator.js';\nexport { generateTool, generateTools } from './converter/tool-generator.js';\nexport type { HttpResponse } from './executor/http-client.js';\nexport { executeRequest, formatResponse } from './executor/http-client.js';\nexport { getBaseUrl, parseOpenApi } from './parser/swagger.js';\nexport type {\n OpenApiOperation,\n OpenApiParameter,\n OpenApiSchema,\n ParsedOpenApiDoc,\n} from './parser/types.js';\n\nexport { createServer, startServer } from './server/index.js';\nexport { ToolManager } from './server/tool-manager.js';\n\nexport {\n Api2McpError,\n ConfigurationError,\n HttpError,\n OpenApiParseError,\n ToolExecutionError,\n} from './utils/error.js';\n\nexport { logger } from './utils/logger.js';\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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 debug: config.debug,\n });\n\n return config;\n}\n\nexport default loadConfig;\n","/**\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 * 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): 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 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 return shape;\n}\n\n/**\n * 从 OpenAPI 操作生成 MCP 工具\n */\nexport function generateTool(\n operation: OpenApiOperation,\n components?: Record<string, OpenApiSchema>,\n toolPrefix?: 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);\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): 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);\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): 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];\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];\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 try {\n // 构建请求\n const built = buildRequest(operation, input, config.headers || {});\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 {\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 throw new OpenApiParseError('No base URL found in OpenAPI document. Please specify --base-url.');\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 * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\n });\n\n // 解析 OpenAPI 文档\n const openApiDoc = await parseOpenApi(config.openapiUrl);\n\n // 获取基础 URL\n let baseUrl: string;\n try {\n baseUrl = getBaseUrl(openApiDoc, config.baseUrl);\n } catch (error) {\n if (config.baseUrl) {\n baseUrl = config.baseUrl;\n } else {\n throw error;\n }\n }\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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","/**\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 { 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 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 const response = await executeRequest(tool.operation, args, this.config);\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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n"],"mappings":"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","names":["import_zod","name","convertSchema","SwaggerParser"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/loader.ts","../src/utils/error.ts","../src/utils/logger.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/server/index.ts","../src/server/tool-manager.ts"],"sourcesContent":["/**\n * 入口导出\n */\n\nexport { loadConfig } from './config/loader.js';\nexport type { ApiHeaders, ApiSourceConfig, Config } from './config/types.js';\nexport { convertSchema, createRefResolver } from './converter/schema-converter.js';\nexport type { GeneratedTool } from './converter/tool-generator.js';\nexport { generateTool, generateTools } from './converter/tool-generator.js';\nexport type { HttpResponse } from './executor/http-client.js';\nexport { executeRequest, formatResponse } from './executor/http-client.js';\nexport { getBaseUrl, parseOpenApi } from './parser/swagger.js';\nexport type {\n OpenApiOperation,\n OpenApiParameter,\n OpenApiSchema,\n ParsedOpenApiDoc,\n} from './parser/types.js';\n\nexport { createServer, startServer } from './server/index.js';\nexport { ToolManager } from './server/tool-manager.js';\n\nexport {\n Api2McpError,\n ConfigurationError,\n HttpError,\n OpenApiParseError,\n ToolExecutionError,\n} from './utils/error.js';\n\nexport { logger } from './utils/logger.js';\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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 debug: config.debug,\n });\n\n return config;\n}\n\nexport default loadConfig;\n","/**\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 * 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): 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 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): GeneratedTool {\n const refResolver = createRefResolver(components);\n\n const name = generateToolName(operation, toolPrefix);\n const description = generateToolDescription(operation);\n const parametersShape = buildParametersSchema(operation, refResolver);\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): 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);\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): 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];\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];\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 || {});\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 * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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","/**\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 { 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 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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n"],"mappings":"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","names":["import_zod","name","convertSchema","SwaggerParser"]}
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
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/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 * 从环境变量加载配置\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.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 toolPrefix: parsed.toolPrefix,\n debug: parsed.debug,\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.prefix) {\n config.toolPrefix = args.prefix;\n }\n\n if (args.debug !== undefined) {\n config.debug = args.debug;\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.toolPrefix !== undefined) merged.toolPrefix = config.toolPrefix;\n if (config.debug !== undefined) merged.debug = config.debug;\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 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): 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 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 return shape;\n}\n\n/**\n * 从 OpenAPI 操作生成 MCP 工具\n */\nexport function generateTool(\n operation: OpenApiOperation,\n components?: Record<string, OpenApiSchema>,\n toolPrefix?: 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);\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): 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);\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): 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];\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];\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 try {\n // 构建请求\n const built = buildRequest(operation, input, config.headers || {});\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 {\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 throw new OpenApiParseError('No base URL found in OpenAPI document. Please specify --base-url.');\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 * 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 { 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 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 const response = await executeRequest(tool.operation, args, this.config);\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 * 获取所有已注册的工具名称\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\nexport default ToolManager;\n","/**\n * MCP 服务器\n */\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 { logger } from '../utils/logger.js';\nimport { ToolManager } from './tool-manager.js';\n\n/**\n * 创建并启动 MCP 服务器\n */\nexport async function createServer(config: Config): Promise<McpServer> {\n logger.info('Creating MCP server...');\n\n // 创建 MCP 服务器实例\n const server = new McpServer({\n name: 'api2mcp',\n version: '0.1.0',\n });\n\n // 解析 OpenAPI 文档\n const openApiDoc = await parseOpenApi(config.openapiUrl);\n\n // 获取基础 URL\n let baseUrl: string;\n try {\n baseUrl = getBaseUrl(openApiDoc, config.baseUrl);\n } catch (error) {\n if (config.baseUrl) {\n baseUrl = config.baseUrl;\n } else {\n throw error;\n }\n }\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 );\n\n // 创建工具管理器并注册工具\n const toolManager = new ToolManager(server, effectiveConfig);\n toolManager.registerTools(tools);\n\n logger.info(`Server ready with ${toolManager.getToolCount()} tools`);\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"]}
|