fa-mcp-sdk 0.2.3 → 0.2.16

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 (60) hide show
  1. package/README.md +1 -1
  2. package/dist/core/_types_/types.d.ts +34 -2
  3. package/dist/core/_types_/types.d.ts.map +1 -1
  4. package/dist/core/bootstrap/dotenv.d.ts.map +1 -1
  5. package/dist/core/bootstrap/dotenv.js +1 -1
  6. package/dist/core/bootstrap/dotenv.js.map +1 -1
  7. package/dist/core/bootstrap/startup-info.d.ts.map +1 -1
  8. package/dist/core/bootstrap/startup-info.js +3 -1
  9. package/dist/core/bootstrap/startup-info.js.map +1 -1
  10. package/dist/core/consul/deregister.d.ts +1 -0
  11. package/dist/core/consul/deregister.d.ts.map +1 -1
  12. package/dist/core/consul/deregister.js +8 -5
  13. package/dist/core/consul/deregister.js.map +1 -1
  14. package/dist/core/index.d.ts +6 -1
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/core/index.js +5 -0
  17. package/dist/core/index.js.map +1 -1
  18. package/dist/core/init-mcp-server.d.ts.map +1 -1
  19. package/dist/core/init-mcp-server.js +3 -0
  20. package/dist/core/init-mcp-server.js.map +1 -1
  21. package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
  22. package/dist/core/mcp/create-mcp-server.js +3 -1
  23. package/dist/core/mcp/create-mcp-server.js.map +1 -1
  24. package/dist/core/mcp/prompts.d.ts.map +1 -1
  25. package/dist/core/mcp/prompts.js +15 -1
  26. package/dist/core/mcp/prompts.js.map +1 -1
  27. package/dist/core/mcp/resources.d.ts +3 -8
  28. package/dist/core/mcp/resources.d.ts.map +1 -1
  29. package/dist/core/mcp/resources.js +13 -6
  30. package/dist/core/mcp/resources.js.map +1 -1
  31. package/dist/core/utils/port-checker.d.ts +15 -0
  32. package/dist/core/utils/port-checker.d.ts.map +1 -0
  33. package/dist/core/utils/port-checker.js +45 -0
  34. package/dist/core/utils/port-checker.js.map +1 -0
  35. package/dist/core/utils/testing/McpSimpleHttpClient.d.ts +45 -0
  36. package/dist/core/utils/testing/McpSimpleHttpClient.d.ts.map +1 -0
  37. package/dist/core/utils/testing/McpSimpleHttpClient.js +99 -0
  38. package/dist/core/utils/testing/McpSimpleHttpClient.js.map +1 -0
  39. package/dist/core/utils/testing/McpSseClient.d.ts +40 -0
  40. package/dist/core/utils/testing/McpSseClient.d.ts.map +1 -0
  41. package/dist/core/utils/testing/McpSseClient.js +259 -0
  42. package/dist/core/utils/testing/McpSseClient.js.map +1 -0
  43. package/dist/core/utils/testing/McpStdioClient.d.ts +18 -0
  44. package/dist/core/utils/testing/McpStdioClient.d.ts.map +1 -0
  45. package/dist/core/utils/testing/McpStdioClient.js +102 -0
  46. package/dist/core/utils/testing/McpStdioClient.js.map +1 -0
  47. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts +62 -0
  48. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -0
  49. package/dist/core/utils/testing/McpStreamableHttpClient.js +242 -0
  50. package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -0
  51. package/dist/core/web/about-page/css.d.ts.map +1 -1
  52. package/dist/core/web/about-page/css.js +4 -0
  53. package/dist/core/web/about-page/css.js.map +1 -1
  54. package/dist/core/web/about-page/render.d.ts.map +1 -1
  55. package/dist/core/web/about-page/render.js +1 -4
  56. package/dist/core/web/about-page/render.js.map +1 -1
  57. package/dist/core/web/server-http.d.ts.map +1 -1
  58. package/dist/core/web/server-http.js +107 -16
  59. package/dist/core/web/server-http.js.map +1 -1
  60. package/package.json +17 -15
