-
Notifications
You must be signed in to change notification settings - Fork 0
fix(dev): bound MCP probe teardown and path redaction #316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| "agent-bundle": patch | ||
| --- | ||
|
|
||
| Keep timed-out MCP probes responsive when transport teardown stalls, while | ||
| continuing the transport close path that terminates stdio children. Redact | ||
| absolute paths that follow common key-value and list separators. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,7 @@ export const mcpProbeFailureTextLimit = 2_048; | |
|
|
||
| const mcpProbeCapabilityLimit = 32; | ||
| const mcpProbeNameTextLimit = 256; | ||
| const mcpProbeTeardownWaitMs = 50; | ||
| const safeCapabilityName = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/u; | ||
| const connectionErrorCodes = new Set([ | ||
| 'EACCES', | ||
|
|
@@ -126,7 +127,7 @@ const bundlePathPattern = (bundleRoot: string): RegExp => { | |
| }; | ||
|
|
||
| const hasAbsolutePath = (value: string): boolean => | ||
| /(?:file:|(?:^|[\s"'([{])\/[^\s,;{}()[\]<>"']+|(?:^|[\s"'([{])[A-Za-z]:[\\/]|\\\\)/u.test(value); | ||
| /(?:file:|(?:^|[\s"'([{=,:])\/[^\s,;{}()[\]<>"']+|(?:^|[\s"'([{=,:])[A-Za-z]:[\\/]|\\\\)/u.test(value); | ||
|
|
||
| /** | ||
| * Probe text follows the Dev Log browser-wire precedent without coupling this | ||
|
|
@@ -465,7 +466,19 @@ export class McpProbeService { | |
| }); | ||
| return report; | ||
| } finally { | ||
| await Promise.allSettled([client.close(), transport.close()]); | ||
| let timer: NodeJS.Timeout | undefined; | ||
| // Keep transport teardown running through its TERM/KILL path without | ||
| // allowing a stalled close to extend the probe's total time budget. | ||
| const teardown = Promise.allSettled([client.close(), transport.close()]); | ||
| const teardownWait = new Promise<void>((resolvePromise) => { | ||
| timer = setTimeout(resolvePromise, mcpProbeTeardownWaitMs); | ||
| timer.unref(); | ||
| }); | ||
| try { | ||
| await Promise.race([teardown, teardownWait]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a stdio server uses the resolved plugin-data directory and its close takes longer than 50 ms, this race lets Useful? React with 👍 / 👎.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in #397 (merged as d25a9c6). Plugin-data removal in |
||
| } finally { | ||
| if (timer !== undefined) clearTimeout(timer); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When instructions, tool metadata, server metadata, or an error contains a normal URL such as
https://example.com/docs, allowing:as the prefix causes this regex to match://example.com/docs;redactProbeTextthen replaces the entire field with[REDACTED]even though it contains no local path. This hides common MCP documentation and link guidance, so exclude URI scheme delimiters before interpreting a colon as a path separator.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in #397 (merged as d25a9c6).
redactProbeTextno longer treats the://of a URI scheme as a path separator, sohttps://…links survive, while userinfo (scheme://user:secret@host) is masked through the final@, non-network schemes (unix://,vscode://file/,postgres://…/…,file:) still fail closed, and URIs glued to a preceding identifier are handled.tests/mcp-probe-service.test.tscovers URLs beside real bundle paths plus the userinfo and local-URI cases.