@hflin/cclin 0.1.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 +124 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +165 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/client.d.ts +32 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +280 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/runtime/compaction.d.ts +49 -0
- package/dist/runtime/compaction.d.ts.map +1 -0
- package/dist/runtime/compaction.js +118 -0
- package/dist/runtime/compaction.js.map +1 -0
- package/dist/runtime/compaction.test.d.ts +7 -0
- package/dist/runtime/compaction.test.d.ts.map +1 -0
- package/dist/runtime/compaction.test.js +70 -0
- package/dist/runtime/compaction.test.js.map +1 -0
- package/dist/runtime/history.d.ts +34 -0
- package/dist/runtime/history.d.ts.map +1 -0
- package/dist/runtime/history.js +63 -0
- package/dist/runtime/history.js.map +1 -0
- package/dist/runtime/hooks.d.ts +54 -0
- package/dist/runtime/hooks.d.ts.map +1 -0
- package/dist/runtime/hooks.js +113 -0
- package/dist/runtime/hooks.js.map +1 -0
- package/dist/runtime/hooks.test.d.ts +7 -0
- package/dist/runtime/hooks.test.d.ts.map +1 -0
- package/dist/runtime/hooks.test.js +73 -0
- package/dist/runtime/hooks.test.js.map +1 -0
- package/dist/runtime/model-profile.d.ts +42 -0
- package/dist/runtime/model-profile.d.ts.map +1 -0
- package/dist/runtime/model-profile.js +84 -0
- package/dist/runtime/model-profile.js.map +1 -0
- package/dist/runtime/prompt.d.ts +38 -0
- package/dist/runtime/prompt.d.ts.map +1 -0
- package/dist/runtime/prompt.js +152 -0
- package/dist/runtime/prompt.js.map +1 -0
- package/dist/runtime/prompt.md +64 -0
- package/dist/runtime/prompt.test.d.ts +7 -0
- package/dist/runtime/prompt.test.d.ts.map +1 -0
- package/dist/runtime/prompt.test.js +38 -0
- package/dist/runtime/prompt.test.js.map +1 -0
- package/dist/runtime/react-loop.d.ts +82 -0
- package/dist/runtime/react-loop.d.ts.map +1 -0
- package/dist/runtime/react-loop.js +311 -0
- package/dist/runtime/react-loop.js.map +1 -0
- package/dist/runtime/react-loop.test.d.ts +7 -0
- package/dist/runtime/react-loop.test.d.ts.map +1 -0
- package/dist/runtime/react-loop.test.js +78 -0
- package/dist/runtime/react-loop.test.js.map +1 -0
- package/dist/runtime/session.d.ts +109 -0
- package/dist/runtime/session.d.ts.map +1 -0
- package/dist/runtime/session.js +252 -0
- package/dist/runtime/session.js.map +1 -0
- package/dist/runtime/skills.d.ts +36 -0
- package/dist/runtime/skills.d.ts.map +1 -0
- package/dist/runtime/skills.js +187 -0
- package/dist/runtime/skills.js.map +1 -0
- package/dist/runtime/skills.test.d.ts +7 -0
- package/dist/runtime/skills.test.d.ts.map +1 -0
- package/dist/runtime/skills.test.js +92 -0
- package/dist/runtime/skills.test.js.map +1 -0
- package/dist/tools/approval.d.ts +61 -0
- package/dist/tools/approval.d.ts.map +1 -0
- package/dist/tools/approval.js +119 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/approval.test.d.ts +9 -0
- package/dist/tools/approval.test.d.ts.map +1 -0
- package/dist/tools/approval.test.js +112 -0
- package/dist/tools/approval.test.js.map +1 -0
- package/dist/tools/bash.d.ts +6 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +58 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/edit-file.d.ts +6 -0
- package/dist/tools/edit-file.d.ts.map +1 -0
- package/dist/tools/edit-file.js +58 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/get-memory.d.ts +9 -0
- package/dist/tools/get-memory.d.ts.map +1 -0
- package/dist/tools/get-memory.js +56 -0
- package/dist/tools/get-memory.js.map +1 -0
- package/dist/tools/list-directory.d.ts +6 -0
- package/dist/tools/list-directory.d.ts.map +1 -0
- package/dist/tools/list-directory.js +68 -0
- package/dist/tools/list-directory.js.map +1 -0
- package/dist/tools/mcp-client.d.ts +74 -0
- package/dist/tools/mcp-client.d.ts.map +1 -0
- package/dist/tools/mcp-client.js +129 -0
- package/dist/tools/mcp-client.js.map +1 -0
- package/dist/tools/mcp-config.d.ts +31 -0
- package/dist/tools/mcp-config.d.ts.map +1 -0
- package/dist/tools/mcp-config.js +55 -0
- package/dist/tools/mcp-config.js.map +1 -0
- package/dist/tools/mcp-registry.d.ts +39 -0
- package/dist/tools/mcp-registry.d.ts.map +1 -0
- package/dist/tools/mcp-registry.js +88 -0
- package/dist/tools/mcp-registry.js.map +1 -0
- package/dist/tools/orchestrator.d.ts +52 -0
- package/dist/tools/orchestrator.d.ts.map +1 -0
- package/dist/tools/orchestrator.js +190 -0
- package/dist/tools/orchestrator.js.map +1 -0
- package/dist/tools/orchestrator.test.d.ts +8 -0
- package/dist/tools/orchestrator.test.d.ts.map +1 -0
- package/dist/tools/orchestrator.test.js +122 -0
- package/dist/tools/orchestrator.test.js.map +1 -0
- package/dist/tools/read-file.d.ts +6 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +50 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +55 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +75 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/registry.test.d.ts +8 -0
- package/dist/tools/registry.test.d.ts.map +1 -0
- package/dist/tools/registry.test.js +100 -0
- package/dist/tools/registry.test.js.map +1 -0
- package/dist/tools/router.d.ts +62 -0
- package/dist/tools/router.d.ts.map +1 -0
- package/dist/tools/router.js +119 -0
- package/dist/tools/router.js.map +1 -0
- package/dist/tools/router.test.d.ts +7 -0
- package/dist/tools/router.test.d.ts.map +1 -0
- package/dist/tools/router.test.js +102 -0
- package/dist/tools/router.test.js.map +1 -0
- package/dist/tools/safety.d.ts +16 -0
- package/dist/tools/safety.d.ts.map +1 -0
- package/dist/tools/safety.js +81 -0
- package/dist/tools/safety.js.map +1 -0
- package/dist/tools/safety.test.d.ts +7 -0
- package/dist/tools/safety.test.d.ts.map +1 -0
- package/dist/tools/safety.test.js +104 -0
- package/dist/tools/safety.test.js.map +1 -0
- package/dist/tools/search-files.d.ts +9 -0
- package/dist/tools/search-files.d.ts.map +1 -0
- package/dist/tools/search-files.js +114 -0
- package/dist/tools/search-files.js.map +1 -0
- package/dist/tools/update-plan.d.ts +9 -0
- package/dist/tools/update-plan.d.ts.map +1 -0
- package/dist/tools/update-plan.js +99 -0
- package/dist/tools/update-plan.js.map +1 -0
- package/dist/tools/write-file.d.ts +6 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +41 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/tui/app.d.ts +31 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +121 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/chatwidget/markdown_renderer.d.ts +20 -0
- package/dist/tui/chatwidget/markdown_renderer.d.ts.map +1 -0
- package/dist/tui/chatwidget/markdown_renderer.js +188 -0
- package/dist/tui/chatwidget/markdown_renderer.js.map +1 -0
- package/dist/tui/cjk_text.d.ts +25 -0
- package/dist/tui/cjk_text.d.ts.map +1 -0
- package/dist/tui/cjk_text.js +84 -0
- package/dist/tui/cjk_text.js.map +1 -0
- package/dist/tui/cjk_text.test.d.ts +2 -0
- package/dist/tui/cjk_text.test.d.ts.map +1 -0
- package/dist/tui/cjk_text.test.js +62 -0
- package/dist/tui/cjk_text.test.js.map +1 -0
- package/dist/tui/composer_input.d.ts +31 -0
- package/dist/tui/composer_input.d.ts.map +1 -0
- package/dist/tui/composer_input.js +184 -0
- package/dist/tui/composer_input.js.map +1 -0
- package/dist/tui/composer_input.test.d.ts +2 -0
- package/dist/tui/composer_input.test.d.ts.map +1 -0
- package/dist/tui/composer_input.test.js +87 -0
- package/dist/tui/composer_input.test.js.map +1 -0
- package/dist/tui/input.d.ts +21 -0
- package/dist/tui/input.d.ts.map +1 -0
- package/dist/tui/input.js +166 -0
- package/dist/tui/input.js.map +1 -0
- package/dist/tui/output.d.ts +17 -0
- package/dist/tui/output.d.ts.map +1 -0
- package/dist/tui/output.js +104 -0
- package/dist/tui/output.js.map +1 -0
- package/dist/tui/state/chat_timeline.d.ts +50 -0
- package/dist/tui/state/chat_timeline.d.ts.map +1 -0
- package/dist/tui/state/chat_timeline.js +129 -0
- package/dist/tui/state/chat_timeline.js.map +1 -0
- package/dist/tui/types.d.ts +45 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/tui/types.js +14 -0
- package/dist/tui/types.js.map +1 -0
- package/dist/types.d.ts +435 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/tokenizer.d.ts +21 -0
- package/dist/utils/tokenizer.d.ts.map +1 -0
- package/dist/utils/tokenizer.js +71 -0
- package/dist/utils/tokenizer.js.map +1 -0
- package/dist/utils/tokenizer.test.d.ts +7 -0
- package/dist/utils/tokenizer.test.d.ts.map +1 -0
- package/dist/utils/tokenizer.test.js +51 -0
- package/dist/utils/tokenizer.test.js.map +1 -0
- package/package.json +41 -0
- package/src/runtime/prompt.md +64 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 客户端 — 管理 MCP Server 的连接生命周期。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:通过 @modelcontextprotocol/sdk 与外部 MCP Server 通信。
|
|
5
|
+
*
|
|
6
|
+
* 职责:
|
|
7
|
+
* 1. 通过 stdio 传输建立与 MCP Server 的连接
|
|
8
|
+
* 2. 发现 Server 提供的工具列表
|
|
9
|
+
* 3. 代理调用远端工具
|
|
10
|
+
* 4. 管理连接生命周期(连接池 + 清理)
|
|
11
|
+
*
|
|
12
|
+
* 设计简化:
|
|
13
|
+
* - 仅支持 stdio 传输(最常见场景)
|
|
14
|
+
* - 不引入 HTTP/OAuth 复杂度
|
|
15
|
+
* - 连接池避免重复连接
|
|
16
|
+
*/
|
|
17
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
18
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
19
|
+
import type { MCPServerConfig } from '../types.js';
|
|
20
|
+
/** 单个 MCP Server 的连接信息。 */
|
|
21
|
+
type McpConnection = {
|
|
22
|
+
/** Server 名称。 */
|
|
23
|
+
name: string;
|
|
24
|
+
/** MCP SDK Client 实例。 */
|
|
25
|
+
client: Client;
|
|
26
|
+
/** stdio 传输层实例。 */
|
|
27
|
+
transport: StdioClientTransport;
|
|
28
|
+
};
|
|
29
|
+
/** MCP Server 发现到的原始工具信息。 */
|
|
30
|
+
export type McpDiscoveredTool = {
|
|
31
|
+
/** 工具原始名称(Server 端的名称)。 */
|
|
32
|
+
name: string;
|
|
33
|
+
/** 工具描述。 */
|
|
34
|
+
description: string;
|
|
35
|
+
/** 输入参数 JSON Schema。 */
|
|
36
|
+
inputSchema: Record<string, unknown>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* MCP 客户端连接池。
|
|
40
|
+
*
|
|
41
|
+
* 管理多个 MCP Server 的 stdio 连接:
|
|
42
|
+
* - 懒连接(首次使用时建立)
|
|
43
|
+
* - 连接复用(同一 Server 不会重复连接)
|
|
44
|
+
* - 统一清理
|
|
45
|
+
*/
|
|
46
|
+
export declare class McpClientPool {
|
|
47
|
+
private connections;
|
|
48
|
+
/**
|
|
49
|
+
* 连接到指定 MCP Server。
|
|
50
|
+
*
|
|
51
|
+
* 如果已经连接过,直接返回已有连接。
|
|
52
|
+
*/
|
|
53
|
+
connect(name: string, config: MCPServerConfig): Promise<McpConnection>;
|
|
54
|
+
/**
|
|
55
|
+
* 发现指定 Server 提供的工具列表。
|
|
56
|
+
*
|
|
57
|
+
* 通过 MCP 协议的 listTools() 方法获取。
|
|
58
|
+
*/
|
|
59
|
+
discoverTools(name: string, config: MCPServerConfig): Promise<McpDiscoveredTool[]>;
|
|
60
|
+
/**
|
|
61
|
+
* 通过 MCP 协议调用远端工具。
|
|
62
|
+
*
|
|
63
|
+
* @param serverName — 目标 Server 名称
|
|
64
|
+
* @param toolName — 工具原始名称(Server 端的名称)
|
|
65
|
+
* @param args — 工具参数
|
|
66
|
+
*/
|
|
67
|
+
callTool(serverName: string, toolName: string, args: Record<string, unknown>): Promise<string>;
|
|
68
|
+
/** 关闭所有 MCP 连接。 */
|
|
69
|
+
closeAll(): Promise<void>;
|
|
70
|
+
/** 获取连接数量。 */
|
|
71
|
+
get size(): number;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=mcp-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIlD,2BAA2B;AAC3B,KAAK,aAAa,GAAG;IACjB,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,mBAAmB;IACnB,SAAS,EAAE,oBAAoB,CAAA;CAClC,CAAA;AAED,6BAA6B;AAC7B,MAAM,MAAM,iBAAiB,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC,CAAA;AAuBD;;;;;;;GAOG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,WAAW,CAAwC;IAE3D;;;;OAIG;IACG,OAAO,CACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC,aAAa,CAAC;IA+BzB;;;;OAIG;IACG,aAAa,CACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACxB,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAW/B;;;;;;OAMG;IACG,QAAQ,CACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;IAwBlB,mBAAmB;IACb,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B,cAAc;IACd,IAAI,IAAI,IAAI,MAAM,CAEjB;CACJ"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 客户端 — 管理 MCP Server 的连接生命周期。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:通过 @modelcontextprotocol/sdk 与外部 MCP Server 通信。
|
|
5
|
+
*
|
|
6
|
+
* 职责:
|
|
7
|
+
* 1. 通过 stdio 传输建立与 MCP Server 的连接
|
|
8
|
+
* 2. 发现 Server 提供的工具列表
|
|
9
|
+
* 3. 代理调用远端工具
|
|
10
|
+
* 4. 管理连接生命周期(连接池 + 清理)
|
|
11
|
+
*
|
|
12
|
+
* 设计简化:
|
|
13
|
+
* - 仅支持 stdio 传输(最常见场景)
|
|
14
|
+
* - 不引入 HTTP/OAuth 复杂度
|
|
15
|
+
* - 连接池避免重复连接
|
|
16
|
+
*/
|
|
17
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
18
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
19
|
+
// ─── 辅助函数 ──────────────────────────────────────────────────────────────
|
|
20
|
+
/** 合并 process.env 与自定义 env 配置。 */
|
|
21
|
+
function mergeProcessEnv(env) {
|
|
22
|
+
if (!env)
|
|
23
|
+
return undefined;
|
|
24
|
+
const merged = {
|
|
25
|
+
...process.env,
|
|
26
|
+
...env,
|
|
27
|
+
};
|
|
28
|
+
// 过滤掉 undefined 值
|
|
29
|
+
const entries = Object.entries(merged).filter((entry) => typeof entry[1] === 'string');
|
|
30
|
+
return Object.fromEntries(entries);
|
|
31
|
+
}
|
|
32
|
+
// ─── McpClientPool 类 ─────────────────────────────────────────────────────
|
|
33
|
+
/**
|
|
34
|
+
* MCP 客户端连接池。
|
|
35
|
+
*
|
|
36
|
+
* 管理多个 MCP Server 的 stdio 连接:
|
|
37
|
+
* - 懒连接(首次使用时建立)
|
|
38
|
+
* - 连接复用(同一 Server 不会重复连接)
|
|
39
|
+
* - 统一清理
|
|
40
|
+
*/
|
|
41
|
+
export class McpClientPool {
|
|
42
|
+
connections = new Map();
|
|
43
|
+
/**
|
|
44
|
+
* 连接到指定 MCP Server。
|
|
45
|
+
*
|
|
46
|
+
* 如果已经连接过,直接返回已有连接。
|
|
47
|
+
*/
|
|
48
|
+
async connect(name, config) {
|
|
49
|
+
// 连接复用
|
|
50
|
+
const existing = this.connections.get(name);
|
|
51
|
+
if (existing)
|
|
52
|
+
return existing;
|
|
53
|
+
// 创建 MCP Client
|
|
54
|
+
const client = new Client({ name: 'cclin-agent', version: '0.1.0' }, { capabilities: {} });
|
|
55
|
+
// 创建 stdio 传输
|
|
56
|
+
const transport = new StdioClientTransport({
|
|
57
|
+
command: config.command,
|
|
58
|
+
args: config.args,
|
|
59
|
+
env: mergeProcessEnv(config.env),
|
|
60
|
+
stderr: 'ignore',
|
|
61
|
+
});
|
|
62
|
+
// 建立连接
|
|
63
|
+
await client.connect(transport);
|
|
64
|
+
const connection = {
|
|
65
|
+
name,
|
|
66
|
+
client,
|
|
67
|
+
transport,
|
|
68
|
+
};
|
|
69
|
+
this.connections.set(name, connection);
|
|
70
|
+
return connection;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 发现指定 Server 提供的工具列表。
|
|
74
|
+
*
|
|
75
|
+
* 通过 MCP 协议的 listTools() 方法获取。
|
|
76
|
+
*/
|
|
77
|
+
async discoverTools(name, config) {
|
|
78
|
+
const conn = await this.connect(name, config);
|
|
79
|
+
const result = await conn.client.listTools();
|
|
80
|
+
return (result.tools || []).map((t) => ({
|
|
81
|
+
name: t.name,
|
|
82
|
+
description: t.description || `Tool from ${name}: ${t.name}`,
|
|
83
|
+
inputSchema: t.inputSchema ?? {},
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 通过 MCP 协议调用远端工具。
|
|
88
|
+
*
|
|
89
|
+
* @param serverName — 目标 Server 名称
|
|
90
|
+
* @param toolName — 工具原始名称(Server 端的名称)
|
|
91
|
+
* @param args — 工具参数
|
|
92
|
+
*/
|
|
93
|
+
async callTool(serverName, toolName, args) {
|
|
94
|
+
const conn = this.connections.get(serverName);
|
|
95
|
+
if (!conn) {
|
|
96
|
+
throw new Error(`MCP server "${serverName}" not connected`);
|
|
97
|
+
}
|
|
98
|
+
const result = await conn.client.callTool({
|
|
99
|
+
name: toolName,
|
|
100
|
+
arguments: args,
|
|
101
|
+
});
|
|
102
|
+
// 提取文本内容
|
|
103
|
+
const texts = (result.content || [])
|
|
104
|
+
.filter((item) => item.type === 'text' && item.text)
|
|
105
|
+
.map((item) => item.text);
|
|
106
|
+
if (result.isError) {
|
|
107
|
+
return `Error: ${texts.join('\n') || 'Unknown MCP tool error'}`;
|
|
108
|
+
}
|
|
109
|
+
return texts.join('\n') || '(empty result)';
|
|
110
|
+
}
|
|
111
|
+
/** 关闭所有 MCP 连接。 */
|
|
112
|
+
async closeAll() {
|
|
113
|
+
const tasks = Array.from(this.connections.values()).map(async (conn) => {
|
|
114
|
+
try {
|
|
115
|
+
await conn.client.close();
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// 忽略关闭错误
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
await Promise.all(tasks);
|
|
122
|
+
this.connections.clear();
|
|
123
|
+
}
|
|
124
|
+
/** 获取连接数量。 */
|
|
125
|
+
get size() {
|
|
126
|
+
return this.connections.size;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=mcp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../src/tools/mcp-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 配置加载器 — 读取 mcp_config.json。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:按优先级搜索 MCP 配置文件。
|
|
5
|
+
*
|
|
6
|
+
* 搜索路径(优先级从高到低):
|
|
7
|
+
* 1. 项目目录 ./mcp_config.json
|
|
8
|
+
* 2. 用户目录 ~/.cclin/mcp_config.json
|
|
9
|
+
*
|
|
10
|
+
* 配置格式:
|
|
11
|
+
* ```json
|
|
12
|
+
* {
|
|
13
|
+
* "mcpServers": {
|
|
14
|
+
* "serverName": {
|
|
15
|
+
* "command": "node",
|
|
16
|
+
* "args": ["path/to/server.js"],
|
|
17
|
+
* "env": { "KEY": "value" }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { MCPServerConfig } from '../types.js';
|
|
24
|
+
/**
|
|
25
|
+
* 加载 MCP 配置。
|
|
26
|
+
*
|
|
27
|
+
* @param cwd — 项目目录(默认 process.cwd())
|
|
28
|
+
* @returns MCP Server 配置表(可能为空)
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadMcpConfig(cwd?: string): Promise<Record<string, MCPServerConfig>>;
|
|
31
|
+
//# sourceMappingURL=mcp-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-config.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,aAAa,CAAA;AAEjE;;;;;GAKG;AACH,wBAAsB,aAAa,CAC/B,GAAG,SAAgB,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA4B1C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 配置加载器 — 读取 mcp_config.json。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:按优先级搜索 MCP 配置文件。
|
|
5
|
+
*
|
|
6
|
+
* 搜索路径(优先级从高到低):
|
|
7
|
+
* 1. 项目目录 ./mcp_config.json
|
|
8
|
+
* 2. 用户目录 ~/.cclin/mcp_config.json
|
|
9
|
+
*
|
|
10
|
+
* 配置格式:
|
|
11
|
+
* ```json
|
|
12
|
+
* {
|
|
13
|
+
* "mcpServers": {
|
|
14
|
+
* "serverName": {
|
|
15
|
+
* "command": "node",
|
|
16
|
+
* "args": ["path/to/server.js"],
|
|
17
|
+
* "env": { "KEY": "value" }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { readFile } from 'node:fs/promises';
|
|
24
|
+
import { join } from 'node:path';
|
|
25
|
+
import { homedir } from 'node:os';
|
|
26
|
+
/**
|
|
27
|
+
* 加载 MCP 配置。
|
|
28
|
+
*
|
|
29
|
+
* @param cwd — 项目目录(默认 process.cwd())
|
|
30
|
+
* @returns MCP Server 配置表(可能为空)
|
|
31
|
+
*/
|
|
32
|
+
export async function loadMcpConfig(cwd = process.cwd()) {
|
|
33
|
+
// 搜索路径优先级
|
|
34
|
+
const candidates = [
|
|
35
|
+
join(cwd, 'mcp_config.json'),
|
|
36
|
+
join(homedir(), '.cclin', 'mcp_config.json'),
|
|
37
|
+
];
|
|
38
|
+
for (const configPath of candidates) {
|
|
39
|
+
try {
|
|
40
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
if (parsed.mcpServers &&
|
|
43
|
+
typeof parsed.mcpServers === 'object') {
|
|
44
|
+
console.log(`[MCP] Config loaded from: ${configPath}`);
|
|
45
|
+
return parsed.mcpServers;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// 文件不存在或解析失败,尝试下一个
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 未找到配置,返回空对象(不是错误)
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=mcp-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-config.js","sourceRoot":"","sources":["../../src/tools/mcp-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAGjC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,UAAU;IACV,MAAM,UAAU,GAAG;QACf,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,iBAAiB,CAAC;KAC/C,CAAA;IAED,KAAK,MAAM,UAAU,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;YAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAA;YAE/C,IACI,MAAM,CAAC,UAAU;gBACjB,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,EACvC,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,6BAA6B,UAAU,EAAE,CAC5C,CAAA;gBACD,OAAO,MAAM,CAAC,UAAU,CAAA;YAC5B,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,mBAAmB;QACvB,CAAC;IACL,CAAC;IAED,oBAAoB;IACpB,OAAO,EAAE,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 工具注册表 — 将 MCP Server 的工具适配为 ToolDefinition。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:连接 MCP Server,发现工具,生成可执行的 ToolDefinition。
|
|
5
|
+
*
|
|
6
|
+
* 职责:
|
|
7
|
+
* 1. 使用 McpClientPool 连接 MCP Server
|
|
8
|
+
* 2. 将发现的工具转换为 cclin 的 ToolDefinition 格式
|
|
9
|
+
* 3. 工具名添加 serverName_ 前缀避免冲突
|
|
10
|
+
* 4. 提供标准查询接口(get/getAll/has/size)
|
|
11
|
+
*/
|
|
12
|
+
import type { MCPServerConfig, McpToolDefinition } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* MCP 工具注册表。
|
|
15
|
+
*
|
|
16
|
+
* 将 MCP Server 的远端工具适配为本地 ToolDefinition,
|
|
17
|
+
* 使其可以无缝接入 ToolRouter 和 ToolOrchestrator。
|
|
18
|
+
*/
|
|
19
|
+
export declare class McpToolRegistry {
|
|
20
|
+
private pool;
|
|
21
|
+
private tools;
|
|
22
|
+
/**
|
|
23
|
+
* 连接并加载所有配置的 MCP Server。
|
|
24
|
+
*
|
|
25
|
+
* @returns 成功加载的工具总数
|
|
26
|
+
*/
|
|
27
|
+
loadServers(servers: Record<string, MCPServerConfig>): Promise<number>;
|
|
28
|
+
/** 获取指定工具。 */
|
|
29
|
+
get(name: string): McpToolDefinition | undefined;
|
|
30
|
+
/** 获取所有 MCP 工具。 */
|
|
31
|
+
getAll(): McpToolDefinition[];
|
|
32
|
+
/** 检查工具是否存在。 */
|
|
33
|
+
has(name: string): boolean;
|
|
34
|
+
/** 已注册 MCP 工具数量。 */
|
|
35
|
+
get size(): number;
|
|
36
|
+
/** 清理所有 MCP 连接。 */
|
|
37
|
+
dispose(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=mcp-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-registry.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EACR,eAAe,EACf,iBAAiB,EAEpB,MAAM,aAAa,CAAA;AAKpB;;;;;GAKG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,KAAK,CAA4C;IAEzD;;;;OAIG;IACG,WAAW,CACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACzC,OAAO,CAAC,MAAM,CAAC;IA4DlB,cAAc;IACd,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIhD,mBAAmB;IACnB,MAAM,IAAI,iBAAiB,EAAE;IAI7B,gBAAgB;IAChB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,oBAAoB;IACpB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,mBAAmB;IACb,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAIjC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file MCP 工具注册表 — 将 MCP Server 的工具适配为 ToolDefinition。
|
|
3
|
+
*
|
|
4
|
+
* Phase 9:连接 MCP Server,发现工具,生成可执行的 ToolDefinition。
|
|
5
|
+
*
|
|
6
|
+
* 职责:
|
|
7
|
+
* 1. 使用 McpClientPool 连接 MCP Server
|
|
8
|
+
* 2. 将发现的工具转换为 cclin 的 ToolDefinition 格式
|
|
9
|
+
* 3. 工具名添加 serverName_ 前缀避免冲突
|
|
10
|
+
* 4. 提供标准查询接口(get/getAll/has/size)
|
|
11
|
+
*/
|
|
12
|
+
import { McpClientPool } from './mcp-client.js';
|
|
13
|
+
// ─── McpToolRegistry 类 ──────────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* MCP 工具注册表。
|
|
16
|
+
*
|
|
17
|
+
* 将 MCP Server 的远端工具适配为本地 ToolDefinition,
|
|
18
|
+
* 使其可以无缝接入 ToolRouter 和 ToolOrchestrator。
|
|
19
|
+
*/
|
|
20
|
+
export class McpToolRegistry {
|
|
21
|
+
pool = new McpClientPool();
|
|
22
|
+
tools = new Map();
|
|
23
|
+
/**
|
|
24
|
+
* 连接并加载所有配置的 MCP Server。
|
|
25
|
+
*
|
|
26
|
+
* @returns 成功加载的工具总数
|
|
27
|
+
*/
|
|
28
|
+
async loadServers(servers) {
|
|
29
|
+
const entries = Object.entries(servers);
|
|
30
|
+
if (entries.length === 0)
|
|
31
|
+
return 0;
|
|
32
|
+
for (const [serverName, config] of entries) {
|
|
33
|
+
try {
|
|
34
|
+
const discovered = await this.pool.discoverTools(serverName, config);
|
|
35
|
+
for (const rawTool of discovered) {
|
|
36
|
+
// 工具名:serverName_originalName
|
|
37
|
+
const qualifiedName = `${serverName}_${rawTool.name}`;
|
|
38
|
+
const tool = {
|
|
39
|
+
name: qualifiedName,
|
|
40
|
+
description: rawTool.description ||
|
|
41
|
+
`Tool from ${serverName}: ${rawTool.name}`,
|
|
42
|
+
inputSchema: rawTool.inputSchema ?? {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {},
|
|
45
|
+
},
|
|
46
|
+
isMutating: true, // 保守策略:MCP 工具默认需要审批
|
|
47
|
+
source: 'mcp',
|
|
48
|
+
serverName,
|
|
49
|
+
originalName: rawTool.name,
|
|
50
|
+
execute: async (input) => {
|
|
51
|
+
const result = await this.pool.callTool(serverName, rawTool.name, input);
|
|
52
|
+
const isError = result.startsWith('Error:');
|
|
53
|
+
return { output: result, isError };
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
this.tools.set(qualifiedName, tool);
|
|
57
|
+
}
|
|
58
|
+
console.log(`[MCP] Loaded ${discovered.length} tools from "${serverName}"`);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.error(`[MCP] Failed to connect to "${serverName}":`, err.message);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return this.tools.size;
|
|
65
|
+
}
|
|
66
|
+
/** 获取指定工具。 */
|
|
67
|
+
get(name) {
|
|
68
|
+
return this.tools.get(name);
|
|
69
|
+
}
|
|
70
|
+
/** 获取所有 MCP 工具。 */
|
|
71
|
+
getAll() {
|
|
72
|
+
return Array.from(this.tools.values());
|
|
73
|
+
}
|
|
74
|
+
/** 检查工具是否存在。 */
|
|
75
|
+
has(name) {
|
|
76
|
+
return this.tools.has(name);
|
|
77
|
+
}
|
|
78
|
+
/** 已注册 MCP 工具数量。 */
|
|
79
|
+
get size() {
|
|
80
|
+
return this.tools.size;
|
|
81
|
+
}
|
|
82
|
+
/** 清理所有 MCP 连接。 */
|
|
83
|
+
async dispose() {
|
|
84
|
+
await this.pool.closeAll();
|
|
85
|
+
this.tools.clear();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=mcp-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-registry.js","sourceRoot":"","sources":["../../src/tools/mcp-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 工具编排器 — 统一调度工具执行。
|
|
3
|
+
*
|
|
4
|
+
* Phase 4:在 ToolRegistry 和 ReAct 循环之间的中间层。
|
|
5
|
+
*
|
|
6
|
+
* 职责链:工具查找 → 审批检查 → 输入解析 → 执行 → 错误分类 → 结果截断
|
|
7
|
+
*
|
|
8
|
+
* 设计思路:
|
|
9
|
+
* 1. 将散落在 registry.createExecuteTool() 和 react-loop 中的
|
|
10
|
+
* 执行逻辑集中到一个统一入口。
|
|
11
|
+
* 2. 通过 ApprovalHooks 回调将审批 UI 解耦。
|
|
12
|
+
* 3. 提供 createExecuteTool() 兼容现有 ReAct 循环接口。
|
|
13
|
+
*/
|
|
14
|
+
import type { ExecuteTool, ApprovalHooks, ToolAction, ToolActionResult, ToolExecutionResult, ToolQueryable } from '../types.js';
|
|
15
|
+
import type { ApprovalManager } from './approval.js';
|
|
16
|
+
/**
|
|
17
|
+
* 工具编排器。
|
|
18
|
+
*
|
|
19
|
+
* 统一的工具执行入口,包含:
|
|
20
|
+
* 1. 工具查找
|
|
21
|
+
* 2. 审批检查
|
|
22
|
+
* 3. 输入解析
|
|
23
|
+
* 4. 工具执行
|
|
24
|
+
* 5. 错误分类
|
|
25
|
+
* 6. 结果截断
|
|
26
|
+
*/
|
|
27
|
+
export declare class ToolOrchestrator {
|
|
28
|
+
private readonly registry;
|
|
29
|
+
private readonly approvalManager;
|
|
30
|
+
constructor(registry: ToolQueryable, approvalManager: ApprovalManager);
|
|
31
|
+
/**
|
|
32
|
+
* 执行单个工具调用。
|
|
33
|
+
*
|
|
34
|
+
* 完整流程:查找 → 审批 → 解析 → 执行 → 截断
|
|
35
|
+
*/
|
|
36
|
+
executeAction(action: ToolAction, hooks?: ApprovalHooks): Promise<ToolActionResult>;
|
|
37
|
+
/**
|
|
38
|
+
* 批量执行工具调用(顺序执行)。
|
|
39
|
+
*/
|
|
40
|
+
executeActions(actions: ToolAction[], hooks?: ApprovalHooks): Promise<ToolExecutionResult>;
|
|
41
|
+
/**
|
|
42
|
+
* 创建兼容 ExecuteTool 签名的函数。
|
|
43
|
+
*
|
|
44
|
+
* 让 Orchestrator 可以无缝接入现有 ReAct 循环。
|
|
45
|
+
*/
|
|
46
|
+
createExecuteTool(hooks?: ApprovalHooks): ExecuteTool;
|
|
47
|
+
/** 清除 once 级别授权(Turn 结束时调用)。 */
|
|
48
|
+
clearOnceApprovals(): void;
|
|
49
|
+
/** 清除所有授权(Session 结束时调用)。 */
|
|
50
|
+
dispose(): void;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/tools/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACR,WAAW,EACX,aAAa,EAEb,UAAU,EACV,gBAAgB,EAEhB,mBAAmB,EACnB,aAAa,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAsDpD;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAErB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,QAAQ,EAAE,aAAa,EACvB,eAAe,EAAE,eAAe;IAGrD;;;;OAIG;IACG,aAAa,CACf,MAAM,EAAE,UAAU,EAClB,KAAK,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,gBAAgB,CAAC;IAwF5B;;OAEG;IACG,cAAc,CAChB,OAAO,EAAE,UAAU,EAAE,EACrB,KAAK,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,mBAAmB,CAAC;IAqB/B;;;;OAIG;IACH,iBAAiB,CAAC,KAAK,CAAC,EAAE,aAAa,GAAG,WAAW;IAerD,gCAAgC;IAChC,kBAAkB,IAAI,IAAI;IAI1B,6BAA6B;IAC7B,OAAO,IAAI,IAAI;CAGlB"}
|