Skip to content

Fix what agents hit through neorepl mcp - #26

Merged
bbatsov merged 9 commits into
mainfrom
mcp-polish
Oct 20, 2026
Merged

bbatsov merged 9 commits into
mainfrom
mcp-polish

Conversation

@bbatsov

@bbatsov bbatsov commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Results the official MCP SDK rejected, calls that could hang or take the server down, and arguments nobody checked. One behaviour change: the tools default to the session called agent, the one the skill already has agents use with the CLI, instead of default, so an agent mixing the two keeps a single session and stays out of the user's.

The first commit only puts #25's CHANGELOG entries in order.

MCP has a tool result's structured content be an object, and the official
SDK rejects one that isn't, so pst and apropos, which returned lists,
failed for agents on it. They now put the list under causes and vars.
Standard input carries neorepl mcp's protocol, so code that read *in* took
the next message the agent sent as its line, and that message never got an
answer. A read now gets end of input, as neorepl eval - gives it.
The reload tool waited for the server as long as it took, ignoring the
timeout, so a namespace that never finished loading kept the call, and
neorepl mcp ending after its input, waiting for good. It now takes the
call's timeout, or the server's, and says it gave up, while the server may
still be at it.
A line the JSON reader choked on in a way it didn't expect, like an id
past a long, or nesting deep enough to overflow the stack, ended neorepl
mcp. Arguments of the wrong type got through to the code, where a port as
a string said no server answered there, and a timeout as a string threw.

The reader now reads integers past a long as bigints, and the server
answers anything it can't read with a parse error. Each call's arguments
get checked against its tool's schema, which now says what the ports,
timeouts and sessions can be, and one that doesn't fit gets an error result
saying so. The arguments without a description got one, and load and
retest declare the timeout they took already.
neorepl mcp found out its connection was dead only when a call failed on
it, so the first call after the nREPL server restarted failed. A
connection whose server went away is now replaced before a call uses it,
and closed.
The tools used the session called default, which is also what neorepl eval
uses without --session, while the skill has agents use one called agent
with the CLI. An agent mixing the two got two sessions, and shared one with
the user. The tools now default to agent. mcp --help says so, rather than
repeating the sessions note, which mentions a --session option mcp doesn't
have.
--max-output cut each value and each stream, so an evaluation of a few
thousand small values still filled the agent's context. The tool's text is
now cut at that many characters as a whole, without splitting a surrogate
pair, and the result says it was truncated.
discovery/probe throws when there are no port files, so the tool failed
rather than saying there were none.
@bbatsov
bbatsov merged commit 9d42a84 into main Oct 20, 2026
18 checks passed
@bbatsov
bbatsov deleted the mcp-polish branch October 20, 2026 04:21
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