ex tool should return stderr/errors to MCP client #14
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
kahliburke/Kaimon.jl#14
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
When using the
extool via MCP (e.g. from Claude Code), errors frominclude()or other expressions go to stderr but are never returned to the MCP client. The tool returns(completed with no output)even when the REPL shows a full stacktrace.This makes it impossible for AI agents to diagnose errors without the user manually copying and pasting the stacktrace from the REPL buffer.
Example
Suggestion
The
extool should capture stderr and include it in the MCP response, at least for errors/exceptions. This is critical for autonomous agent workflows where the agent needs to see errors to fix them.Environment
Note: I see this is likely addressed in the 1.1 branch (commits
a160f985,32b68fe8,89d3acf5), but 1.1 currently fails to precompile due to aBoxTabsdependency issue with Tachikoma.Update: Kaimon 1.1 + Claude Code SSE incompatibility
Installed Kaimon 1.1 successfully (needed Tachikoma from
dev/v2.0-previewbranch forBoxTabs). The MCP server starts andpingworks fine. However,extool calls hang from Claude Code's perspective:excalls, regardless ofq,s, orsesparameterspingworks fine — onlyexis affectedThis looks like an SSE streaming change in 1.1 that Claude Code's MCP client can't handle. The eval result is never delivered back to the MCP client even though it completes on the REPL side.
Reverted to 1.0.1 for now.
Also when I try to intially setup 1.1. there is a bunch of fancy text and animation and it causes problems with the julia REPL/terminal.
@prittjam I am using it successfully with the latest Claude all the time, so perhaps something else is going on here. What version of Claude code are you using?
Status: Fixed in 1.1 branch
The error capture and SSE streaming issues are both resolved in the current
1.1branch. Here's verification of errors flowing back correctly to the MCP client (Claude Code):Error examples
Explicit error:
UndefVarError:
include() errors (original issue):
ArgumentError:
All error types return full stacktraces to the MCP client.
SSE hang fix
The
exhang issue (eval runs but result never returns to Claude Code) was caused byREPL.call_on_backenddeadlocking when the gate eval runs on a background thread while the REPL backend is occupied by the interactive session. This is now fixed — async evals bypasscall_on_backendand eval directly.Setup
BoxTabsexport). Make sure your Tachikoma dependency resolves to 1.1.6+.~/.config/kaimon/config.jsonmanually with{"mode": "lax"}before first run.@prittjam Tested again and it is working here..Yes the 1.1 branch is in flux with other changes in Tachi. I will work on stabilizing and releasing it soon, but if you bypass the startup wizard with the workaround suggested above (I have not tried to do it in emacs) and you already have the dev/v2.0-preview of Tachi checked out, that should be a good combination until the official release Is there.
Let me know if I can assist in getting the setup worked out. It works very well for me but there are sometimes these environmental issues that are hard to predict.
Workaround: Disabling println stripping
For our workflow (CUDA kernel debugging with progress prints), the
printlnstripping in theextool is a significant blocker. The agent can't see any stdout output, making it impossible to diagnose where long-running operations hang.One-line fix that worked for us
In
src/Kaimon.jlaround line 766, commenting out theremove_println_callsline:Feature request
Could the
extool get an option to disable println stripping? For example:Or perhaps only strip when
q=true(quiet mode), and pass through stdout whenq=false? The current behavior where println is "ALWAYS stripped" (per the docs) means agents have zero visibility into long-running operations, compilation progress, or debugging output.Context
We're developing CUDA kernels where JIT compilation takes 30+ seconds per kernel. Without println output, the agent can't tell which kernel is compiling, whether it's hung, or what errors occurred. We had to have the user manually paste REPL output back to the agent, which defeats the purpose of the MCP integration.
Update: Kaimon 1.1 SSE issue — more details
Tried Kaimon 1.1 again (with Tachikoma from
dev/v2.0-previewforBoxTabs). Theextool hangs from Claude Code's perspective:pingworks fine (returns immediately)ex(e="1+1", q=false)— the eval runs, user sees2in REPL, but Claude Code never receives the response. Claude Code spins indefinitely until the user interrupts.sesparameter, withs=true, all same behaviorThe MCP config:
Reverted to 1.0.1 where
exworks (though println is stripped). Seems like the 1.1 SSE streaming path forexresults isn't completing/closing the response properly for HTTP MCP clients.Environment
Diagnostic scripts and recommended patterns
We've been testing extensively and want to share diagnostic tools and findings. We're working to understand what's different in your environment — everything works reliably on our end, so we need your help isolating the issue.
How println stripping works
The
extool stripsprintln/print/printstyledfrom the agent's submitted code AST at all nesting levels. This is by design — agents should useq=falsewith return values, not println.However, stdout from called functions is captured and returned. This is the key distinction:
println("debug"); 4242my_function()where my_function has printlnq=falseinclude("script.jl")where script has printlnq=falseTested examples from our session:
Recommended pattern for long-running tasks: Gate.progress()
For CUDA kernel compilation and similar long-running work, define a custom GateTool that uses
Gate.progress()to stream real-time updates to the agent:The agent calls
compile_kernel(name="matmul")and eachGate.progress()call sends an SSE progress notification during execution. These are visible in the Kaimon TUI Activity tab and delivered to the MCP client.Diagnostic scripts
Attached are test scripts to verify behavior in your environment — include
demo_println_behavior.jlto get test functions, then call them withq=falseto verify stdout flows back:https://gist.github.com/kahliburke/44b0053a1715951419409c8a23219d23
Isolating the issue
Since the fixes above work reliably in our testing, we'd like to narrow down what's different in your setup. You mentioned using
claude-code-ide.elfor Emacs integration. While the MCP HTTP traffic between Claude Code and Kaimon isn't altered by the Emacs wrapper, the Claude Code CLI runs inside a terminal emulator buffer (vterm/eat), and the CLI may behave differently based on its terminal environment — TTY detection, output buffering, capability reporting, etc.Could you try running Claude Code from a regular terminal (outside Emacs) and have the agent use the
extool? If it works from a standard terminal but not from Emacs, that tells us the CLI's streaming behavior changes based on its terminal context, and we can investigate further from there.Thanks, I'll try this a bit later. Maybe I'll wait for 1.1 official release and revisit
@prittjam Thank you, I will close as I am seeing the correct behavior and even have unit tests for this stuff. There is some other factor which we might be missing or some bug that you're hitting which I'm not. Let's revisit when you have the time to do a little investigation, as I'd really love for you to be able to use this, it is in my opinion a HUGE leap forward from what MCPRepl provided. 1.1 is actually getting pretty powerful.