@@ -0,0 +1,99 @@
1
+ // noinspection UnnecessaryLocalVariableJS
2
+ /**
3
+ * MCP Simple HTTP Client
4
+ *
5
+ * Uses simple POST requests instead of streaming HTTP for compatibility
6
+ * with the current server implementation
7
+ */
8
+ export class McpSimpleHttpClient {
9
+ baseUrl;
10
+ endpointPath;
11
+ customHeaders;
12
+ nextId = 1;
13
+ serverInfo;
14
+ capabilities;
15
+ protocolVersion;
16
+ constructor(baseUrl, options) {
17
+ this.baseUrl = baseUrl.replace(/\/$/, '');
18
+ this.endpointPath = options?.endpointPath ?? '/mcp';
19
+ this.customHeaders = options?.headers ?? {};
20
+ }
21
+ async initialize(params = {}) {
22
+ const res = await this.sendRpc('initialize', params);
23
+ this.protocolVersion = res?.protocolVersion;
24
+ this.capabilities = res?.capabilities;
25
+ this.serverInfo = res?.serverInfo;
26
+ // best-effort: notify the server about initialization
27
+ this.notify('notifications/initialized', {});
28
+ return res;
29
+ }
30
+ async close() {
31
+ // No persistent connection to close for simple HTTP client
32
+ }
33
+ async sendRequest(request) {
34
+ const headers = {
35
+ 'Content-Type': 'application/json',
36
+ 'Accept': 'application/json',
37
+ ...this.customHeaders,
38
+ };
39
+ const response = await fetch(`${this.baseUrl}${this.endpointPath}`, {
40
+ method: 'POST',
41
+ headers,
42
+ body: JSON.stringify(request),
43
+ });
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP request failed: ${response.status} ${response.statusText}`);
46
+ }
47
+ const result = await response.json();
48
+ return result;
49
+ }
50
+ notify(method, params) {
51
+ const req = { jsonrpc: '2.0', method, params };
52
+ // Fire and forget for notifications
53
+ this.sendRequest(req).catch(() => {
54
+ // Ignore errors for notifications
55
+ });
56
+ }
57
+ async sendRpc(method, params) {
58
+ const id = this.nextId++;
59
+ const req = { jsonrpc: '2.0', id, method, params };
60
+ const response = await this.sendRequest(req);
61
+ // Handle response
62
+ if (response.result !== undefined && typeof response.id === 'number') {
63
+ const { result } = response;
64
+ return result;
65
+ }
66
+ // Handle error response
67
+ if (response.error && 'id' in response) {
68
+ const { error } = response;
69
+ const err = new Error(`MCP Error ${error.code}: ${error.message}`);
70
+ err.data = error.data;
71
+ throw err;
72
+ }
73
+ throw new Error(`Invalid MCP response: ${JSON.stringify(response)}`);
74
+ }
75
+ // High-level MCP methods
76
+ async listTools() {
77
+ const res = await this.sendRpc('tools/list');
78
+ return res?.tools ?? res;
79
+ }
80
+ async callTool(toolName, args = {}) {
81
+ return this.sendRpc('tools/call', { name: toolName, arguments: args });
82
+ }
83
+ async listResources() {
84
+ return this.sendRpc('resources/list');
85
+ }
86
+ async readResource(uri) {
87
+ return this.sendRpc('resources/read', { uri });
88
+ }
89
+ async listPrompts() {
90
+ return this.sendRpc('prompts/list');
91
+ }
92
+ async getPrompt(name, args = {}) {
93
+ return this.sendRpc('prompts/get', { name, arguments: args });
94
+ }
95
+ async ping() {
96
+ return this.sendRpc('ping');
97
+ }
98
+ }
99
+ //# sourceMappingURL=McpSimpleHttpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpSimpleHttpClient.js","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpSimpleHttpClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * MCP SSE Client for testing (improved)
3
+ *
4
+ * Keeps a single long-lived SSE connection for receiving responses
5
+ * and sends JSON-RPC requests as separate HTTP POSTs to /rpc.
6
+ * Supports routing by id and per-operation timeouts.
7
+ */
8
+ export declare class McpSseClient {
9
+ private readonly baseUrl;
10
+ private readonly customHeaders;
11
+ private requestId;
12
+ private sseAbort?;
13
+ private sseReaderTask?;
14
+ private connected;
15
+ private pending;
16
+ constructor(baseUrl: string, customHeaders?: Record<string, string>);
17
+ /** Public API: close SSE and reject all pending */
18
+ close(): Promise<void>;
19
+ /** Ensure SSE stream established */
20
+ private ensureConnected;
21
+ /** Open SSE stream via fetch and start reader loop */
22
+ private connect;
23
+ /** Parse SSE stream and dispatch messages by JSON-RPC id */
24
+ private readSseLoop;
25
+ /** Handle one SSE event block (multiple lines). Parse data: lines only */
26
+ private handleSseEvent;
27
+ /**
28
+ * Send JSON-RPC request over HTTP; await response via SSE stream
29
+ */
30
+ sendRequest(method: string, params?: Record<string, any>): Promise<any>;
31
+ listTools(): Promise<any>;
32
+ callTool(toolName: string, parameters?: {}): Promise<any>;
33
+ listResources(): Promise<any>;
34
+ readResource(uri: string): Promise<any>;
35
+ listPrompts(): Promise<any>;
36
+ getPrompt(name: string, args?: Record<string, any>): Promise<any>;
37
+ ping(): Promise<any>;
38
+ health(): Promise<unknown>;
39
+ }
40
+ //# sourceMappingURL=McpSseClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpSseClient.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpSseClient.ts"],"names":[],"mappings":"AAWA;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,QAAQ,CAAC,CAA8B;IAC/C,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,OAAO,CAKV;gBAEQ,OAAO,EAAE,MAAM,EAAE,aAAa,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAMxE,mDAAmD;IAC7C,KAAK;IAkBX,oCAAoC;YACtB,eAAe;IAO7B,sDAAsD;YACxC,OAAO;IAqCrB,4DAA4D;YAC9C,WAAW;IAgCzB,0EAA0E;IAC1E,OAAO,CAAC,cAAc;IAkEtB;;OAEG;IACG,WAAW,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAsC5E,SAAS;IAKT,QAAQ,CAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,KAAK;IAO3C,aAAa;IAKb,YAAY,CAAE,GAAG,EAAE,MAAM;IAIzB,WAAW;IAKX,SAAS,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAIvD,IAAI;IAIJ,MAAM;CAIb"}
@@ -0,0 +1,259 @@
1
+ import { getJsonFromResult } from '../../index.js';
2
+ async function safeReadText(res) {
3
+ try {
4
+ const text = await res.text();
5
+ return text?.slice(0, 1000);
6
+ }
7
+ catch {
8
+ return undefined;
9
+ }
10
+ }
11
+ /**
12
+ * MCP SSE Client for testing (improved)
13
+ *
14
+ * Keeps a single long-lived SSE connection for receiving responses
15
+ * and sends JSON-RPC requests as separate HTTP POSTs to /rpc.
16
+ * Supports routing by id and per-operation timeouts.
17
+ */
18
+ export class McpSseClient {
19
+ baseUrl;
20
+ customHeaders;
21
+ requestId;
22
+ // SSE connection state
23
+ sseAbort;
24
+ sseReaderTask;
25
+ connected = false;
26
+ // pending requests awaiting response by id
27
+ pending = new Map();
28
+ constructor(baseUrl, customHeaders = {}) {
29
+ this.baseUrl = baseUrl.replace(/\/$/, '');
30
+ this.customHeaders = customHeaders;
31
+ this.requestId = 1;
32
+ }
33
+ /** Public API: close SSE and reject all pending */
34
+ async close() {
35
+ this.connected = false;
36
+ if (this.sseAbort) {
37
+ this.sseAbort.abort();
38
+ this.sseAbort = undefined;
39
+ }
40
+ // Reject all pending
41
+ const err = new Error('MCP SSE client closed');
42
+ for (const [id, entry] of this.pending.entries()) {
43
+ clearTimeout(entry.timeout);
44
+ entry.reject(err);
45
+ this.pending.delete(id);
46
+ }
47
+ // Wait reader to finish
48
+ await this.sseReaderTask?.catch(() => {
49
+ });
50
+ }
51
+ /** Ensure SSE stream established */
52
+ async ensureConnected() {
53
+ if (this.connected) {
54
+ return;
55
+ }
56
+ await this.connect();
57
+ }
58
+ /** Open SSE stream via fetch and start reader loop */
59
+ async connect() {
60
+ if (this.connected) {
61
+ return;
62
+ }
63
+ const headers = {
64
+ Accept: 'text/event-stream',
65
+ ...this.customHeaders,
66
+ };
67
+ this.sseAbort = new AbortController();
68
+ const url = `${this.baseUrl}/sse`;
69
+ const res = await fetch(url, {
70
+ method: 'GET',
71
+ headers,
72
+ signal: this.sseAbort.signal,
73
+ });
74
+ if (!res.ok || !res.body) {
75
+ const text = await safeReadText(res);
76
+ throw new Error(`Failed to open SSE stream: ${res.status} ${res.statusText}${text ? ' - ' + text : ''}`);
77
+ }
78
+ this.connected = true;
79
+ this.sseReaderTask = this.readSseLoop(res.body);
80
+ // detach errors to console but keep state clean
81
+ this.sseReaderTask.catch(err => {
82
+ this.connected = false;
83
+ // Reject all pending on fatal SSE error
84
+ for (const [id, entry] of this.pending.entries()) {
85
+ clearTimeout(entry.timeout);
86
+ entry.reject(err);
87
+ this.pending.delete(id);
88
+ }
89
+ });
90
+ }
91
+ /** Parse SSE stream and dispatch messages by JSON-RPC id */
92
+ async readSseLoop(body) {
93
+ const reader = body.getReader();
94
+ const decoder = new TextDecoder('utf-8');
95
+ let buffer = '';
96
+ try {
97
+ while (true) {
98
+ const { value, done } = await reader.read();
99
+ if (done) {
100
+ break;
101
+ }
102
+ buffer += decoder.decode(value, { stream: true });
103
+ // SSE events are separated by double newline
104
+ let idx;
105
+ while ((idx = buffer.indexOf('\n\n')) !== -1) {
106
+ const rawEvent = buffer.slice(0, idx);
107
+ buffer = buffer.slice(idx + 2);
108
+ this.handleSseEvent(rawEvent);
109
+ }
110
+ }
111
+ }
112
+ finally {
113
+ // flush tail
114
+ const tail = decoder.decode();
115
+ if (tail) {
116
+ buffer += tail;
117
+ }
118
+ if (buffer.trim()) {
119
+ this.handleSseEvent(buffer);
120
+ }
121
+ this.connected = false;
122
+ }
123
+ }
124
+ /** Handle one SSE event block (multiple lines). Parse data: lines only */
125
+ handleSseEvent(eventBlock) {
126
+ // eventBlock may contain comments ": ..." and other fields
127
+ const lines = eventBlock.split(/\r?\n/);
128
+ let dataLines = [];
129
+ for (const line of lines) {
130
+ if (!line) {
131
+ continue;
132
+ }
133
+ if (line.startsWith(':')) {
134
+ continue;
135
+ } // comment/keepalive
136
+ if (line.startsWith('data:')) {
137
+ dataLines.push(line.slice(5).trimStart());
138
+ }
139
+ // we ignore id:, event:, retry: for now (not required for simple tests)
140
+ }
141
+ if (dataLines.length === 0) {
142
+ return;
143
+ }
144
+ const dataStr = dataLines.join('\n');
145
+ let payload;
146
+ try {
147
+ payload = JSON.parse(dataStr);
148
+ }
149
+ catch {
150
+ // non-JSON data frames are ignored in tests
151
+ return;
152
+ }
153
+ const id = payload?.id;
154
+ if (id == null) {
155
+ // broadcast/notification — ignore in this test client
156
+ return;
157
+ }
158
+ const pending = this.pending.get(id);
159
+ if (!pending) {
160
+ // late/unknown id — ignore silently for tests
161
+ return;
162
+ }
163
+ clearTimeout(pending.timeout);
164
+ this.pending.delete(id);
165
+ if (payload.error) {
166
+ const errorMessage = payload.error?.message || 'Unknown error';
167
+ // In test environment, log validation errors but don't crash
168
+ if (errorMessage.includes('invalid_type')) {
169
+ console.log(` ⚠️ Parameter validation error: ${errorMessage}`);
170
+ pending.resolve({
171
+ result: null,
172
+ requestHeaders: this.customHeaders,
173
+ });
174
+ return;
175
+ }
176
+ const err = new Error(`MCP Error: ${errorMessage}`);
177
+ err.data = payload.error?.data;
178
+ err.fullMcpResponse = payload;
179
+ pending.reject(err);
180
+ }
181
+ else {
182
+ const res = getJsonFromResult(payload.result);
183
+ if (res?.message) {
184
+ console.log(' message:', res.message);
185
+ }
186
+ pending.resolve({
187
+ result: payload.result,
188
+ requestHeaders: this.customHeaders,
189
+ });
190
+ }
191
+ }
192
+ /**
193
+ * Send JSON-RPC request over HTTP; await response via SSE stream
194
+ */
195
+ async sendRequest(method, params = {}) {
196
+ await this.ensureConnected();
197
+ const id = this.requestId++;
198
+ const request = { jsonrpc: '2.0', id, method, params };
199
+ // Prepare promise and timeout
200
+ const opTimeoutMs = 30000;
201
+ let timeoutRef;
202
+ const promise = new Promise((resolve, reject) => {
203
+ timeoutRef = setTimeout(() => {
204
+ this.pending.delete(id);
205
+ reject(new Error(`Request timeout for method: ${method}`));
206
+ }, opTimeoutMs);
207
+ this.pending.set(id, { resolve, reject, timeout: timeoutRef, method });
208
+ });
209
+ // Fire-and-wait: POST to /sse
210
+ const headers = {
211
+ 'Content-Type': 'application/json',
212
+ ...this.customHeaders,
213
+ };
214
+ const res = await fetch(`${this.baseUrl}/sse`, {
215
+ method: 'POST',
216
+ headers,
217
+ body: JSON.stringify(request),
218
+ });
219
+ if (!res.ok) {
220
+ clearTimeout(timeoutRef);
221
+ this.pending.delete(id);
222
+ const text = await safeReadText(res);
223
+ throw new Error(`RPC send failed: ${res.status} ${res.statusText}${text ? ' - ' + text : ''}`);
224
+ }
225
+ return promise;
226
+ }
227
+ async listTools() {
228
+ const { result } = await this.sendRequest('tools/list');
229
+ return result;
230
+ }
231
+ async callTool(toolName, parameters = {}) {
232
+ return this.sendRequest('tools/call', {
233
+ name: toolName,
234
+ arguments: parameters,
235
+ });
236
+ }
237
+ async listResources() {
238
+ const { result } = await this.sendRequest('resources/list');
239
+ return result;
240
+ }
241
+ async readResource(uri) {
242
+ return this.sendRequest('resources/read', { uri });
243
+ }
244
+ async listPrompts() {
245
+ const { result } = await this.sendRequest('prompts/list');
246
+ return result;
247
+ }
248
+ async getPrompt(name, args = {}) {
249
+ return this.sendRequest('prompts/get', { name, arguments: args });
250
+ }
251
+ async ping() {
252
+ return this.sendRequest('ping');
253
+ }
254
+ async health() {
255
+ const response = await fetch(`${this.baseUrl}/health`);
256
+ return response.json();
257
+ }
258
+ }
259
+ //# sourceMappingURL=McpSseClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpSseClient.js","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpSseClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import '../../bootstrap/dotenv.js';
2
+ import { ChildProcess } from 'child_process';
3
+ export declare class McpStdioClient {
4
+ private proc;
5
+ private nextId;
6
+ private pending;
7
+ private buffer;
8
+ constructor(proc: ChildProcess);
9
+ processLines(): void;
10
+ send(method: string, params?: {}, timeoutMs?: number): Promise<unknown>;
11
+ listTools(): Promise<unknown>;
12
+ callTool(name: string, args?: Record<string, any>): Promise<unknown>;
13
+ listResources(): Promise<unknown>;
14
+ readResource(uri: string): Promise<unknown>;
15
+ listPrompts(): Promise<unknown>;
16
+ getPrompt(name: string, args?: Record<string, any>): Promise<unknown>;
17
+ }
18
+ //# sourceMappingURL=McpStdioClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpStdioClient.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpStdioClient.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAY7C,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,MAAM,CAAS;gBAEV,IAAI,EAAE,YAAY;IAqB/B,YAAY;IA+BZ,IAAI,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,EAAE,SAAS,SAAQ;IAqBpD,SAAS;IAIT,QAAQ,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAItD,aAAa;IAIb,YAAY,CAAE,GAAG,EAAE,MAAM;IAIzB,WAAW;IAIX,SAAS,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;CAGxD"}
@@ -0,0 +1,102 @@
1
+ import '../../bootstrap/dotenv.js';
2
+ import chalk from 'chalk';
3
+ const SHOW_IN = process.env.TEST_SHOW_IN === 'true';
4
+ const SHOW_OUT = process.env.TEST_SHOW_OUT === 'true';
5
+ const SHOW_ERR = process.env.TEST_SHOW_ERR === 'true';
6
+ export class McpStdioClient {
7
+ proc;
8
+ nextId;
9
+ pending;
10
+ buffer;
11
+ constructor(proc) {
12
+ this.proc = proc;
13
+ this.nextId = 1;
14
+ this.pending = new Map();
15
+ this.buffer = '';
16
+ if (this.proc.stdout) {
17
+ this.proc.stdout.on('data', (chunk) => {
18
+ this.buffer += chunk.toString();
19
+ this.processLines();
20
+ });
21
+ }
22
+ if (this.proc.stderr) {
23
+ this.proc.stderr.on('data', (data) => {
24
+ if (SHOW_ERR) {
25
+ console.error(chalk.gray(String(data)));
26
+ }
27
+ });
28
+ }
29
+ }
30
+ processLines() {
31
+ const lines = this.buffer.split('\n');
32
+ this.buffer = lines.pop() || '';
33
+ for (const line of lines) {
34
+ const s = line.trim();
35
+ if (!s) {
36
+ continue;
37
+ }
38
+ try {
39
+ const msg = JSON.parse(s);
40
+ if (SHOW_IN) {
41
+ console.log(chalk.bgYellow('IN ') + s);
42
+ }
43
+ if (typeof msg.id === 'number' && (msg.result !== undefined || msg.error)) {
44
+ const p = this.pending.get(msg.id);
45
+ if (p) {
46
+ clearTimeout(p.t);
47
+ this.pending.delete(msg.id);
48
+ if (msg.error) {
49
+ p.reject(new Error(msg.error?.message || 'MCP Error'));
50
+ }
51
+ else {
52
+ p.resolve(msg.result);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ catch {
58
+ // ignore parse errors
59
+ }
60
+ }
61
+ }
62
+ send(method, params = {}, timeoutMs = 15000) {
63
+ const id = this.nextId++;
64
+ const req = { jsonrpc: '2.0', id, method, params };
65
+ const text = JSON.stringify(req) + '\n';
66
+ if (SHOW_OUT) {
67
+ console.log(chalk.bgBlue('OUT') + ' ' + text.trim());
68
+ }
69
+ if (this.proc.stdin) {
70
+ this.proc.stdin.write(text);
71
+ }
72
+ else {
73
+ throw new Error('Process stdin is not available');
74
+ }
75
+ return new Promise((resolve, reject) => {
76
+ const t = setTimeout(() => {
77
+ this.pending.delete(id);
78
+ reject(new Error(`Timeout for ${method}`));
79
+ }, timeoutMs);
80
+ this.pending.set(id, { resolve, reject, t });
81
+ });
82
+ }
83
+ listTools() {
84
+ return this.send('tools/list');
85
+ }
86
+ callTool(name, args = {}) {
87
+ return this.send('tools/call', { name, arguments: args });
88
+ }
89
+ listResources() {
90
+ return this.send('resources/list');
91
+ }
92
+ readResource(uri) {
93
+ return this.send('resources/read', { uri });
94
+ }
95
+ listPrompts() {
96
+ return this.send('prompts/list');
97
+ }
98
+ getPrompt(name, args = {}) {
99
+ return this.send('prompts/get', { name, arguments: args });
100
+ }
101
+ }
102
+ //# sourceMappingURL=McpStdioClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpStdioClient.js","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpStdioClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ type Json = any;
2
+ /**
3
+ * MCP Streamable HTTP Client
4
+ *
5
+ * Supports a long-lived connection over HTTP (NDJSON),
6
+ * multiple requests/responses and incoming notifications.
7
+ */
8
+ export declare class McpStreamableHttpClient {
9
+ private readonly baseUrl;
10
+ private readonly endpointPath;
11
+ private readonly customHeaders;
12
+ private readonly requestTimeoutMs;
13
+ private encoder;
14
+ private decoder;
15
+ private controller;
16
+ private outgoing;
17
+ private response;
18
+ private reader;
19
+ private abort;
20
+ private readLoopPromise;
21
+ private nextId;
22
+ private pending;
23
+ private notifications;
24
+ serverInfo?: {
25
+ name: string;
26
+ version: string;
27
+ };
28
+ capabilities?: any;
29
+ protocolVersion?: string;
30
+ constructor(baseUrl: string, options?: {
31
+ endpointPath?: string;
32
+ headers?: Record<string, string>;
33
+ requestTimeoutMs?: number;
34
+ });
35
+ onNotification(method: string, handler: (params: any) => void): () => boolean;
36
+ private emitNotification;
37
+ connect(): Promise<void>;
38
+ initialize(params?: {
39
+ protocolVersion?: string;
40
+ capabilities?: any;
41
+ clientInfo?: {
42
+ name: string;
43
+ version: string;
44
+ };
45
+ }): Promise<any>;
46
+ close(): Promise<void>;
47
+ private cleanup;
48
+ private readLoop;
49
+ private routeIncoming;
50
+ private writeNdjson;
51
+ notify(method: string, params?: Json): void;
52
+ sendRpc<T = any>(method: string, params?: Json, timeoutMs?: number): Promise<T>;
53
+ listTools(): Promise<any>;
54
+ callTool(toolName: string, parameters?: Record<string, any>): Promise<any>;
55
+ listResources(): Promise<any>;
56
+ readResource(uri: string): Promise<any>;
57
+ listPrompts(): Promise<any>;
58
+ getPrompt(name: string, arguments_?: Record<string, any>): Promise<any>;
59
+ ping(): Promise<any>;
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=McpStreamableHttpClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpStreamableHttpClient.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpStreamableHttpClient.ts"],"names":[],"mappings":"AAAA,KAAK,IAAI,GAAG,GAAG,CAAC;AA6BhB;;;;;GAKG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,MAAM,CAAsD;IACpE,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,eAAe,CAA4B;IAEnD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAA2F;IAC1G,OAAO,CAAC,aAAa,CAAiD;IAE/D,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QACtC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B;IAOD,cAAc,CAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI;IAM9D,OAAO,CAAC,gBAAgB;IAWlB,OAAO;IAsCP,UAAU,CAAE,MAAM,GAAE;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,GAAG,CAAC;QACnB,UAAU,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3C;IAYA,KAAK;IAyBX,OAAO,CAAC,OAAO;YAOD,QAAQ;IAwBtB,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,WAAW;IAKnB,MAAM,CAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI;IAK/B,OAAO,CAAC,CAAC,GAAG,GAAG,EAAG,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,SAAwB,GAAG,OAAO,CAAC,CAAC,CAAC;IAgB/F,SAAS;IAKT,QAAQ,CAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAIhE,aAAa;IAIb,YAAY,CAAE,GAAG,EAAE,MAAM;IAIzB,WAAW;IAIX,SAAS,CAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAI7D,IAAI;CAGX"}