Skip to content

fix(mcp): list the MCP server's own probe and close the list_probes client - #19

Merged
jbachorik merged 2 commits into
mainfrom
fix/list-probes-connected
Nov 4, 2026
Merged

jbachorik merged 2 commits into
mainfrom
fix/list-probes-connected

Conversation

@jbachorik

Copy link
Copy Markdown
Contributor

What & why

list_probes only relayed the agent's list, which by design holds detached probes (no client connected). So it returned nothing while this MCP server's own probe was running, and tutorial 05's "check that no probe is left" step proved nothing.

  • The output now has two sections: Connected through this MCP server (from ClientManager: running, exited, or connection lost — a lost session is reported and forgotten) and Detached (stop with stop_detached_probe). It also says that probes connected through another client are not listed.
  • The handler never closed the BTraceClient it opened. It is now closed in finally on every path, including a failed attach and a timeout.
  • The 10 s wait only started after the blocking listProbes call returned, so an agent that never answered hung the request. The call now runs in a daemon FutureTask under that timeout.
  • Tool description and the btrace-mcp-operations skill say what list_probes covers.

Rejected: changing the agent to list connected probes too. That changes what btrace -lp and the LIST_PROBES reply contain for every client.

How verified

Command Result
./gradlew check (plugins/btrace-observability/mcp, JDK 21) BUILD SUCCESSFUL, 55 tests, 0 failures, coverage check passed
BTRACE_JAR=<current btrace develop build> ./gradlew e2eTest McpServerE2ETest 13/13, McpLostConnectionE2ETest 2/2
scripts/validate-marketplace.sh Marketplace validation passed
node scripts/check-tool-references.js OK: all 37 referenced tools exist on the server

Coverage notes

New ListProbesHandlerTest (5): connected session reported, no session, lost session described and forgotten, timeout closes the client, failed attach closes the client. McpServerE2ETest asserts the deployed probe shows as connected and not detached, and "Connected through this MCP server: none" after detaching.

Not verified / known limitations

  • e2e ran against a local btrace develop build, not a release | CI's mcp-e2e job.
  • The JBang launch path of the e2e tests (needs a resolvable btrace artifact, see the plugin's //DEPS on 3.0.0-SNAPSHOT).
  • StopDetachedProbeHandler has the same leak (closes its client only on timeout); not changed here.

Breaking changes / migration

The tool's text output changes shape (two sections). The e2e tests that pick the detached line by probe class still work, because the connected section names no probe class.

Links

Companion docs PR: btraceio/btrace#995

🤖 Generated with Claude Code

…lient

list_probes only relayed the agent's list of detached probes, so it
returned nothing while this server's own probe was running, and "check that
no probe is left" proved nothing. It now reports the session this server
holds (running, exited or connection lost) next to the detached probes.

The handler also never closed the client it opened, and its 10 s wait
started only after the blocking listProbes call returned, so an agent that
never answered hung the request. The call now runs under the timeout and
the client is closed on every path.

Verified: ./gradlew check 55 tests, 0 failures; e2eTest against a current
btrace build - McpServerE2ETest 13/13, McpLostConnectionE2ETest 2/2;
validate-marketplace and check-tool-references pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow-ups from review:

- list_probes read this server's session before listing and forgot any
  lost session afterwards. A session that dropped while the list was in
  flight was reported as live ("stop with exit_probe") and then forgotten,
  so that exit_probe call failed. Only a session this listing reported as
  lost is forgotten now; one that drops mid-list is reported by the next
  call.
- On a timeout or a failed attach the error now still says what this
  server's session is, which needs no answer from the agent.
- An interrupt restores the thread's flag, and error text unwraps
  reflection wrappers like stop_detached_probe does.
- The e2e assertion checks the whole "Connected through this MCP server:
  none" line, not a prefix that the exited and lost variants also match.

Verified: ./gradlew check 56 tests, 0 failures; the new
keepsASessionLostWhileTheListIsInFlightForTheNextCall fails with the old
unconditional forget and passes with the fix; e2eTest against a current
btrace build - McpServerE2ETest 13/13, McpLostConnectionE2ETest 2/2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jbachorik
jbachorik added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit 88f942f Nov 4, 2026
4 checks passed
jbachorik added a commit that referenced this pull request Nov 4, 2026
…b5-b13

main's #19 rewrote list_probes to list this server's connected probe as
well as detached ones, which supersedes this branch's attached-probe note,
so ListProbesHandler and its ToolHandlersTest assertion take main's
version. The skill keeps this branch's confirm-the-PID rule plus main's
list_probes wording, and the detach test keeps this branch's
laterOutputSent wait.

main's new McpSilentDropE2ETest needs the v2 heartbeat (btraceio/btrace#998),
which the pinned 79062f8 lacks, so the pin moves to develop 802d169.

Verified: ./gradlew clean test e2eTest with BTRACE_JAR built from
802d169: 56 unit and 16 e2e tests, 0 failed (against 79062f8 the
silent-drop test fails). validate-repository, validate-evals (15 cases),
check-tool-references, validate-marketplace and actionlint pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant