apifox-import-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # MCP Apifox Import Server
2
+
3
+ 一个基于 MCP (Model Context Protocol) 的服务器,用于将 OpenAPI 3/Swagger 2 格式数据导入到 Apifox 平台。
4
+
5
+ ## 快速开始
6
+
7
+ ### Claude Desktop 配置
8
+
9
+ 在 `mcp.json` 中添加:
10
+
11
+ ```json
12
+ {
13
+ "servers": {
14
+ "apifox-import": {
15
+ "command": "npx",
16
+ "args": ["-y", "apifox-import-mcp", "--project-id", "<your-project-id>"],
17
+ "env": {
18
+ "APIFOX_ACCESS_TOKEN": "<your-access-token>"
19
+ }
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ ## 功能特性
26
+
27
+ - 支持 OpenAPI 3 和 Swagger 2 格式数据导入
28
+ - 提供丰富的导入选项(目录、覆盖行为、分支等)
29
+ - 基于 stdio 的 MCP 传输方式
30
+
31
+ ## 获取 Apifox 访问令牌
32
+
33
+ 1. 登录 [Apifox](https://app.apifox.com)
34
+ 2. 进入「开放平台」
35
+ 3. 创建系统级访问令牌
36
+ 4. 将令牌复制到 `mcp配置` 文件中
37
+
38
+ ## 获取 Apifox 项目 ID
39
+
40
+ 项目 ID 可以从 Apifox 项目 URL 中获取:
41
+ 1. 在 Apifox 中打开您的项目
42
+ 2. 浏览器地址栏的 URL 格式为:`https://app.apifox.com/project/{projectId}/...`
43
+ 3. `{projectId}` 部分即为项目 ID
44
+
45
+ ## 开发
46
+
47
+ ```bash
48
+ # 构建
49
+ npm run build
50
+
51
+ # 运行
52
+ npm start
53
+
54
+ # 开发模式(构建后运行)
55
+ npm run dev
56
+
57
+ # 监听模式
58
+ npm run watch
59
+ ```
60
+
61
+ ## MCP 工具
62
+
63
+ ### import-openapi
64
+
65
+ 将 OpenAPI 3/Swagger 2 数据导入到 Apifox 项目。项目 ID 需要在 MCP 配置中设置。
66
+
67
+ #### 参数
68
+
69
+ - `input` (必填): OpenAPI 数据,支持以下格式:
70
+ - `string`: JSON/YAML 格式的 OpenAPI 数据字符串
71
+ - `options` (可选): 导入配置选项
72
+ - `targetEndpointFolderId`: 目标接口目录 ID
73
+ - `targetSchemaFolderId`: 目标数据模型目录 ID
74
+ - `endpointOverwriteBehavior`: 接口覆盖行为
75
+ - `schemaOverwriteBehavior`: 数据模型覆盖行为
76
+ - `updateFolderOfChangedEndpoint`: 是否更新接口目录
77
+ - `prependBasePath`: 是否添加基础路径
78
+ - `targetBranchId`: 目标分支 ID
79
+ - `moduleId`: 目标模块 ID
80
+
81
+ #### 示例
82
+
83
+ ```json
84
+ {
85
+ "input": "{\"openapi\":\"3.0.1\",\"info\":{\"title\":\"API\"},\"paths\":{}}",
86
+ "options": {
87
+ "targetEndpointFolderId": 0,
88
+ "endpointOverwriteBehavior": "OVERWRITE_EXISTING"
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## 许可证
94
+
95
+ MIT
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Apifox API 客户端
3
+ */
4
+ import { EnvConfig, ImportRequest, ImportResponse, ImportError } from './types.js';
5
+ export declare class ApifoxClient {
6
+ private baseUrl;
7
+ private apiVersion;
8
+ private accessToken;
9
+ constructor(config: EnvConfig);
10
+ /**
11
+ * 创建带有认证的请求头
12
+ */
13
+ private getHeaders;
14
+ /**
15
+ * 执行 HTTP POST 请求(带详细错误处理)
16
+ */
17
+ private post;
18
+ /**
19
+ * 导入 OpenAPI 数据到 Apifox
20
+ * @param projectId Apifox 项目 ID
21
+ * @param request 导入请求体
22
+ * @returns 导入结果
23
+ */
24
+ importOpenAPI(projectId: string, request: ImportRequest): Promise<ImportResponse>;
25
+ /**
26
+ * 格式化错误信息
27
+ */
28
+ static formatErrors(errors: ImportError[]): string;
29
+ /**
30
+ * 格式化导入结果为易读的文本
31
+ */
32
+ static formatImportResult(response: ImportResponse | any): string;
33
+ }
34
+ //# sourceMappingURL=apifox-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apifox-client.d.ts","sourceRoot":"","sources":["../src/apifox-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,SAAS,EACT,aAAa,EACb,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,SAAS;IAM7B;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;YACW,IAAI;IAmClB;;;;;OAKG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC;IAc1B;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM;IAUlD;;OAEG;IACH,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,cAAc,GAAG,GAAG,GAC7B,MAAM;CAyDV"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Apifox API 客户端
3
+ */
4
+ export class ApifoxClient {
5
+ baseUrl;
6
+ apiVersion;
7
+ accessToken;
8
+ constructor(config) {
9
+ this.baseUrl = config.APIFOX_API_BASE_URL;
10
+ this.apiVersion = config.APIFOX_API_VERSION;
11
+ this.accessToken = config.APIFOX_ACCESS_TOKEN;
12
+ }
13
+ /**
14
+ * 创建带有认证的请求头
15
+ */
16
+ getHeaders() {
17
+ return {
18
+ 'X-Apifox-Api-Version': this.apiVersion,
19
+ 'Authorization': `Bearer ${this.accessToken}`,
20
+ 'Content-Type': 'application/json',
21
+ };
22
+ }
23
+ /**
24
+ * 执行 HTTP POST 请求(带详细错误处理)
25
+ */
26
+ async post(url, body) {
27
+ try {
28
+ const response = await fetch(url, {
29
+ method: 'POST',
30
+ headers: this.getHeaders(),
31
+ body: JSON.stringify(body),
32
+ });
33
+ if (!response.ok) {
34
+ let errorText = '';
35
+ try {
36
+ errorText = await response.text();
37
+ // 尝试解析 JSON 错误响应
38
+ const errorJson = JSON.parse(errorText);
39
+ if (errorJson.message) {
40
+ errorText = errorJson.message;
41
+ }
42
+ }
43
+ catch {
44
+ // 如果不是 JSON,使用原始文本
45
+ }
46
+ throw new Error(`API request failed with status ${response.status}: ${errorText}`);
47
+ }
48
+ const json = await response.json();
49
+ return json;
50
+ }
51
+ catch (error) {
52
+ if (error instanceof Error) {
53
+ throw new Error(`Failed to call Apifox API: ${error.message}`);
54
+ }
55
+ throw new Error('Unknown error occurred while calling Apifox API');
56
+ }
57
+ }
58
+ /**
59
+ * 导入 OpenAPI 数据到 Apifox
60
+ * @param projectId Apifox 项目 ID
61
+ * @param request 导入请求体
62
+ * @returns 导入结果
63
+ */
64
+ async importOpenAPI(projectId, request) {
65
+ const url = `${this.baseUrl}/v1/projects/${projectId}/import-openapi`;
66
+ try {
67
+ const response = await this.post(url, request);
68
+ return response;
69
+ }
70
+ catch (error) {
71
+ if (error instanceof Error) {
72
+ throw new Error(`Failed to import OpenAPI: ${error.message}`);
73
+ }
74
+ throw new Error('Unknown error occurred while importing OpenAPI');
75
+ }
76
+ }
77
+ /**
78
+ * 格式化错误信息
79
+ */
80
+ static formatErrors(errors) {
81
+ if (errors.length === 0) {
82
+ return '无错误';
83
+ }
84
+ return errors
85
+ .map((error, index) => `${index + 1}. [${error.code}] ${error.message}`)
86
+ .join('\n');
87
+ }
88
+ /**
89
+ * 格式化导入结果为易读的文本
90
+ */
91
+ static formatImportResult(response) {
92
+ const result = [];
93
+ result.push('=== 导入结果 ===\n');
94
+ // 检查响应结构
95
+ if (!response.data) {
96
+ result.push('❌ 响应数据格式错误');
97
+ result.push(`响应内容: ${JSON.stringify(response, null, 2)}`);
98
+ return result.join('\n');
99
+ }
100
+ const { counters, errors } = response.data;
101
+ // 如果缺少 counters 或 errors,显示错误
102
+ if (!counters) {
103
+ result.push('❌ 响应缺少 counters 字段');
104
+ result.push(`响应内容: ${JSON.stringify(response, null, 2)}`);
105
+ return result.join('\n');
106
+ }
107
+ // 接口统计
108
+ result.push('📋 接口:');
109
+ result.push(` 新增: ${counters.endpointCreated || 0}`);
110
+ result.push(` 更新: ${counters.endpointUpdated || 0}`);
111
+ result.push(` 忽略: ${counters.endpointIgnored || 0}`);
112
+ result.push(` 失败: ${counters.endpointFailed || 0}`);
113
+ // 数据模型统计
114
+ result.push('\n📊 数据模型:');
115
+ result.push(` 新增: ${counters.schemaCreated || 0}`);
116
+ result.push(` 更新: ${counters.schemaUpdated || 0}`);
117
+ result.push(` 忽略: ${counters.schemaIgnored || 0}`);
118
+ result.push(` 失败: ${counters.schemaFailed || 0}`);
119
+ // 目录统计
120
+ result.push('\n📁 接口目录:');
121
+ result.push(` 新增: ${counters.endpointFolderCreated || 0}`);
122
+ result.push(` 更新: ${counters.endpointFolderUpdated || 0}`);
123
+ result.push(` 忽略: ${counters.endpointFolderIgnored || 0}`);
124
+ result.push(` 失败: ${counters.endpointFolderFailed || 0}`);
125
+ result.push('\n📂 数据模型目录:');
126
+ result.push(` 新增: ${counters.schemaFolderCreated || 0}`);
127
+ result.push(` 更新: ${counters.schemaFolderUpdated || 0}`);
128
+ result.push(` 忽略: ${counters.schemaFolderIgnored || 0}`);
129
+ result.push(` 失败: ${counters.schemaFolderFailed || 0}`);
130
+ // 错误信息
131
+ if (errors && errors.length > 0) {
132
+ result.push('\n❌ 错误信息:');
133
+ result.push(this.formatErrors(errors));
134
+ }
135
+ else {
136
+ result.push('\n✅ 导入成功,无错误');
137
+ }
138
+ return result.join('\n');
139
+ }
140
+ }
141
+ //# sourceMappingURL=apifox-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apifox-client.js","sourceRoot":"","sources":["../src/apifox-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HTTP 服务器实现 - 通过 HTTP/SSE 调用 MCP 服务器
3
+ */
4
+ import type { EnvConfig } from './types.js';
5
+ /**
6
+ * 启动 HTTP 服务器
7
+ * @param port 监听端口
8
+ * @param config 环境配置
9
+ */
10
+ export declare function startHTTPServer(port: number, config: EnvConfig): Promise<void>;
11
+ //# sourceMappingURL=http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAqHpF"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * HTTP 服务器实现 - 通过 HTTP/SSE 调用 MCP 服务器
3
+ */
4
+ import express from 'express';
5
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
6
+ import { createServer as createMCPServer } from './server.js';
7
+ /**
8
+ * 启动 HTTP 服务器
9
+ * @param port 监听端口
10
+ * @param config 环境配置
11
+ */
12
+ export async function startHTTPServer(port, config) {
13
+ const app = express();
14
+ // 解析 JSON 请求体
15
+ app.use(express.json());
16
+ // 创建 MCP 服务器实例
17
+ const mcpServer = createMCPServer(config);
18
+ let transport = null;
19
+ // SSE 端点 - 建立 MCP 连接
20
+ app.get('/sse', async (req, res) => {
21
+ console.log('[HTTP] 新的 SSE 连接建立');
22
+ try {
23
+ // 创建 SSE 传输
24
+ transport = new SSEServerTransport('/messages', res);
25
+ // 连接 MCP 服务器
26
+ await mcpServer.connect(transport);
27
+ console.log('[HTTP] SSE 连接已建立');
28
+ }
29
+ catch (error) {
30
+ console.error('[HTTP] SSE 连接失败:', error);
31
+ res.status(500).send('SSE connection failed');
32
+ }
33
+ });
34
+ // SSE 消息端点 - 接收客户端发送的消息
35
+ app.post('/messages', async (req, res) => {
36
+ console.log('[HTTP] 收到消息:', JSON.stringify(req.body, null, 2));
37
+ if (!transport) {
38
+ res.status(400).json({ error: 'No active SSE connection' });
39
+ return;
40
+ }
41
+ try {
42
+ // 处理消息
43
+ await transport.handlePostMessage(req, res);
44
+ }
45
+ catch (error) {
46
+ console.error('[HTTP] 处理消息失败:', error);
47
+ res.status(500).json({ error: 'Failed to process message' });
48
+ }
49
+ });
50
+ // 健康检查端点
51
+ app.get('/health', (req, res) => {
52
+ res.json({ status: 'ok', service: 'mcp-apifox-import' });
53
+ });
54
+ // API 文档端点
55
+ app.get('/', (req, res) => {
56
+ res.json({
57
+ name: 'MCP Apifox Import Server',
58
+ version: '1.0.0',
59
+ description: '通过 HTTP/SSE 调用的 MCP 服务器,用于导入 OpenAPI 数据到 Apifox',
60
+ endpoints: {
61
+ sse: '/sse - SSE 连接端点(建立持久连接)',
62
+ messages: '/messages - 消息端点(POST 发送 MCP 请求)',
63
+ health: '/health - 健康检查',
64
+ },
65
+ usage: `
66
+ 1. 首先建立 SSE 连接: GET /sse
67
+ 2. 然后发送 MCP 请求: POST /messages
68
+
69
+ 请求格式示例:
70
+ {
71
+ "jsonrpc": "2.0",
72
+ "id": 1,
73
+ "method": "tools/list"
74
+ }
75
+
76
+ 或者调用导入工具:
77
+ {
78
+ "jsonrpc": "2.0",
79
+ "id": 2,
80
+ "method": "tools/call",
81
+ "params": {
82
+ "name": "import-openapi",
83
+ "arguments": {
84
+ "input": "{\\"openapi\\":\\"3.0.1\\"...}",
85
+ "options": {
86
+ "endpointOverwriteBehavior": "CREATE_NEW"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ `,
92
+ });
93
+ });
94
+ // 启动服务器
95
+ app.listen(port, () => {
96
+ console.log(`[HTTP] MCP 服务器已启动`);
97
+ console.log(`[HTTP] 监听地址: http://localhost:${port}`);
98
+ console.log(`[HTTP] SSE 端点: http://localhost:${port}/sse`);
99
+ console.log(`[HTTP] 消息端点: http://localhost:${port}/messages`);
100
+ console.log(`[HTTP] 健康检查: http://localhost:${port}/health`);
101
+ });
102
+ // 优雅关闭
103
+ process.on('SIGINT', async () => {
104
+ console.log('\n[HTTP] 正在关闭服务器...');
105
+ if (transport) {
106
+ await mcpServer.close();
107
+ }
108
+ process.exit(0);
109
+ });
110
+ process.on('SIGTERM', async () => {
111
+ console.log('\n[HTTP] 正在关闭服务器...');
112
+ if (transport) {
113
+ await mcpServer.close();
114
+ }
115
+ process.exit(0);
116
+ });
117
+ }
118
+ //# sourceMappingURL=http-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-server.js","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * MCP 服务器 HTTP 启动入口
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=index-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-http.d.ts","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * MCP 服务器 HTTP 启动入口
3
+ */
4
+ import { startHTTPServer } from './http-server.js';
5
+ /**
6
+ * 从环境变量读取配置
7
+ */
8
+ function loadConfig() {
9
+ const apiBaseUrl = process.env.APIFOX_API_BASE_URL || 'https://api.apifox.com';
10
+ const apiVersion = process.env.APIFOX_API_VERSION || '2024-03-28';
11
+ const accessToken = process.env.APIFOX_ACCESS_TOKEN || '';
12
+ const projectId = process.env.APIFOX_PROJECT_ID || '';
13
+ if (!accessToken) {
14
+ console.error('错误: 未设置 APIFOX_ACCESS_TOKEN 环境变量');
15
+ console.error('请创建 .env 文件并设置 APIFOX_ACCESS_TOKEN');
16
+ console.error('可以参考 .env.example 文件');
17
+ process.exit(1);
18
+ }
19
+ if (!projectId) {
20
+ console.error('错误: 未设置 APIFOX_PROJECT_ID 环境变量');
21
+ console.error('请创建 .env 文件并设置 APIFOX_PROJECT_ID');
22
+ console.error('可以参考 .env.example 文件');
23
+ process.exit(1);
24
+ }
25
+ return {
26
+ APIFOX_API_BASE_URL: apiBaseUrl,
27
+ APIFOX_API_VERSION: apiVersion,
28
+ APIFOX_ACCESS_TOKEN: accessToken,
29
+ APIFOX_PROJECT_ID: projectId,
30
+ };
31
+ }
32
+ // 加载环境配置
33
+ const config = loadConfig();
34
+ // 默认端口(可通过环境变量覆盖)
35
+ const port = parseInt(process.env.MCP_HTTP_PORT || '3000', 10);
36
+ // 启动 HTTP 服务器
37
+ startHTTPServer(port, config);
38
+ //# sourceMappingURL=index-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-http.js","sourceRoot":"","sources":["../src/index-http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,SAAS,UAAU;IACjB,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC;IAC9D,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,YAAY,CAAC;IACjD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC;IAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CACX,kCAAkC,CACnC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,gCAAgC,CACjC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,mBAAmB,EAAE,UAAU;QAC/B,kBAAkB,EAAE,UAAU;QAC9B,mBAAmB,EAAE,WAAW;QAChC,iBAAiB,EAAE,SAAS;KAC7B,CAAC;AACJ,CAAC;AAED,SAAS;AACT,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;AAE5B,kBAAkB;AAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAE/D,cAAc;AACd,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Apifox Import Server 入口文件
4
+ */
5
+ import type { EnvConfig } from './types.js';
6
+ import { startServer } from './server.js';
7
+ /**
8
+ * 从环境变量和命令行参数读取配置
9
+ */
10
+ declare function loadConfig(): EnvConfig;
11
+ export { loadConfig, startServer };
12
+ export type { EnvConfig } from './types.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,iBAAS,UAAU,IAAI,SAAS,CAgD/B;AAiBD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Apifox Import Server 入口文件
4
+ */
5
+ import { startServer } from './server.js';
6
+ /**
7
+ * 从环境变量和命令行参数读取配置
8
+ */
9
+ function loadConfig() {
10
+ const apiBaseUrl = process.env.APIFOX_API_BASE_URL || 'https://api.apifox.com';
11
+ const apiVersion = process.env.APIFOX_API_VERSION || '2024-03-28';
12
+ const accessToken = process.env.APIFOX_ACCESS_TOKEN || '';
13
+ // 从命令行参数或环境变量获取 project-id
14
+ let projectId = process.env.APIFOX_PROJECT_ID || '';
15
+ const args = process.argv.slice(2);
16
+ const projectIdIndex = args.indexOf('--project-id');
17
+ if (projectIdIndex !== -1 && args[projectIdIndex + 1]) {
18
+ projectId = args[projectIdIndex + 1];
19
+ }
20
+ if (!accessToken) {
21
+ console.error('错误: 未设置 APIFOX_ACCESS_TOKEN 环境变量');
22
+ console.error('使用方法:');
23
+ console.error(' npx apifox-import-mcp');
24
+ console.error(' npx apifox-import-mcp --project-id <project-id>');
25
+ console.error('');
26
+ console.error('环境变量:');
27
+ console.error(' APIFOX_ACCESS_TOKEN (必需)');
28
+ console.error(' APIFOX_PROJECT_ID (可选,也可通过 --project-id 参数指定)');
29
+ console.error(' APIFOX_API_BASE_URL (可选,默认: https://api.apifox.com)');
30
+ process.exit(1);
31
+ }
32
+ if (!projectId) {
33
+ console.error('错误: 未设置 APIFOX_PROJECT_ID 环境变量或 --project-id 参数');
34
+ console.error('使用方法:');
35
+ console.error(' npx apifox-import-mcp --project-id <project-id>');
36
+ console.error('');
37
+ console.error('或设置环境变量:');
38
+ console.error(' export APIFOX_PROJECT_ID=<project-id>');
39
+ process.exit(1);
40
+ }
41
+ return {
42
+ APIFOX_API_BASE_URL: apiBaseUrl,
43
+ APIFOX_API_VERSION: apiVersion,
44
+ APIFOX_ACCESS_TOKEN: accessToken,
45
+ APIFOX_PROJECT_ID: projectId,
46
+ };
47
+ }
48
+ /**
49
+ * 主函数
50
+ */
51
+ async function main() {
52
+ const config = loadConfig();
53
+ await startServer(config);
54
+ }
55
+ // 启动服务器
56
+ main().catch((error) => {
57
+ console.error('服务器启动失败:', error);
58
+ process.exit(1);
59
+ });
60
+ // 导出供测试使用
61
+ export { loadConfig, startServer };
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;GAEG;AACH,SAAS,UAAU;IACjB,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC;IAC9D,MAAM,UAAU,GACd,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,YAAY,CAAC;IACjD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC;IAE1D,2BAA2B;IAC3B,IAAI,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,cAAc,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,EAAE,CAAC;QACtD,SAAS,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CACX,kCAAkC,CACnC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACzC,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CACX,iDAAiD,CAClD,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,mBAAmB,EAAE,UAAU;QAC/B,kBAAkB,EAAE,UAAU;QAC9B,mBAAmB,EAAE,WAAW;QAChC,iBAAiB,EAAE,SAAS;KAC7B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,QAAQ;AACR,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,UAAU;AACV,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * MCP 服务器实现
3
+ */
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+ import type { EnvConfig } from './types.js';
6
+ /**
7
+ * 创建 MCP 服务器
8
+ */
9
+ export declare function createServer(config: EnvConfig): Server;
10
+ /**
11
+ * 启动服务器
12
+ */
13
+ export declare function startServer(config: EnvConfig): Promise<void>;
14
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAOnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CA+GtD;AA2GD;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAWlE"}
package/dist/server.js ADDED
@@ -0,0 +1,219 @@
1
+ /**
2
+ * MCP 服务器实现
3
+ */
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
7
+ import { z } from 'zod';
8
+ import { ApifoxClient } from './apifox-client.js';
9
+ /**
10
+ * 创建 MCP 服务器
11
+ */
12
+ export function createServer(config) {
13
+ // 创建 Apifox 客户端实例
14
+ const apifoxClient = new ApifoxClient(config);
15
+ // 创建 MCP 服务器
16
+ const server = new Server({
17
+ name: 'mcp-apifox-import',
18
+ version: '1.0.0',
19
+ }, {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ });
24
+ // 注册工具列表处理程序
25
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
26
+ return {
27
+ tools: [
28
+ {
29
+ name: 'import-openapi',
30
+ description: '将 OpenAPI 3 或 Swagger 2 格式的数据导入到 Apifox 项目。支持字符串(JSON/YAML)或 URL 两种方式。',
31
+ inputSchema: {
32
+ type: 'object',
33
+ properties: {
34
+ input: {
35
+ type: 'string',
36
+ description: 'OpenAPI 数据字符串(JSON 或 YAML 格式)'
37
+ },
38
+ options: {
39
+ type: 'object',
40
+ description: '导入配置选项',
41
+ properties: {
42
+ targetEndpointFolderId: {
43
+ type: 'number',
44
+ description: '目标接口目录 ID(未指定则使用 Root 目录)',
45
+ },
46
+ targetSchemaFolderId: {
47
+ type: 'number',
48
+ description: '目标数据模型目录 ID(未指定则使用 Root 目录)',
49
+ },
50
+ endpointOverwriteBehavior: {
51
+ type: 'string',
52
+ enum: [
53
+ 'OVERWRITE_EXISTING',
54
+ 'AUTO_MERGE',
55
+ 'KEEP_EXISTING',
56
+ 'CREATE_NEW',
57
+ ],
58
+ description: '接口覆盖行为',
59
+ },
60
+ schemaOverwriteBehavior: {
61
+ type: 'string',
62
+ enum: [
63
+ 'OVERWRITE_EXISTING',
64
+ 'AUTO_MERGE',
65
+ 'KEEP_EXISTING',
66
+ 'CREATE_NEW',
67
+ ],
68
+ description: '数据模型覆盖行为',
69
+ },
70
+ updateFolderOfChangedEndpoint: {
71
+ type: 'boolean',
72
+ description: '是否更新接口目录',
73
+ },
74
+ prependBasePath: {
75
+ type: 'boolean',
76
+ description: '是否添加基础路径',
77
+ },
78
+ targetBranchId: {
79
+ type: 'number',
80
+ description: '目标分支 ID',
81
+ },
82
+ moduleId: {
83
+ type: 'number',
84
+ description: '目标模块 ID',
85
+ },
86
+ },
87
+ },
88
+ },
89
+ required: ['input'],
90
+ },
91
+ },
92
+ ],
93
+ };
94
+ });
95
+ // 注册工具调用处理程序
96
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
97
+ const { name, arguments: args } = request.params;
98
+ if (name === 'import-openapi') {
99
+ return await handleImportOpenAPI(apifoxClient, config, args);
100
+ }
101
+ return {
102
+ content: [
103
+ {
104
+ type: 'text',
105
+ text: `未知的工具: ${name}`,
106
+ },
107
+ ],
108
+ isError: true,
109
+ };
110
+ });
111
+ return server;
112
+ }
113
+ /**
114
+ * 处理 import-openapi 工具调用
115
+ */
116
+ async function handleImportOpenAPI(client, config, args) {
117
+ // 参数验证
118
+ const schema = z.object({
119
+ input: z.union([
120
+ z.string().min(1, '输入数据不能为空'),
121
+ z.object({
122
+ url: z.string().url('URL 格式不正确'),
123
+ basicAuth: z
124
+ .object({
125
+ username: z.string(),
126
+ password: z.string(),
127
+ })
128
+ .optional(),
129
+ }),
130
+ ]),
131
+ options: z
132
+ .object({
133
+ targetEndpointFolderId: z.number().optional(),
134
+ targetSchemaFolderId: z.number().optional(),
135
+ endpointOverwriteBehavior: z
136
+ .enum([
137
+ 'OVERWRITE_EXISTING',
138
+ 'AUTO_MERGE',
139
+ 'KEEP_EXISTING',
140
+ 'CREATE_NEW',
141
+ ])
142
+ .optional(),
143
+ schemaOverwriteBehavior: z
144
+ .enum([
145
+ 'OVERWRITE_EXISTING',
146
+ 'AUTO_MERGE',
147
+ 'KEEP_EXISTING',
148
+ 'CREATE_NEW',
149
+ ])
150
+ .optional(),
151
+ updateFolderOfChangedEndpoint: z.boolean().optional(),
152
+ prependBasePath: z.boolean().optional(),
153
+ targetBranchId: z.number().optional(),
154
+ moduleId: z.number().optional(),
155
+ })
156
+ .optional(),
157
+ });
158
+ const validationResult = schema.safeParse(args);
159
+ if (!validationResult.success) {
160
+ const errors = validationResult.error.errors
161
+ .map((e) => `${e.path.join('.')}: ${e.message}`)
162
+ .join('\n');
163
+ return {
164
+ content: [
165
+ {
166
+ type: 'text',
167
+ text: `参数验证失败:\n${errors}`,
168
+ },
169
+ ],
170
+ isError: true,
171
+ };
172
+ }
173
+ const { input, options } = validationResult.data;
174
+ const projectId = config.APIFOX_PROJECT_ID;
175
+ try {
176
+ // 调用 Apifox API
177
+ const response = await client.importOpenAPI(projectId, {
178
+ input,
179
+ options,
180
+ });
181
+ // 格式化结果
182
+ const formattedResult = ApifoxClient.formatImportResult(response);
183
+ return {
184
+ content: [
185
+ {
186
+ type: 'text',
187
+ text: formattedResult,
188
+ },
189
+ ],
190
+ isError: false,
191
+ };
192
+ }
193
+ catch (error) {
194
+ const errorMessage = error instanceof Error ? error.message : '未知错误';
195
+ return {
196
+ content: [
197
+ {
198
+ type: 'text',
199
+ text: `导入失败: ${errorMessage}`,
200
+ },
201
+ ],
202
+ isError: true,
203
+ };
204
+ }
205
+ }
206
+ /**
207
+ * 启动服务器
208
+ */
209
+ export async function startServer(config) {
210
+ const server = createServer(config);
211
+ const transport = new StdioServerTransport();
212
+ await server.connect(transport);
213
+ // 优雅关闭
214
+ process.on('SIGINT', async () => {
215
+ await server.close();
216
+ process.exit(0);
217
+ });
218
+ }
219
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Apifox Import API 类型定义
3
+ */
4
+ export type OverwriteBehavior = 'OVERWRITE_EXISTING' | 'AUTO_MERGE' | 'KEEP_EXISTING' | 'CREATE_NEW';
5
+ export interface BasicAuth {
6
+ username: string;
7
+ password: string;
8
+ }
9
+ export interface UrlInput {
10
+ url: string;
11
+ basicAuth?: BasicAuth;
12
+ }
13
+ export type OpenAPIInput = string | UrlInput;
14
+ export interface ImportOptions {
15
+ targetEndpointFolderId?: number;
16
+ targetSchemaFolderId?: number;
17
+ endpointOverwriteBehavior?: OverwriteBehavior;
18
+ schemaOverwriteBehavior?: OverwriteBehavior;
19
+ updateFolderOfChangedEndpoint?: boolean;
20
+ prependBasePath?: boolean;
21
+ targetBranchId?: number;
22
+ moduleId?: number;
23
+ }
24
+ export interface ImportRequest {
25
+ input: OpenAPIInput;
26
+ options?: ImportOptions;
27
+ }
28
+ export interface Counters {
29
+ endpointCreated: number;
30
+ endpointUpdated: number;
31
+ endpointFailed: number;
32
+ endpointIgnored: number;
33
+ schemaCreated: number;
34
+ schemaUpdated: number;
35
+ schemaFailed: number;
36
+ schemaIgnored: number;
37
+ endpointFolderCreated: number;
38
+ endpointFolderUpdated: number;
39
+ endpointFolderFailed: number;
40
+ endpointFolderIgnored: number;
41
+ schemaFolderCreated: number;
42
+ schemaFolderUpdated: number;
43
+ schemaFolderFailed: number;
44
+ schemaFolderIgnored: number;
45
+ }
46
+ export interface ImportError {
47
+ message: string;
48
+ code: string;
49
+ }
50
+ export interface ImportResponseData {
51
+ counters: Counters;
52
+ errors: ImportError[];
53
+ }
54
+ export interface ImportResponse {
55
+ data: ImportResponseData;
56
+ }
57
+ export interface EnvConfig {
58
+ APIFOX_API_BASE_URL: string;
59
+ APIFOX_API_VERSION: string;
60
+ APIFOX_ACCESS_TOKEN: string;
61
+ APIFOX_PROJECT_ID: string;
62
+ }
63
+ export interface ImportOpenAPIToolArgs {
64
+ input: OpenAPIInput;
65
+ options?: ImportOptions;
66
+ }
67
+ export interface FormattedCounters {
68
+ label: string;
69
+ created: number;
70
+ updated: number;
71
+ failed: number;
72
+ ignored: number;
73
+ }
74
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,iBAAiB,GACzB,oBAAoB,GACpB,YAAY,GACZ,eAAe,GACf,YAAY,CAAC;AAGjB,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAGD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAG7C,MAAM,WAAW,aAAa;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yBAAyB,CAAC,EAAE,iBAAiB,CAAC;IAC9C,uBAAuB,CAAC,EAAE,iBAAiB,CAAC;IAC5C,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAGD,MAAM,WAAW,QAAQ;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAGD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAGD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAGD,MAAM,WAAW,SAAS;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAGD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAGD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Apifox Import API 类型定义
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "apifox-import-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for importing OpenAPI data to Apifox",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "apifox-import-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "start": "node dist/index.js",
19
+ "dev": "tsc && node dist/index.js",
20
+ "watch": "tsc --watch",
21
+ "test:prepare": "npm run build",
22
+ "publish:npm": "npm run build && npm publish"
23
+ },
24
+ "keywords": [
25
+ "mcp",
26
+ "apifox",
27
+ "openapi",
28
+ "swagger",
29
+ "import"
30
+ ],
31
+ "author": "",
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.0.4",
35
+ "@types/express": "^5.0.6",
36
+ "express": "^5.2.1",
37
+ "zod": "^3.23.8"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.10.2",
41
+ "typescript": "^5.7.2"
42
+ }
43
+ }