@aria-cli/tools 1.0.9 → 1.0.11

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 (241) hide show
  1. package/package.json +9 -5
  2. package/src/__tests__/web-fetch-download.test.ts +0 -433
  3. package/src/__tests__/web-tools.test.ts +0 -619
  4. package/src/ask-user-interaction.ts +0 -33
  5. package/src/cache/web-cache.ts +0 -110
  6. package/src/definitions/arion.ts +0 -118
  7. package/src/definitions/browser/browser.ts +0 -502
  8. package/src/definitions/browser/index.ts +0 -5
  9. package/src/definitions/browser/pw-downloads.ts +0 -142
  10. package/src/definitions/browser/pw-interactions.ts +0 -282
  11. package/src/definitions/browser/pw-responses.ts +0 -98
  12. package/src/definitions/browser/pw-session.ts +0 -405
  13. package/src/definitions/browser/pw-shared.ts +0 -85
  14. package/src/definitions/browser/pw-snapshot.ts +0 -383
  15. package/src/definitions/browser/pw-state.ts +0 -101
  16. package/src/definitions/browser/types.ts +0 -203
  17. package/src/definitions/code-intelligence.ts +0 -526
  18. package/src/definitions/core.ts +0 -118
  19. package/src/definitions/delegation.ts +0 -567
  20. package/src/definitions/deploy.ts +0 -73
  21. package/src/definitions/filesystem.ts +0 -217
  22. package/src/definitions/frg.ts +0 -67
  23. package/src/definitions/index.ts +0 -28
  24. package/src/definitions/memory.ts +0 -150
  25. package/src/definitions/messaging.ts +0 -734
  26. package/src/definitions/meta.ts +0 -392
  27. package/src/definitions/network.ts +0 -179
  28. package/src/definitions/outlook.ts +0 -318
  29. package/src/definitions/patch/apply-patch.ts +0 -235
  30. package/src/definitions/patch/fuzzy-match.ts +0 -217
  31. package/src/definitions/patch/index.ts +0 -1
  32. package/src/definitions/patch/patch-parser.ts +0 -297
  33. package/src/definitions/patch/sandbox-paths.ts +0 -129
  34. package/src/definitions/process/index.ts +0 -5
  35. package/src/definitions/process/process-registry.ts +0 -303
  36. package/src/definitions/process/process.ts +0 -456
  37. package/src/definitions/process/pty-keys.ts +0 -298
  38. package/src/definitions/process/session-slug.ts +0 -147
  39. package/src/definitions/quip.ts +0 -225
  40. package/src/definitions/search.ts +0 -67
  41. package/src/definitions/session-history.ts +0 -79
  42. package/src/definitions/shell.ts +0 -202
  43. package/src/definitions/slack.ts +0 -211
  44. package/src/definitions/web.ts +0 -119
  45. package/src/executors/apply-patch.ts +0 -1035
  46. package/src/executors/arion.ts +0 -199
  47. package/src/executors/code-intelligence.ts +0 -1179
  48. package/src/executors/deploy.ts +0 -1066
  49. package/src/executors/filesystem.ts +0 -1428
  50. package/src/executors/frg-freshness.ts +0 -743
  51. package/src/executors/frg.ts +0 -394
  52. package/src/executors/index.ts +0 -280
  53. package/src/executors/learning-meta.ts +0 -1367
  54. package/src/executors/lsp-client.ts +0 -355
  55. package/src/executors/memory.ts +0 -978
  56. package/src/executors/meta.ts +0 -293
  57. package/src/executors/process-registry.ts +0 -570
  58. package/src/executors/pty-session-store.ts +0 -43
  59. package/src/executors/pty.ts +0 -342
  60. package/src/executors/restart.ts +0 -133
  61. package/src/executors/search-freshness.ts +0 -249
  62. package/src/executors/search-types.ts +0 -98
  63. package/src/executors/search.ts +0 -89
  64. package/src/executors/self-diagnose.ts +0 -552
  65. package/src/executors/session-history.ts +0 -435
  66. package/src/executors/shell-safety.ts +0 -519
  67. package/src/executors/shell.ts +0 -1243
  68. package/src/executors/utils.ts +0 -40
  69. package/src/executors/web.ts +0 -786
  70. package/src/extraction/content-extraction.ts +0 -281
  71. package/src/extraction/index.ts +0 -5
  72. package/src/headless-control-contract.ts +0 -1149
  73. package/src/index.ts +0 -788
  74. package/src/local-control-http-auth.ts +0 -2
  75. package/src/mcp/client.ts +0 -218
  76. package/src/mcp/connection.ts +0 -568
  77. package/src/mcp/index.ts +0 -11
  78. package/src/mcp/jsonrpc.ts +0 -195
  79. package/src/mcp/types.ts +0 -199
  80. package/src/network-control-adapter.ts +0 -88
  81. package/src/network-runtime/address-types.ts +0 -218
  82. package/src/network-runtime/db-owner-fencing.ts +0 -91
  83. package/src/network-runtime/delivery-receipts.ts +0 -372
  84. package/src/network-runtime/direct-endpoint-authority.ts +0 -35
  85. package/src/network-runtime/index.ts +0 -316
  86. package/src/network-runtime/local-control-contract.ts +0 -784
  87. package/src/network-runtime/node-store-contract.ts +0 -46
  88. package/src/network-runtime/pair-route-contract.ts +0 -97
  89. package/src/network-runtime/peer-capabilities.ts +0 -48
  90. package/src/network-runtime/peer-principal-ref.ts +0 -20
  91. package/src/network-runtime/peer-state-machine.ts +0 -160
  92. package/src/network-runtime/protocol-schemas.ts +0 -265
  93. package/src/network-runtime/runtime-bootstrap-contract.ts +0 -83
  94. package/src/outlook/desktop-session.ts +0 -409
  95. package/src/policy.ts +0 -171
  96. package/src/providers/brave.ts +0 -80
  97. package/src/providers/duckduckgo.ts +0 -199
  98. package/src/providers/exa.ts +0 -85
  99. package/src/providers/firecrawl.ts +0 -77
  100. package/src/providers/index.ts +0 -8
  101. package/src/providers/jina.ts +0 -70
  102. package/src/providers/router.ts +0 -121
  103. package/src/providers/search-provider.ts +0 -74
  104. package/src/providers/tavily.ts +0 -74
  105. package/src/quip/desktop-session.ts +0 -435
  106. package/src/registry/index.ts +0 -1
  107. package/src/registry/registry.ts +0 -905
  108. package/src/runtime-socket-local-control-client.ts +0 -632
  109. package/src/security/dns-normalization.ts +0 -34
  110. package/src/security/dns-pinning.ts +0 -138
  111. package/src/security/external-content.ts +0 -129
  112. package/src/security/ssrf.ts +0 -207
  113. package/src/slack/desktop-session.ts +0 -493
  114. package/src/tool-factory.ts +0 -91
  115. package/src/types.ts +0 -1341
  116. package/src/utils/retry.ts +0 -163
  117. package/src/utils/safe-parse-json.ts +0 -176
  118. package/src/utils/url.ts +0 -20
  119. package/tests/benchmarks/registry.bench.ts +0 -57
  120. package/tests/cache/web-cache.test.ts +0 -147
  121. package/tests/critical-integration.test.ts +0 -1465
  122. package/tests/definitions/apply-patch.test.ts +0 -586
  123. package/tests/definitions/browser.test.ts +0 -495
  124. package/tests/definitions/delegation-pause-resume.test.ts +0 -758
  125. package/tests/definitions/execution.test.ts +0 -671
  126. package/tests/definitions/messaging-inbox-scope.test.ts +0 -229
  127. package/tests/definitions/messaging.test.ts +0 -1468
  128. package/tests/definitions/outlook.test.ts +0 -30
  129. package/tests/definitions/process.test.ts +0 -469
  130. package/tests/definitions/slack.test.ts +0 -28
  131. package/tests/definitions/tool-inventory.test.ts +0 -218
  132. package/tests/e2e/delegation-quest-orchestration.e2e.test.ts +0 -433
  133. package/tests/e2e/memory-tool-discovery-contract.e2e.test.ts +0 -81
  134. package/tests/executors/apply-patch.test.ts +0 -538
  135. package/tests/executors/arion.test.ts +0 -309
  136. package/tests/executors/conversation-primitives.test.ts +0 -250
  137. package/tests/executors/deploy.test.ts +0 -746
  138. package/tests/executors/filesystem-tools.test.ts +0 -357
  139. package/tests/executors/filesystem.test.ts +0 -959
  140. package/tests/executors/frg-freshness.test.ts +0 -136
  141. package/tests/executors/frg-merge.test.ts +0 -70
  142. package/tests/executors/frg-session-content.test.ts +0 -40
  143. package/tests/executors/frg.test.ts +0 -56
  144. package/tests/executors/memory-bugfixes.test.ts +0 -257
  145. package/tests/executors/memory-real-memoria.integration.test.ts +0 -316
  146. package/tests/executors/memory.test.ts +0 -853
  147. package/tests/executors/meta-tools.test.ts +0 -411
  148. package/tests/executors/meta.test.ts +0 -683
  149. package/tests/executors/path-containment.test.ts +0 -51
  150. package/tests/executors/process-registry.test.ts +0 -505
  151. package/tests/executors/pty.test.ts +0 -664
  152. package/tests/executors/quest-security.test.ts +0 -249
  153. package/tests/executors/read-file-media.test.ts +0 -230
  154. package/tests/executors/recall-knowledge-schema.test.ts +0 -209
  155. package/tests/executors/recall-tags.test.ts +0 -278
  156. package/tests/executors/remember-null-safety.contract.test.ts +0 -41
  157. package/tests/executors/restart.test.ts +0 -67
  158. package/tests/executors/search-unified.test.ts +0 -381
  159. package/tests/executors/session-history.test.ts +0 -340
  160. package/tests/executors/session-transcript.test.ts +0 -561
  161. package/tests/executors/shell-abort.test.ts +0 -416
  162. package/tests/executors/shell-env-blocklist.test.ts +0 -648
  163. package/tests/executors/shell-env-process.test.ts +0 -245
  164. package/tests/executors/shell-process-registry.test.ts +0 -334
  165. package/tests/executors/shell-tools.test.ts +0 -393
  166. package/tests/executors/shell.test.ts +0 -690
  167. package/tests/executors/web-abort-vs-timeout.test.ts +0 -213
  168. package/tests/executors/web-integration.test.ts +0 -633
  169. package/tests/executors/web-symlink.test.ts +0 -18
  170. package/tests/executors/web.test.ts +0 -1400
  171. package/tests/executors/write-stdin.test.ts +0 -145
  172. package/tests/extraction/content-extraction.test.ts +0 -153
  173. package/tests/guards/tools-default-test-lane.integration.test.ts +0 -21
  174. package/tests/guards/tools-package-test-commands.e2e.test.ts +0 -43
  175. package/tests/guards/tools-test-lane-manifest.contract.test.ts +0 -76
  176. package/tests/guards/tools-vitest-workspace-alias.contract.test.ts +0 -63
  177. package/tests/helpers/async-waits.ts +0 -53
  178. package/tests/integration/headless-control-contract.integration.test.ts +0 -153
  179. package/tests/integration/memory-tool-schema-parity.integration.test.ts +0 -67
  180. package/tests/integration/meta-tools-round-trip.integration.test.ts +0 -506
  181. package/tests/integration/quest-round-trip.test.ts +0 -303
  182. package/tests/integration/registry-executor-flow.test.ts +0 -85
  183. package/tests/integration.test.ts +0 -177
  184. package/tests/loading-tier.test.ts +0 -126
  185. package/tests/mcp/client-reconnect.test.ts +0 -267
  186. package/tests/mcp/connection.test.ts +0 -846
  187. package/tests/mcp/injectable-logger.test.ts +0 -83
  188. package/tests/mcp/jsonrpc.test.ts +0 -109
  189. package/tests/mcp/lifecycle.test.ts +0 -879
  190. package/tests/network-runtime/address-types.contract.test.ts +0 -143
  191. package/tests/network-runtime/continuity-bind-schema.contract.test.ts +0 -203
  192. package/tests/network-runtime/local-control-contract.test.ts +0 -869
  193. package/tests/network-runtime/local-control-invite-token.contract.test.ts +0 -146
  194. package/tests/network-runtime/node-store-contract.test.ts +0 -11
  195. package/tests/network-runtime/pair-protocol-nodeid.contract.test.ts +0 -15
  196. package/tests/network-runtime/peer-state-machine.contract.test.ts +0 -148
  197. package/tests/network-runtime/protocol-schemas.contract.test.ts +0 -512
  198. package/tests/network-runtime/relay-pending-nodeid.contract.test.ts +0 -62
  199. package/tests/network-runtime/runtime-bootstrap-contract.test.ts +0 -227
  200. package/tests/network-runtime/runtime-socket-local-control-client.test.ts +0 -621
  201. package/tests/network-runtime/wait-for-message-script.test.ts +0 -288
  202. package/tests/parallel.test.ts +0 -71
  203. package/tests/policy.test.ts +0 -184
  204. package/tests/print-default-test-lane.ts +0 -14
  205. package/tests/print-test-lane-manifest.ts +0 -22
  206. package/tests/providers/brave.test.ts +0 -159
  207. package/tests/providers/duckduckgo.test.ts +0 -207
  208. package/tests/providers/exa.test.ts +0 -175
  209. package/tests/providers/firecrawl.test.ts +0 -168
  210. package/tests/providers/jina.test.ts +0 -144
  211. package/tests/providers/router.test.ts +0 -328
  212. package/tests/providers/tavily.test.ts +0 -165
  213. package/tests/registry/discovery.test.ts +0 -154
  214. package/tests/registry/injectable-logger.test.ts +0 -230
  215. package/tests/registry/input-validation.test.ts +0 -361
  216. package/tests/registry/interface-completeness.test.ts +0 -85
  217. package/tests/registry/mcp-integration.test.ts +0 -103
  218. package/tests/registry/mcp-read-only-hint.test.ts +0 -60
  219. package/tests/registry/memoria-discovery.test.ts +0 -390
  220. package/tests/registry/nested-validation.test.ts +0 -283
  221. package/tests/registry/pseudo-tool-filtering.test.ts +0 -258
  222. package/tests/registry/registration-lifecycle.test.ts +0 -133
  223. package/tests/registry-validation.test.ts +0 -424
  224. package/tests/registry.test.ts +0 -460
  225. package/tests/security/dns-pinning.test.ts +0 -162
  226. package/tests/security/external-content.test.ts +0 -144
  227. package/tests/security/ssrf.test.ts +0 -118
  228. package/tests/shell-safety-integration.test.ts +0 -32
  229. package/tests/shell-safety.test.ts +0 -365
  230. package/tests/slack/desktop-session.test.ts +0 -50
  231. package/tests/test-lane-manifest.ts +0 -440
  232. package/tests/test-utils.ts +0 -27
  233. package/tests/tool-factory.test.ts +0 -188
  234. package/tests/utils/retry.test.ts +0 -231
  235. package/tests/utils/url.test.ts +0 -63
  236. package/tsconfig.cjs.json +0 -24
  237. package/tsconfig.json +0 -12
  238. package/vitest.config.ts +0 -55
  239. package/vitest.e2e.config.ts +0 -24
  240. package/vitest.integration.config.ts +0 -24
  241. package/vitest.native.config.ts +0 -24
