feat(mcp): serve the host's schema tools through the MCP facade - #449
Merged
Conversation
tools/list at POST <mount>/mcp offers every tool the dashboard's discovered ActiveAgent::SchemaTools classes generate — find_<records>, count_<records>, get_<record> — beside the run_<slug> agents, each with its own parameter schema, and tools/call runs one as the key's caller through the host's own scope, exactly as it would inside an agent run. A boundary violation is a tool result with isError; a refusal from the host's scope is a JSON-RPC -32003; neither the execution switch nor the execution quota applies, because nothing generates. ActionAgent.mcp_schema_tools = false keeps the tools reachable only through agents. ActiveAgent::NotAuthorized becomes autoloadable: it was defined only when Base loaded, and the engine referencing it first raised NameError. Also records this batch of work under docs/work/schema-tools-follow-ups. Closes #439. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XMSRnSxYS9mRx1hSjytB9Z
TonsOfFun
changed the base branch from
claude/zealous-turing-4afxvn
to
main
September 12, 2026 19:24
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
# Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #439. Stacked on #443 (it needs
agent_actor); retarget tomainonce that merges.#439 asked for a mounted Rack endpoint serving the schema-tool roster over MCP. As the review on #443 noted,
Api::MCPControlleralready is that endpoint; what was missing was the roster. This extends the facade rather than adding a second server — one definition, two transports.Change
tools/listoffers every tool the dashboard's discoveredActiveAgent::SchemaToolsclasses generate —find_<records>,count_<records>,get_<record>— beside therun_<slug>agents, each with the tool's own parameter schema asinputSchema, so a client sees which columns it may filter on.tools/callon one of them runsSchemaTools.call(name, actor: agent_actor, **arguments): the key's caller (or whateverActionAgent.agent_actor_resolverreturns), through the host's own scope, exactly as inside an agent run. Arguments that name the caller (actor,current_user) are dropped, for the reason Carry the caller into agent runs, so agents can authorize like controllers #443 gives.isError, the shape an agent's model would get, so a client can correct its call. A refusal raised by the host's scope —ActiveAgent::NotAuthorizedor an error named withdenies_with— is a JSON-RPC-32003, as an agent's refusal is.execution_enablednor the execution quota applies to a direct read, and no execution usage is recorded.ActionAgent.mcp_schema_tools = falsekeeps the tools reachable only through agents. On by default: the host declared them, and every key holder could already reach them through any agent that has them enabled.autoload :NotAuthorizedinlib/active_agent.rb: the class is defined inconcerns/authorization.rb, loaded only withBase, and the engine referencing it before any agent class had loaded raisedNameError(whichrun_refused?on Carry the caller into agent runs, so agents can authorize like controllers #443 sidesteps by comparing strings).docs/framework/dashboard.mdgains a section on the facade;docs/work/schema-tools-follow-ups/records this batch of work (branches, issues, milestones, PRs).Testing
actionagent/test/mcp_schema_tools_test.rb: nine cases — listing beside agents with the parameter schema, running as the resolved caller with the client's arguments, a client cannot name the caller, unattributed when nothing resolves, a boundary violation asisError, a refusal as-32003, unknown tool, the switch, no execution switch or quota.bin/test actionagent/test/mcp_*_test.rb test/authorization_test.rb— 30 runs, 83 assertions, 0 failures.bin/rubocopclean on the changed files.🤖 Generated with Claude Code
https://claude.ai/code/session_01XMSRnSxYS9mRx1hSjytB9Z