openmcp-sdk 0.0.4 → 0.0.6

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.
Files changed (172) hide show
  1. package/README.md +37 -15
  2. package/icons/openmcp-sdk.svg +34 -0
  3. package/main.js +85 -0
  4. package/package.json +5 -2
  5. package/renderer/CascadiaCode.woff2 +0 -0
  6. package/renderer/animation.css +121 -0
  7. package/renderer/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  8. package/renderer/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  9. package/renderer/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  10. package/renderer/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  11. package/renderer/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  12. package/renderer/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  13. package/renderer/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  14. package/renderer/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  15. package/renderer/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  16. package/renderer/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  17. package/renderer/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  18. package/renderer/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  19. package/renderer/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  20. package/renderer/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  21. package/renderer/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  22. package/renderer/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  23. package/renderer/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  24. package/renderer/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  25. package/renderer/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  26. package/renderer/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  27. package/renderer/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  28. package/renderer/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  29. package/renderer/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  30. package/renderer/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  31. package/renderer/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  32. package/renderer/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  33. package/renderer/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  34. package/renderer/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  35. package/renderer/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  36. package/renderer/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  37. package/renderer/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  38. package/renderer/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  39. package/renderer/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  40. package/renderer/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  41. package/renderer/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  42. package/renderer/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  43. package/renderer/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  44. package/renderer/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  45. package/renderer/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  46. package/renderer/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  47. package/renderer/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  48. package/renderer/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  49. package/renderer/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  50. package/renderer/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  51. package/renderer/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  52. package/renderer/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  53. package/renderer/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  54. package/renderer/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  55. package/renderer/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  56. package/renderer/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  57. package/renderer/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  58. package/renderer/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  59. package/renderer/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  60. package/renderer/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  61. package/renderer/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  62. package/renderer/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  63. package/renderer/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  64. package/renderer/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  65. package/renderer/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  66. package/renderer/assets/index-DfIBlLbZ.js +447 -0
  67. package/renderer/assets/style-DX4gh5fe.css +1 -0
  68. package/renderer/default-dark.css +772 -0
  69. package/renderer/default-light.css +777 -0
  70. package/renderer/favicon.png +0 -0
  71. package/renderer/iconfont.css +219 -0
  72. package/renderer/iconfont.woff2 +0 -0
  73. package/renderer/images/deepseek.com.ico +0 -0
  74. package/renderer/images/grok.com.png +0 -0
  75. package/renderer/images/gstatic.com.svg +22 -0
  76. package/renderer/images/kimichat.cn.png +0 -0
  77. package/renderer/images/mistral.ai.ico +0 -0
  78. package/renderer/images/ollama.png +0 -0
  79. package/renderer/images/openai.com.ico +0 -0
  80. package/renderer/images/openmcp-qq-qrcode.jpg +0 -0
  81. package/renderer/images/openmcp.png +0 -0
  82. package/renderer/images/openmcp.svg +22 -0
  83. package/renderer/images/perplexity.ai.ico +0 -0
  84. package/renderer/index.html +19 -0
  85. package/renderer/mcp.css +230 -0
  86. package/renderer/sf-mono-regular.woff2 +0 -0
  87. package/renderer/vscode.css +149 -0
  88. package/service/common/index.d.ts +1 -2
  89. package/service/common/index.d.ts.map +1 -1
  90. package/service/common/index.dto.d.ts +7 -3
  91. package/service/common/index.dto.d.ts.map +1 -1
  92. package/service/common/index.dto.js +1 -2
  93. package/service/common/index.js +4 -8
  94. package/service/common/router.d.ts +7 -7
  95. package/service/common/router.d.ts.map +1 -1
  96. package/service/common/router.js +18 -22
  97. package/service/hook/adapter.d.ts +10 -17
  98. package/service/hook/adapter.d.ts.map +1 -1
  99. package/service/hook/adapter.js +31 -51
  100. package/service/hook/axios-fetch.d.ts +7 -0
  101. package/service/hook/axios-fetch.d.ts.map +1 -0
  102. package/service/hook/axios-fetch.js +162 -0
  103. package/service/hook/db.d.ts.map +1 -1
  104. package/service/hook/db.js +11 -50
  105. package/service/hook/llm.d.ts.map +1 -1
  106. package/service/hook/llm.js +49 -4
  107. package/service/hook/setting.js +6 -11
  108. package/service/hook/types.js +1 -2
  109. package/service/hook/util.d.ts +2 -0
  110. package/service/hook/util.d.ts.map +1 -0
  111. package/service/hook/util.js +1 -0
  112. package/service/index.d.ts +4 -4
  113. package/service/index.d.ts.map +1 -1
  114. package/service/index.js +4 -14
  115. package/service/llm/llm.controller.d.ts +9 -4
  116. package/service/llm/llm.controller.d.ts.map +1 -1
  117. package/service/llm/llm.controller.js +27 -20
  118. package/service/llm/llm.dto.d.ts +15 -0
  119. package/service/llm/llm.dto.d.ts.map +1 -1
  120. package/service/llm/llm.dto.js +1 -2
  121. package/service/llm/llm.service.d.ts +3 -3
  122. package/service/llm/llm.service.d.ts.map +1 -1
  123. package/service/llm/llm.service.js +53 -28
  124. package/service/main.d.ts +7 -0
  125. package/service/main.d.ts.map +1 -0
  126. package/service/main.js +107 -0
  127. package/service/mcp/auth.service.d.ts +23 -0
  128. package/service/mcp/auth.service.d.ts.map +1 -0
  129. package/service/mcp/auth.service.js +158 -0
  130. package/service/mcp/client.controller.d.ts +146 -40
  131. package/service/mcp/client.controller.d.ts.map +1 -1
  132. package/service/mcp/client.controller.js +34 -31
  133. package/service/mcp/client.dto.d.ts +4 -3
  134. package/service/mcp/client.dto.d.ts.map +1 -1
  135. package/service/mcp/client.dto.js +1 -2
  136. package/service/mcp/client.service.d.ts +140 -32
  137. package/service/mcp/client.service.d.ts.map +1 -1
  138. package/service/mcp/client.service.js +55 -22
  139. package/service/mcp/connect.controller.d.ts +5 -5
  140. package/service/mcp/connect.controller.d.ts.map +1 -1
  141. package/service/mcp/connect.controller.js +28 -15
  142. package/service/mcp/connect.service.d.ts +7 -5
  143. package/service/mcp/connect.service.d.ts.map +1 -1
  144. package/service/mcp/connect.service.js +235 -27
  145. package/service/mcp/ocr.controller.d.ts +3 -4
  146. package/service/mcp/ocr.controller.d.ts.map +1 -1
  147. package/service/mcp/ocr.controller.js +11 -15
  148. package/service/mcp/ocr.dto.js +1 -2
  149. package/service/mcp/ocr.service.d.ts +2 -2
  150. package/service/mcp/ocr.service.d.ts.map +1 -1
  151. package/service/mcp/ocr.service.js +21 -64
  152. package/service/panel/panel.controller.d.ts +9 -9
  153. package/service/panel/panel.controller.d.ts.map +1 -1
  154. package/service/panel/panel.controller.js +28 -26
  155. package/service/panel/panel.dto.js +1 -2
  156. package/service/panel/panel.service.d.ts +3 -3
  157. package/service/panel/panel.service.d.ts.map +1 -1
  158. package/service/panel/panel.service.js +7 -44
  159. package/service/server.d.ts +7 -0
  160. package/service/server.d.ts.map +1 -0
  161. package/service/server.js +131 -0
  162. package/service/setting/setting.controller.d.ts +7 -7
  163. package/service/setting/setting.controller.d.ts.map +1 -1
  164. package/service/setting/setting.controller.js +15 -21
  165. package/service/setting/setting.dto.js +1 -2
  166. package/service/setting/setting.service.d.ts +1 -1
  167. package/service/setting/setting.service.d.ts.map +1 -1
  168. package/service/setting/setting.service.js +14 -49
  169. package/task-loop.d.ts +35 -0
  170. package/task-loop.js +8480 -205
  171. package/tools.js +8 -1
  172. package/task-loop.js.map +0 -1
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
2
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
3
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -19,20 +18,19 @@ var __rest = (this && this.__rest) || function (s, e) {
19
18
  }