@@ -1,568 +0,0 @@
1
- /**
2
- * MCP Server Connection
3
- *
4
- * Manages lifecycle and protocol methods for a single MCP server.
5
- */
6
-
7
- import type { ChildProcess } from "child_process";
8
- import { spawn } from "child_process";
9
- import { EventEmitter } from "events";
10
- import { PassThrough, Writable } from "stream";
11
- import { JSONRPCClient } from "./jsonrpc.js";
12
- import type {
13
- MCPServerConfig,
14
- MCPCapabilities,
15
- MCPInitializeResult,
16
- MCPTool,
17
- MCPToolCallResult,
18
- MCPResource,
19
- MCPResourceContent,
20
- MCPPrompt,
21
- MCPPromptMessage,
22
- } from "./types.js";
23
- import type { ToolResult } from "../types.js";
24
-
25
- function sanitizeGitEnv(
26
- env: NodeJS.ProcessEnv | Record<string, string | undefined> = process.env,
27
- ): Record<string, string> {
28
- const sanitized: Record<string, string> = {};
29
- for (const [key, value] of Object.entries(env)) {
30
- if (value === undefined) continue;
31
- if (key.toUpperCase().startsWith("GIT_")) continue;
32
- sanitized[key] = value;
33
- }
34
- return sanitized;
35
- }
36
-
37
- export class MCPServerConnection extends EventEmitter {
38
- private process?: ChildProcess;
39
- private transport: "stdio" | "sse" = "stdio";
40
- private rpc: JSONRPCClient;
41
- private capabilities: MCPCapabilities = {};
42
- private _initialized = false;
43
- private sseAbortController?: AbortController;
44
- private sseStreamPromise?: Promise<void>;
45
- private ssePostUrl?: string;
46
- private sseSessionId?: string;
47
- private sseOutput?: PassThrough;
48
-
49
- // Auto-reconnect state
50
- private _disconnecting = false;
51
- private _reconnecting = false;
52
- private _reconnectAttempts = 0;
53
-
54
- private static readonly RECONNECT_BASE_DELAY_MS = 1000;
55
- private static readonly RECONNECT_MAX_DELAY_MS = 30000;
56
- private static readonly RECONNECT_MAX_ATTEMPTS = 5;
57
-
58
- constructor(private config: MCPServerConfig) {
59
- super();
60
- this.rpc = new JSONRPCClient();
61
- }
62
-
63
- get name(): string {
64
- return this.config.name;
65
- }
66
-
67
- get initialized(): boolean {
68
- return this._initialized;
69
- }
70
-
71
- /**
72
- * Initialize connection to MCP server
73
- */
74
- async initialize(): Promise<MCPCapabilities> {
75
- // Reset disconnecting flag on fresh initialization so auto-reconnect is active.
76
- // During reconnect, attemptReconnect() checks _disconnecting before each attempt.
77
- if (!this._reconnecting) {
78
- this._disconnecting = false;
79
- this._reconnectAttempts = 0;
80
- }
81
-
82
- this.transport = this.config.transport ?? "stdio";
83
-
84
- try {
85
- if (this.transport === "stdio") {
86
- await this.initializeStdioTransport();
87
- } else {
88
- await this.initializeSSETransport();
89
- }
90
-
91
- // Forward notifications
92
- this.rpc.on("notifications/tools/list_changed", () => this.emit("tools/list_changed"));
93
- this.rpc.on("notifications/resources/list_changed", () =>
94
- this.emit("resources/list_changed"),
95
- );
96
- this.rpc.on("notifications/prompts/list_changed", () => this.emit("prompts/list_changed"));
97
-
98
- // MCP initialize handshake
99
- const result = await this.rpc.request<MCPInitializeResult>("initialize", {
100
- protocolVersion: "2024-11-05",
101
- capabilities: {
102
- roots: { listChanged: true },
103
- },
104
- clientInfo: {
105
- name: "aria-cli",
106
- version: "1.0.0",
107
- },
108
- });
109
-
110
- this.capabilities = result.capabilities || {};
111
- this._initialized = true;
112
-
113
- // Send initialized notification
114
- this.rpc.notify("notifications/initialized", {});
115
-
116
- return this.capabilities;
117
- } catch (error) {
118
- await this.cleanupAfterInitializeFailure();
119
- throw error;
120
- }
121
- }
122
-
123
- /**
124
- * Attempt to reconnect with exponential backoff.
125
- * Called when the transport drops unexpectedly (not via explicit shutdown).
126
- */
127
- private async attemptReconnect(): Promise<void> {
128
- if (this._disconnecting || this._reconnecting) {
129
- return;
130
- }
131
-
132
- this._reconnecting = true;
133
-
134
- while (
135
- this._reconnectAttempts < MCPServerConnection.RECONNECT_MAX_ATTEMPTS &&
136
- !this._disconnecting
137
- ) {
138
- this._reconnectAttempts++;
139
-
140
- const delay = Math.min(
141
- MCPServerConnection.RECONNECT_BASE_DELAY_MS * Math.pow(2, this._reconnectAttempts - 1),
142
- MCPServerConnection.RECONNECT_MAX_DELAY_MS,
143
- );
144
-
145
- this.emit("log", {
146
- level: "info",
147
- message: `Reconnect attempt ${this._reconnectAttempts}/${MCPServerConnection.RECONNECT_MAX_ATTEMPTS} in ${delay}ms`,
148
- });
149
-
150
- await new Promise((resolve) => setTimeout(resolve, delay));
151
-
152
- if (this._disconnecting) {
153
- break;
154
- }
155
-
156
- try {
157
- // Clean up stale RPC state before reconnecting
158
- this.rpc.close();
159
- this.rpc = new JSONRPCClient();
160
-
161
- await this.initialize();
162
-
163
- // Success — reset reconnect state
164
- this._reconnectAttempts = 0;
165
- this._reconnecting = false;
166
- this.emit("reconnected");
167
- return;
168
- } catch (error) {
169
- this.emit("log", {
170
- level: "error",
171
- message: `Reconnect attempt ${this._reconnectAttempts} failed: ${(error as Error).message}`,
172
- });
173
- }
174
- }
175
-
176
- // All attempts exhausted or disconnecting flag was set
177
- this._reconnecting = false;
178
- if (!this._disconnecting) {
179
- this._initialized = false;
180
- this.emit(
181
- "error",
182
- new Error(
183
- `Failed to reconnect after ${MCPServerConnection.RECONNECT_MAX_ATTEMPTS} attempts`,
184
- ),
185
- );
186
- }
187
- }
188
-
189
- private async initializeStdioTransport(): Promise<void> {
190
- if (!this.config.command) {
191
- throw new Error("Command required for stdio transport");
192
- }
193
-
194
- // Spawn server process
195
- this.process = spawn(this.config.command, this.config.args || [], {
196
- env: { ...sanitizeGitEnv(), ...sanitizeGitEnv(this.config.env ?? {}) },
197
- stdio: ["pipe", "pipe", "pipe"],
198
- });
199
-
200
- if (!this.process.stdin || !this.process.stdout) {
201
- throw new Error("Failed to create stdio streams");
202
- }
203
-
204
- this.rpc.connect(this.process.stdin, this.process.stdout);
205
-
206
- // Handle stderr for logging
207
- this.process.stderr?.on("data", (data) => {
208
- this.emit("log", { level: "error", message: data.toString() });
209
- });
210
-
211
- this.process.on("exit", (code) => {
212
- this._initialized = false;
213
- this.rpc.close();
214
- this.emit("exit", code);
215
-
216
- // Attempt auto-reconnect on unexpected exit
217
- if (!this._disconnecting) {
218
- void this.attemptReconnect();
219
- }
220
- });
221
- }
222
-
223
- private async initializeSSETransport(): Promise<void> {
224
- const url = this.config.url;
225
- if (!url) {
226
- throw new Error("URL required for sse transport");
227
- }
228
-
229
- const stdin = new Writable({
230
- write: (chunk, _encoding, callback) => {
231
- const payload = chunk.toString();
232
- this.postSSEMessages(payload)
233
- .then(() => callback())
234
- .catch((err) => callback(err as Error));
235
- },
236
- });
237
- const stdout = new PassThrough();
238
- this.sseOutput = stdout;
239
- this.rpc.connect(stdin, stdout);
240
-
241
- this.sseAbortController = new AbortController();
242
- const response = await fetch(url, {
243
- method: "GET",
244
- headers: { Accept: "text/event-stream" },
245
- signal: this.sseAbortController.signal,
246
- });
247
- if (!response.ok || !response.body) {
248
- const errorText = await response.text();
249
- throw new Error(
250
- `Failed to connect SSE transport: ${response.status} ${response.statusText} ${errorText}`,
251
- );
252
- }
253
-
254
- this.sseSessionId = response.headers.get("mcp-session-id") ?? undefined;
255
- this.ssePostUrl = url;
256
- this.sseStreamPromise = this.consumeSSE(response.body, url);
257
- }
258
-
259
- private async postSSEMessages(payload: string): Promise<void> {
260
- const trimmed = payload.trim();
261
- if (!trimmed) {
262
- return;
263
- }
264
-
265
- const endpoint = this.ssePostUrl || this.config.url;
266
- if (!endpoint) {
267
- throw new Error("SSE transport endpoint is not configured");
268
- }
269
-
270
- const messages = trimmed
271
- .split("\n")
272
- .map((line) => line.trim())
273
- .filter((line) => line.length > 0);
274
-
275
- for (const message of messages) {
276
- const response = await fetch(endpoint, {
277
- method: "POST",
278
- headers: {
279
- "Content-Type": "application/json",
280
- ...(this.sseSessionId ? { "mcp-session-id": this.sseSessionId } : {}),
281
- },
282
- body: message,
283
- });
284
-
285
- if (!response.ok) {
286
- const errorText = await response.text();
287
- throw new Error(
288
- `SSE transport POST failed: ${response.status} ${response.statusText} ${errorText}`,
289
- );
290
- }
291
-
292
- const responseText = (await response.text()).trim();
293
- if (!responseText || !this.sseOutput) {
294
- continue;
295
- }
296
-
297
- // Some servers return direct JSON-RPC responses on POST while others
298
- // publish responses only via SSE. Forward direct JSON replies into RPC.
299
- for (const line of responseText.split("\n")) {
300
- const jsonLine = line.trim();
301
- if (!jsonLine) {
302
- continue;
303
- }
304
- if (jsonLine.startsWith("{") && jsonLine.endsWith("}")) {
305
- this.sseOutput.write(`${jsonLine}\n`);
306
- }
307
- }
308
- }
309
- }
310
-
311
- private async consumeSSE(body: ReadableStream<Uint8Array>, baseUrl: string): Promise<void> {
312
- const reader = body.getReader();
313
- const decoder = new TextDecoder();
314
- let buffer = "";
315
- let eventType = "";
316
- let dataLines: string[] = [];
317
-
318
- const dispatch = (): void => {
319
- if (dataLines.length === 0) {
320
- eventType = "";
321
- return;
322
- }
323
-
324
- const data = dataLines.join("\n").trim();
325
- const event = eventType || "message";
326
- eventType = "";
327
- dataLines = [];
328
-
329
- if (!data) {
330
- return;
331
- }
332
-
333
- if (event === "endpoint") {
334
- this.ssePostUrl = new URL(data, baseUrl).toString();
335
- return;
336
- }
337
-
338
- if (!this.sseOutput) {
339
- return;
340
- }
341
-
342
- if (data.startsWith("{") && data.endsWith("}")) {
343
- this.sseOutput.write(`${data}\n`);
344
- }
345
- };
346
-
347
- try {
348
- while (true) {
349
- const { done, value } = await reader.read();
350
- if (done) {
351
- dispatch();
352
- break;
353
- }
354
-
355
- buffer += decoder.decode(value, { stream: true });
356
- const lines = buffer.split(/\r?\n/);
357
- buffer = lines.pop() || "";
358
-
359
- for (const line of lines) {
360
- if (line === "") {
361
- dispatch();
362
- continue;
363
- }
364
- if (line.startsWith("event:")) {
365
- eventType = line.slice(6).trim();
366
- continue;
367
- }
368
- if (line.startsWith("data:")) {
369
- dataLines.push(line.slice(5).trim());
370
- }
371
- }
372
- }
373
- } catch (error) {
374
- // Ignore abort errors from normal shutdown.
375
- if (!(error instanceof DOMException && error.name === "AbortError")) {
376
- this.emit("log", {
377
- level: "error",
378
- message: `SSE stream error: ${(error as Error).message}`,
379
- });
380
- }
381
- } finally {
382
- if (this._initialized) {
383
- this._initialized = false;
384
- this.rpc.close();
385
- this.emit("exit", 0);
386
-
387
- // Attempt auto-reconnect on unexpected SSE stream end
388
- if (!this._disconnecting) {
389
- void this.attemptReconnect();
390
- }
391
- }
392
- }
393
- }
394
-
395
- private async cleanupAfterInitializeFailure(): Promise<void> {
396
- if (this.transport === "stdio") {
397
- if (this.process && !this.process.killed) {
398
- try {
399
- this.process.kill("SIGTERM");
400
- } catch {
401
- // Ignore kill failures during cleanup.
402
- }
403
- }
404
- this.process = undefined;
405
- } else {
406
- this.sseAbortController?.abort();
407
- try {
408
- await this.sseStreamPromise;
409
- } catch {
410
- // Ignore stream errors during cleanup.
411
- }
412
- this.sseOutput?.end();
413
- this.sseOutput = undefined;
414
- }
415
- this.rpc.close();
416
- }
417
-
418
- /**
419
- * Gracefully shutdown the connection
420
- */
421
- async shutdown(): Promise<void> {
422
- this._disconnecting = true;
423
- if (!this._initialized) return;
424
- this._initialized = false;
425
- if (this.transport === "sse") {
426
- try {
427
- await this.rpc.request("shutdown", {});
428
- this.rpc.notify("notifications/exit", {});
429
- } catch {
430
- // Best effort
431
- }
432
- this.sseAbortController?.abort();
433
- try {
434
- await this.sseStreamPromise;
435
- } catch {
436
- // Ignore stream shutdown errors
437
- }
438
- this.sseOutput?.end();
439
- this.sseOutput = undefined;
440
- this.rpc.close();
441
- return;
442
- }
443
-
444
- if (this.process) {
445
- // Send MCP shutdown/exit protocol before killing
446
- try {
447
- await this.rpc.request("shutdown", {});
448
- this.rpc.notify("notifications/exit", {});
449
- // Give process a moment to clean up
450
- await new Promise((resolve) => setTimeout(resolve, 500));
451
- } catch {
452
- // Process may already be dead, proceed with kill
453
- }
454
- this.process.kill("SIGTERM");
455
-
456
- // Await process exit before resolving
457
- await new Promise<void>((resolve) => {
458
- // Escalate to SIGKILL if process doesn't exit within 5s
459
- const killTimeout = setTimeout(() => {
460
- try {
461
- this.process?.kill("SIGKILL");
462
- } catch {
463
- /* already dead */
464
- }
465
- }, 5000);
466
- this.process!.once("exit", () => {
467
- clearTimeout(killTimeout);
468
- this.rpc.close();
469
- resolve();
470
- });
471
- });
472
- } else {
473
- this.rpc.close();
474
- }
475
- }
476
-
477
- // ========== Tools ==========
478
-
479
- async listTools(): Promise<MCPTool[]> {
480
- const result = await this.rpc.request<{ tools: MCPTool[] }>("tools/list", {});
481
- return result.tools || [];
482
- }
483
-
484
- async callTool(name: string, args: unknown, abortSignal?: AbortSignal): Promise<ToolResult> {
485
- // Early abort check before making the RPC call
486
- if (abortSignal?.aborted) {
487
- return { success: false, message: "Tool execution cancelled by user." };
488
- }
489
-
490
- try {
491
- // Race the RPC call against the abort signal so user cancel
492
- // doesn't block waiting for a slow MCP server response.
493
- const rpcPromise = this.rpc.request<MCPToolCallResult>("tools/call", {
494
- name,
495
- arguments: args,
496
- });
497
-
498
- let result: MCPToolCallResult;
499
- if (abortSignal) {
500
- result = await new Promise<MCPToolCallResult>((resolve, reject) => {
501
- const onAbort = () => reject(new DOMException("Aborted", "AbortError"));
502
- abortSignal.addEventListener("abort", onAbort, { once: true });
503
- rpcPromise.then(
504
- (r) => {
505
- abortSignal.removeEventListener("abort", onAbort);
506
- resolve(r);
507
- },
508
- (e) => {
509
- abortSignal.removeEventListener("abort", onAbort);
510
- reject(e);
511
- },
512
- );
513
- });
514
- } else {
515
- result = await rpcPromise;
516
- }
517
-
518
- const text =
519
- result.content
520
- ?.filter((c): c is { type: "text"; text: string } => c.type === "text")
521
- .map((c) => c.text)
522
- .join("\n") || "";
523
-
524
- return {
525
- success: !result.isError,
526
- message: text,
527
- data: result.content,
528
- };
529
- } catch (error) {
530
- if (error instanceof DOMException && error.name === "AbortError") {
531
- return { success: false, message: "Tool execution cancelled by user." };
532
- }
533
- return {
534
- success: false,
535
- message: (error as Error).message,
536
- };
537
- }
538
- }
539
-
540
- // ========== Resources ==========
541
-
542
- async listResources(): Promise<MCPResource[]> {
543
- const result = await this.rpc.request<{ resources: MCPResource[] }>("resources/list", {});
544
- return result.resources || [];
545
- }
546
-
547
- async readResource(uri: string): Promise<MCPResourceContent[]> {
548
- const result = await this.rpc.request<{ contents: MCPResourceContent[] }>("resources/read", {
549
- uri,
550
- });
551
- return result.contents || [];
552
- }
553
-
554
- // ========== Prompts ==========
555
-
556
- async listPrompts(): Promise<MCPPrompt[]> {
557
- const result = await this.rpc.request<{ prompts: MCPPrompt[] }>("prompts/list", {});
558
- return result.prompts || [];
559
- }
560
-
561
- async getPrompt(name: string, args?: Record<string, string>): Promise<MCPPromptMessage[]> {
562
- const result = await this.rpc.request<{ messages: MCPPromptMessage[] }>("prompts/get", {
563
- name,
564
- arguments: args,
565
- });
566
- return result.messages || [];
567
- }
568
- }
package/src/mcp/index.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * MCP (Model Context Protocol) Module
3
- *
4
- * Provides client implementation for connecting to MCP servers
5
- * and discovering tools, resources, and prompts dynamically.
6
- */
7
-
8
- export * from './types.js';
9
- export { JSONRPCClient } from './jsonrpc.js';
10
- export { MCPServerConnection } from './connection.js';
11
- export { MCPClient } from './client.js';