20
19
  return t;
21
20
  };
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.McpClient = void 0;
24
- exports.connect = connect;
25
- exports.postProcessMcpToolcallResponse = postProcessMcpToolcallResponse;
26
- const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
27
- const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
28
- const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
29
- const ocr_service_1 = require("./ocr.service");
21
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
22
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
23
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
24
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
25
+ import { createOcrWorker, saveBase64ImageData } from "./ocr.service.js";
26
+ import { OAuthClient } from "./auth.service.js";
27
+ import { UnauthorizedError } from '@modelcontextprotocol/sdk/client/auth.js';
30
28
  // 增强的客户端类
31
- class McpClient {
29
+ export class McpClient {
32
30
  constructor(options) {
33
31
  this.options = options;
34
32
  this.serverVersion = undefined;
35
- this.client = new index_js_1.Client({
33
+ this.client = new Client({
36
34
  name: "openmcp test local client",
37
35
  version: "0.0.1"
38
36
  }, {
@@ -42,14 +40,18 @@ class McpClient {
42
40
  tools: {}
43
41
  }
44
42
  });
43
+ this.oAuthClient = new OAuthClient();
45
44
  }
46
45
  // 连接方法
47
46
  connect() {
48
47
  return __awaiter(this, void 0, void 0, function* () {
48
+ if (!this.oauthPovider) {
49
+ this.oauthPovider = yield this.oAuthClient.getOAuthProvider();
50
+ }
49
51
  // 根据连接类型创建传输层
50
52
  switch (this.options.connectionType) {
51
53
  case 'STDIO':
52
- this.transport = new stdio_js_1.StdioClientTransport({
54
+ this.transport = new StdioClientTransport({
53
55
  command: this.options.command || '',
54
56
  args: this.options.args || [],
55
57
  cwd: this.options.cwd || process.cwd(),
@@ -61,15 +63,47 @@ class McpClient {
61
63
  if (!this.options.url) {
62
64
  throw new Error('URL is required for SSE connection');
63
65
  }
64
- this.transport = new sse_js_1.SSEClientTransport(new URL(this.options.url));
66
+ this.transport = new SSEClientTransport(new URL(this.options.url), {
67
+ authProvider: this.oauthPovider
68
+ });
69
+ break;
70
+ case 'STREAMABLE_HTTP':
71
+ if (!this.options.url) {
72
+ throw new Error('URL is required for STREAMABLE_HTTP connection');
73
+ }
74
+ this.transport = new StreamableHTTPClientTransport(new URL(this.options.url), {
75
+ authProvider: this.oauthPovider
76
+ });
65
77
  break;
66
78
  default:
67
79
  throw new Error(`Unsupported connection type: ${this.options.connectionType}`);
68
80
  }
69
81
  // 建立连接
70
82
  if (this.transport) {
71
- yield this.client.connect(this.transport);
72
- console.log(`Connected to MCP server via ${this.options.connectionType}`);
83
+ try {
84
+ // console.log(`🔌 Connecting to MCP server via ${this.options.connectionType}...`);
85
+ yield this.client.connect(this.transport);
86
+ // console.log(`✅ Connected to MCP server via ${this.options.connectionType}`);
87
+ }
88
+ catch (error) {
89
+ if (error instanceof UnauthorizedError) {
90
+ if (!(this.transport instanceof StreamableHTTPClientTransport) && !(this.transport instanceof SSEClientTransport)) {
91
+ console.error('❌ OAuth is only supported for StreamableHTTP and SSE transports. Please use one of these transports for OAuth authentication.');
92
+ return;
93
+ }
94
+ console.log('🔐 OAuth required - waiting for authorization...');
95
+ const callbackPromise = this.oAuthClient.waitForOAuthCallback();
96
+ const authCode = yield callbackPromise;
97
+ yield this.transport.finishAuth(authCode);
98
+ console.log('🔐 Authorization code received:', authCode);
99
+ console.log('🔌 Reconnecting with authenticated transport...');
100
+ yield this.connect(); // 递归重试
101
+ }
102
+ else {
103
+ console.error('❌ Connection failed with non-auth error:', error);
104
+ throw error;
105
+ }
106
+ }
73
107
  }
74
108
  });
75
109
  }
@@ -132,14 +166,13 @@ class McpClient {
132
166
  callTool(options) {
133
167
  return __awaiter(this, void 0, void 0, function* () {
134
168
  const { callToolOption } = options, methodArgs = __rest(options, ["callToolOption"]);
135
- console.log('callToolOption', callToolOption);
136
- return yield this.client.callTool(methodArgs, undefined, callToolOption);
169
+ const res = yield this.client.callTool(methodArgs, undefined, callToolOption);
170
+ return res;
137
171
  });
138
172
  }
139
173
  }
140
- exports.McpClient = McpClient;
141
174
  // Connect 函数实现
142
- function connect(options) {
175
+ export function connect(options) {
143
176
  return __awaiter(this, void 0, void 0, function* () {
144
177
  const client = new McpClient(options);
145
178
  yield client.connect();
@@ -149,10 +182,10 @@ function connect(options) {
149
182
  function handleImage(content, webview) {
150
183
  return __awaiter(this, void 0, void 0, function* () {
151
184
  if (content.data && content.mimeType) {
152
- const filename = (0, ocr_service_1.saveBase64ImageData)(content.data, content.mimeType);
185
+ const filename = saveBase64ImageData(content.data, content.mimeType);
153
186
  content.data = filename;
154
187
  // 加入工作线程
155
- const worker = (0, ocr_service_1.createOcrWorker)(filename, webview);
188
+ const worker = createOcrWorker(filename, webview);
156
189
  content._meta = {
157
190
  ocr: true,
158
191
  workerId: worker.id
@@ -167,7 +200,7 @@ function handleImage(content, webview) {
167
200
  * @param response
168
201
  * @returns
169
202
  */
170
- function postProcessMcpToolcallResponse(response, webview) {
203
+ export function postProcessMcpToolcallResponse(response, webview) {
171
204
  if (response.isError) {
172
205
  // 如果是错误响应,将其转换为错误信息
173
206
  return response;
@@ -1,12 +1,12 @@
1
- import { RequestClientType } from '../common';
2
- import { PostMessageble } from '../hook/adapter';
1
+ import { PostMessageble } from '../hook/adapter.js';
2
+ import { RequestData } from '../common/index.dto.js';
3
3
  export declare class ConnectController {
4
- connect(client: RequestClientType, data: any, webview: PostMessageble): Promise<import("../common/index.dto").RestfulResponse>;
5
- lookupEnvVar(client: RequestClientType, data: any, webview: PostMessageble): Promise<{
4
+ connect(data: any, webview: PostMessageble): Promise<import("../common/index.dto.js").RestfulResponse>;
5
+ lookupEnvVar(data: RequestData, webview: PostMessageble): Promise<{
6
6
  code: number;
7
7
  msg: any;
8
8
  }>;
9
- ping(client: RequestClientType, data: any, webview: PostMessageble): Promise<{
9
+ ping(data: RequestData, webview: PostMessageble): Promise<{
10
10
  code: number;
11
11
  msg: string;
12
12
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"connect.controller.d.ts","sourceRoot":"","sources":["../../src/mcp/connect.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,qBAAa,iBAAiB;IAGpB,OAAO,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;IAMrE,YAAY,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;IAW1E,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;;;;CAc3E"}
1
+ {"version":3,"file":"connect.controller.d.ts","sourceRoot":"","sources":["../../src/mcp/connect.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,qBAAa,iBAAiB;IAGpB,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;IAM1C,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc;;;;IA6BvD,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc;;;;;;;CAexD"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -14,29 +13,44 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
14
13
  step((generator = generator.apply(thisArg, _arguments || [])).next());
15
14
  });
16
15
  };
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.ConnectController = void 0;
19
- const common_1 = require("../common");
20
- const connect_service_1 = require("./connect.service");
21
- class ConnectController {
22
- connect(client, data, webview) {
16
+ import { Controller } from '../common/index.js';
17
+ import { connectService, getClient } from './connect.service.js';
18
+ export class ConnectController {
19
+ connect(data, webview) {
23
20
  return __awaiter(this, void 0, void 0, function* () {
24
- const res = yield (0, connect_service_1.connectService)(client, data);
21
+ const res = yield connectService(data, webview);
25
22
  return res;
26
23
  });
27
24
  }
28
- lookupEnvVar(client, data, webview) {
25
+ lookupEnvVar(data, webview) {
29
26
  return __awaiter(this, void 0, void 0, function* () {
30
27
  const { keys } = data;
31
- const values = keys.map((key) => process.env[key] || '');
28
+ const values = keys.map((key) => {
29
+ if (process.platform === 'win32') {
30
+ switch (key) {
31
+ case 'USER':
32
+ return process.env.USERNAME || '';
33
+ case 'HOME':
34
+ return process.env.USERPROFILE || process.env.HOME;
35
+ case 'LOGNAME':
36
+ return process.env.USERNAME || '';
37
+ case 'SHELL':
38
+ return process.env.SHELL || process.env.COMSPEC;
39
+ case 'TERM':
40
+ return process.env.TERM || '未设置 (Windows 默认终端)';
41
+ }
42
+ }
43
+ return process.env[key] || '';
44
+ });
32
45
  return {
33
46
  code: 200,
34
47
  msg: values
35
48
  };
36
49
  });
37
50
  }
38
- ping(client, data, webview) {
51
+ ping(data, webview) {
39
52
  return __awaiter(this, void 0, void 0, function* () {
53
+ const client = getClient(data.clientId);
40
54
  if (!client) {
41
55
  const connectResult = {
42
56
  code: 501,
@@ -51,13 +65,12 @@ class ConnectController {
51
65
  });
52
66
  }
53
67
  }
54
- exports.ConnectController = ConnectController;
55
68
  __decorate([
56
- (0, common_1.Controller)('connect')
69
+ Controller('connect')
57
70
  ], ConnectController.prototype, "connect", null);
58
71
  __decorate([
59
- (0, common_1.Controller)('lookup-env-var')
72
+ Controller('lookup-env-var')
60
73
  ], ConnectController.prototype, "lookupEnvVar", null);
61
74
  __decorate([
62
- (0, common_1.Controller)('ping')
75
+ Controller('ping')
63
76
  ], ConnectController.prototype, "ping", null);
@@ -1,7 +1,9 @@
1
- import { RequestClientType } from '../common';
2
- import { RestfulResponse } from '../common/index.dto';
3
- import { McpOptions } from './client.dto';
4
- export declare let client: RequestClientType;
1
+ import { RequestClientType } from '../common/index.dto.js';
2
+ import { RestfulResponse } from '../common/index.dto.js';
3
+ import { McpOptions } from './client.dto.js';
4
+ import { PostMessageble } from '../hook/adapter.js';
5
+ export declare const clientMap: Map<string, RequestClientType>;
6
+ export declare function getClient(clientId?: string): RequestClientType | undefined;
5
7
  export declare function tryGetRunCommandError(command: string, args?: string[], cwd?: string): string | null;
6
- export declare function connectService(_client: RequestClientType, option: McpOptions): Promise<RestfulResponse>;
8
+ export declare function connectService(option: McpOptions, webview?: PostMessageble): Promise<RestfulResponse>;
7
9
  //# sourceMappingURL=connect.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.service.d.ts","sourceRoot":"","sources":["../../src/mcp/connect.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,eAAO,IAAI,MAAM,EAAE,iBAA6B,CAAC;AAEjD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBvG;AAED,wBAAsB,cAAc,CAChC,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,UAAU,GACnB,OAAO,CAAC,eAAe,CAAC,CA0C1B"}
1
+ {"version":3,"file":"connect.service.d.ts","sourceRoot":"","sources":["../../src/mcp/connect.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,eAAO,MAAM,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAa,CAAC;AACnE,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBvG;AA8MD,wBAAsB,cAAc,CACnC,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAiF1B"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
2
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
3
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -8,19 +7,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
8
  });
10
9
  };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.client = void 0;
13
- exports.tryGetRunCommandError = tryGetRunCommandError;
14
- exports.connectService = connectService;
15
- const node_child_process_1 = require("node:child_process");
16
- const client_service_1 = require("./client.service");
17
- // TODO: 更多的 client
18
- exports.client = undefined;
19
- function tryGetRunCommandError(command, args = [], cwd) {
10
+ import { exec, execSync, spawnSync } from 'node:child_process';
11
+ import { connect } from './client.service.js';
12
+ import * as crypto from 'node:crypto';
13
+ import path from 'node:path';
14
+ import fs from 'node:fs';
15
+ import * as os from 'os';
16
+ import Table from 'cli-table3';
17
+ export const clientMap = new Map();
18
+ export function getClient(clientId) {
19
+ return clientMap.get(clientId || '');
20
+ }
21
+ export function tryGetRunCommandError(command, args = [], cwd) {
20
22
  try {
21
- console.log('current command', command);
22
- console.log('current args', args);
23
- const result = (0, node_child_process_1.spawnSync)(command, args, {
23
+ const commandString = command + ' ' + args.join(' ');
24
+ const result = spawnSync(commandString, {
24
25
  cwd: cwd || process.cwd(),
25
26
  stdio: 'pipe',
26
27
  encoding: 'utf-8'
@@ -37,33 +38,240 @@ function tryGetRunCommandError(command, args = [], cwd) {
37
38
  return error instanceof Error ? error.message : String(error);
38
39
  }
39
40
  }
40
- function connectService(_client, option) {
41
+ function getCWD(option) {
42
+ var _a;
43
+ // if (option.cwd) {
44
+ // return option.cwd;
45
+ // }
46
+ const file = (_a = option.args) === null || _a === void 0 ? void 0 : _a.at(-1);
47
+ if (file) {
48
+ // 如果是绝对路径,直接返回目录
49
+ if (path.isAbsolute(file)) {
50
+ // 如果是是文件,则返回文件所在的目录
51
+ if (fs.statSync(file).isDirectory()) {
52
+ return file;
53
+ }
54
+ else {
55
+ return path.dirname(file);
56
+ }
57
+ }
58
+ else {
59
+ // 如果是相对路径,根据 cwd 获取真实路径
60
+ const absPath = path.resolve(option.cwd || process.cwd(), file);
61
+ // 如果是是文件,则返回文件所在的目录
62
+ if (fs.statSync(absPath).isDirectory()) {
63
+ return absPath;
64
+ }
65
+ else {
66
+ return path.dirname(absPath);
67
+ }
68
+ }
69
+ }
70
+ return undefined;
71
+ }
72
+ function getCommandFileExt(option) {
73
+ var _a;
74
+ const file = (_a = option.args) === null || _a === void 0 ? void 0 : _a.at(-1);
75
+ if (file) {
76
+ return path.extname(file);
77
+ }
78
+ return undefined;
79
+ }
80
+ function collectAllOutputExec(command, cwd) {
81
+ return new Promise((resolve, reject) => {
82
+ const handler = setTimeout(() => {
83
+ resolve('');
84
+ }, 5000);
85
+ exec(command, { cwd }, (error, stdout, stderr) => {
86
+ const errorString = error || '';
87
+ const stdoutString = stdout || '';
88
+ const stderrString = stderr || '';
89
+ console.log('[collectAllOutputExec]', errorString);
90
+ console.log('[collectAllOutputExec]', stdoutString);
91
+ console.log('[collectAllOutputExec]', stderrString);
92
+ clearTimeout(handler);
93
+ resolve(errorString + stdoutString + stderrString);
94
+ });
95
+ });
96
+ }
97
+ function preprocessCommand(option, webview) {
41
98
  return __awaiter(this, void 0, void 0, function* () {
42
- try {
43
- console.log('ready to connect', option);
44
- // 对于特殊表示的路径,进行特殊的支持
45
- if (option.args) {
46
- option.args = option.args.map(arg => {
47
- if (arg.startsWith('~/')) {
48
- return arg.replace('~', process.env.HOME || '');
49
- }
50
- return arg;
51
- });
99
+ // 对于特殊表示的路径,进行特殊的支持
100
+ if (option.args) {
101
+ option.args = option.args.map(arg => {
102
+ if (arg.startsWith('~/')) {
103
+ return arg.replace('~', process.env.HOME || '');
104
+ }
105
+ return arg;
106
+ });
107
+ }
108
+ if (option.cwd && option.cwd.startsWith('~/')) {
109
+ option.cwd = option.cwd.replace('~', process.env.HOME || '');
110
+ }
111
+ if (option.connectionType === 'SSE' || option.connectionType === 'STREAMABLE_HTTP') {
112
+ return;
113
+ }
114
+ const cwd = getCWD(option);
115
+ if (!cwd) {
116
+ return;
117
+ }
118
+ const ext = getCommandFileExt(option);
119
+ if (!ext) {
120
+ return;
121
+ }
122
+ // STDIO 模式下,对不同类型的项目进行额外支持
123
+ // uv:如果没有初始化,则进行 uv sync,将 mcp 设置为虚拟环境的
124
+ // npm:如果没有初始化,则进行 npm init,将 mcp 设置为虚拟环境
125
+ // go:如果没有初始化,则进行 go mod init
126
+ switch (ext) {
127
+ case '.py':
128
+ yield initUv(option, cwd, webview);
129
+ break;
130
+ case '.js':
131
+ case '.ts':
132
+ yield initNpm(option, cwd, webview);
133
+ break;
134
+ default:
135
+ break;
136
+ }
137
+ });
138
+ }
139
+ function initUv(option, cwd, webview) {
140
+ return __awaiter(this, void 0, void 0, function* () {
141
+ let projectDir = cwd;
142
+ while (projectDir !== path.dirname(projectDir)) {
143
+ if (fs.readdirSync(projectDir).includes('pyproject.toml')) {
144
+ break;
145
+ }
146
+ projectDir = path.dirname(projectDir);
147
+ }
148
+ const venv = path.join(projectDir, '.venv');
149
+ // judge by OS
150
+ const mcpCli = os.platform() === 'win32' ?
151
+ path.join(venv, 'Scripts', 'mcp.exe') :
152
+ path.join(venv, 'bin', 'mcp');
153
+ if (option.command === 'mcp') {
154
+ option.command = mcpCli;
155
+ option.cwd = projectDir;
156
+ }
157
+ if (fs.existsSync(mcpCli)) {
158
+ return '';
159
+ }
160
+ const syncOutput = yield collectAllOutputExec('uv sync', projectDir);
161
+ webview === null || webview === void 0 ? void 0 : webview.postMessage({
162
+ command: 'connect/log',
163
+ data: {
164
+ code: syncOutput.toLowerCase().startsWith('error') ? 501 : 200,
165
+ msg: {
166
+ title: 'uv sync',
167
+ message: syncOutput
168
+ }
169
+ }
170
+ });
171
+ const addOutput = yield collectAllOutputExec('uv add mcp "mcp[cli]"', projectDir);
172
+ webview === null || webview === void 0 ? void 0 : webview.postMessage({
173
+ command: 'connect/log',
174
+ data: {
175
+ code: addOutput.toLowerCase().startsWith('error') ? 501 : 200,
176
+ msg: {
177
+ title: 'uv add mcp "mcp[cli]"',
178
+ message: addOutput
179
+ }
180
+ }
181
+ });
182
+ });
183
+ }
184
+ function initNpm(option, cwd, webview) {
185
+ return __awaiter(this, void 0, void 0, function* () {
186
+ let projectDir = cwd;
187
+ while (projectDir !== path.dirname(projectDir)) {
188
+ if (fs.readdirSync(projectDir).includes('package.json')) {
189
+ break;
52
190
  }
53
- exports.client = yield (0, client_service_1.connect)(option);
191
+ projectDir = path.dirname(projectDir);
192
+ }
193
+ const nodeModulesPath = path.join(projectDir, 'node_modules');
194
+ if (fs.existsSync(nodeModulesPath)) {
195
+ return '';
196
+ }
197
+ const installOutput = execSync('npm i', { cwd: projectDir }).toString('utf-8') + '\n';
198
+ webview === null || webview === void 0 ? void 0 : webview.postMessage({
199
+ command: 'connect/log',
200
+ data: {
201
+ code: installOutput.toLowerCase().startsWith('error') ? 200 : 501,
202
+ msg: {
203
+ title: 'npm i',
204
+ message: installOutput
205
+ }
206
+ }
207
+ });
208
+ });
209
+ }
210
+ function deterministicUUID(input) {
211
+ return __awaiter(this, void 0, void 0, function* () {
212
+ // 使用Web Crypto API进行哈希
213
+ const msgBuffer = new TextEncoder().encode(input);
214
+ const hashBuffer = yield crypto.subtle.digest('SHA-1', msgBuffer);
215
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
216
+ const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
217
+ // 格式化为UUID (版本5)
218
+ return [
219
+ hashHex.substring(0, 8),
220
+ hashHex.substring(8, 4),
221
+ '5' + hashHex.substring(13, 3), // 设置版本为5
222
+ '8' + hashHex.substring(17, 3), // 设置变体
223
+ hashHex.substring(20, 12)
224
+ ].join('-');
225
+ });
226
+ }
227
+ export function connectService(option, webview) {
228
+ return __awaiter(this, void 0, void 0, function* () {
229
+ var _a;
230
+ try {
231
+ // 使用cli-table3创建美观的表格
232
+ const table = new Table({
233
+ head: ['Property', 'Value'],
234
+ colWidths: [20, 60],
235
+ style: {
236
+ head: ['green'],
237
+ border: ['grey']
238
+ }
239
+ });
240
+ table.push(['Connection Type', option.connectionType], ['Command', option.command || 'N/A'], ['Arguments', ((_a = option.args) === null || _a === void 0 ? void 0 : _a.join(' ')) || 'N/A'], ['Working Directory', option.cwd || 'N/A'], ['URL', option.url || 'N/A']);
241
+ console.log(table.toString());
242
+ // 预处理字符串
243
+ yield preprocessCommand(option, webview);
244
+ // 通过 option 字符串进行 hash,得到唯一的 uuid
245
+ const uuid = yield deterministicUUID(JSON.stringify(option));
246
+ const reuseConntion = clientMap.has(uuid);
247
+ // if (!clientMap.has(uuid)) {
248
+ // const client = await connect(option);
249
+ // clientMap.set(uuid, client);
250
+ // }
251
+ // const client = clientMap.get(uuid)!;
252
+ const client = yield connect(option);
253
+ clientMap.set(uuid, client);
254
+ const versionInfo = client.getServerVersion();
54
255
  const connectResult = {
55
256
  code: 200,
56
- msg: 'Connect to OpenMCP successfully\nWelcome back, Kirigaya'
257
+ msg: {
258
+ status: 'success',
259
+ clientId: uuid,
260
+ reuseConntion,
261
+ name: versionInfo === null || versionInfo === void 0 ? void 0 : versionInfo.name,
262
+ version: versionInfo === null || versionInfo === void 0 ? void 0 : versionInfo.version
263
+ }
57
264
  };
58
265
  return connectResult;
59
266
  }
60
267
  catch (error) {
268
+ console.log('[connectService catch error]', error);
61
269
  // TODO: 这边获取到的 error 不够精致,如何才能获取到更加精准的错误
62
270
  // 比如 error: Failed to spawn: `server.py`
63
271
  // Caused by: No such file or directory (os error 2)
64
272
  let errorMsg = '';
65
273
  if (option.command) {
66
- errorMsg += tryGetRunCommandError(option.command, option.args, option.cwd);
274
+ errorMsg += yield collectAllOutputExec(option.command + ' ' + (option.args || []).join(' '), option.cwd || process.cwd());
67
275
  }
68
276
  errorMsg += error.toString();
69
277
  const connectResult = {
@@ -1,13 +1,12 @@
1
- import { RequestClientType } from "../common";
2
- import { PostMessageble } from "../hook/adapter";
1
+ import { PostMessageble } from "../hook/adapter.js";
3
2
  export declare class OcrController {
4
- getOcrImage(client: RequestClientType, data: any, webview: PostMessageble): Promise<{
3
+ getOcrImage(data: any, webview: PostMessageble): Promise<{
5
4
  code: number;
6
5
  msg: {
7
6
  base64String: string | undefined;
8
7
  };
9
8
  }>;
10
- startOcr(client: RequestClientType, data: any, webview: PostMessageble): Promise<{
9
+ startOcr(data: any, webview: PostMessageble): Promise<{
11
10
  code: number;
12
11
  msg: {
13
12
  filename: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ocr.controller.d.ts","sourceRoot":"","sources":["../../src/mcp/ocr.controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,qBAAa,aAAa;IAEhB,WAAW,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;;;IAazE,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;;;;CAe/E"}
1
+ {"version":3,"file":"ocr.controller.d.ts","sourceRoot":"","sources":["../../src/mcp/ocr.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIpD,qBAAa,aAAa;IAEhB,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;;;IAa9C,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc;;;;;;;CAepD"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -14,16 +13,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
14
13
  step((generator = generator.apply(thisArg, _arguments || [])).next());
15
14
  });
16
15
  };
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.OcrController = void 0;
19
- const common_1 = require("../common");
20
- const db_1 = require("../hook/db");
21
- const ocr_service_1 = require("./ocr.service");
22
- class OcrController {
23
- getOcrImage(client, data, webview) {
16
+ import { Controller } from "../common/index.js";
17
+ import { diskStorage } from "../hook/db.js";
18
+ import { createOcrWorker, saveBase64ImageData } from "./ocr.service.js";
19
+ export class OcrController {
20
+ getOcrImage(data, webview) {
24
21
  return __awaiter(this, void 0, void 0, function* () {
25
22
  const { filename } = data;
26
- const buffer = db_1.diskStorage.getSync(filename);
23
+ const buffer = diskStorage.getSync(filename);
27
24
  const base64String = buffer ? buffer.toString('base64') : undefined;
28
25
  return {
29
26
  code: 200,
@@ -33,11 +30,11 @@ class OcrController {
33
30
  };
34
31
  });
35
32
  }
36
- startOcr(client, data, webview) {
33
+ startOcr(data, webview) {
37
34
  return __awaiter(this, void 0, void 0, function* () {
38
35
  const { base64String, mimeType } = data;
39
- const filename = (0, ocr_service_1.saveBase64ImageData)(base64String, mimeType);
40
- const worker = (0, ocr_service_1.createOcrWorker)(filename, webview);
36
+ const filename = saveBase64ImageData(base64String, mimeType);
37
+ const worker = createOcrWorker(filename, webview);
41
38
  return {
42
39
  code: 200,
43
40
  msg: {
@@ -48,10 +45,9 @@ class OcrController {
48
45
  });
49
46
  }
50
47
  }
51
- exports.OcrController = OcrController;
52
48
  __decorate([
53
- (0, common_1.Controller)('ocr/get-ocr-image')
49
+ Controller('ocr/get-ocr-image')
54
50
  ], OcrController.prototype, "getOcrImage", null);
55
51
  __decorate([
56
- (0, common_1.Controller)('ocr/start-ocr')
52
+ Controller('ocr/start-ocr')
57
53
  ], OcrController.prototype, "startOcr", null);
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};