Research review / frameworks

Framework Watch: An Agent Exposed Over MCP Sent Its Hidden Reasoning to Clients

ADK Python stopped to_mcp_server from returning a model's thought parts to MCP clients. Claude Code 2.1.314 adds a setting that blocks writes outside the working directories in every permission mode. Codex 0.166 keeps approval settings across resume and fork, and PyRIT fixed a Crescendo refusal check that was judging the wrong text.

By Sandeep Belgavi · Published 2026-10-30

This week's changes are about information crossing a boundary it should not cross: reasoning reaching a client, a file write leaving the project, permission state lost on resume, and a scorer given the wrong input.

ADK Python: thoughts returned as tool results

ADK's to_mcp_server exposes an ADK agent as an MCP tool. Issue #7834, opened October 29, 2026, reported that it turned every part with text into an MCP TextContent block, "including parts with thought=True." With a thinking model, the MCP client received the model's hidden reasoning as part of the tool result, and progress notifications included thought text too. The issue's example shows a private instruction reaching the client before the answer.

A commit merged on October 30 makes _part_to_content return nothing for thought parts and filters them from progress messages. The issue notes that AgentTool and the memory services already skipped thoughts, so this was one path that had been missed. The fix is on the main branch and is not yet in a tagged release. A separate October 29 commit fixes serialization of Gemma 3 tool results that hold datetimes, bytes or models.

Claude Code 2.1.314: a write boundary and a fail-open fix

Claude Code v2.1.314, released October 30, adds permissions.blockWritesOutsideWorkingDirectories: Write, Edit and NotebookEdit "refuse paths outside the working directories in every permission mode." Several fixes in the same release concern behaviour that looked fine but was not:

  • forceRemoteSettingsRefresh, set only in remote managed settings, stopped applying once the stored copy expired, "which let sessions start without policy when the server could not be reached."
  • claude -p exited "with code 0 and no output when startup failed". It now prints the error and exits 1.
  • "Continue automatically at usage limit" could continue more than three times without a prompt when a task restarted itself between waits.
  • claude mcp logout reported success when the MCP sign-in had not been removed.
  • A PreCompact hook with very large output could make compaction fail. Each hook's output is now cut at 10,000 characters.

Codex 0.166: state that survives resume

Codex rust-v0.166.0, released October 29, "preserved acknowledged approval and permission settings when resuming or forking threads" (#57227). It also preserves reasoning-token accounting across resume and fork "to avoid premature compaction" (#57839). The release adds clearer explanations when a safety block stops a request, codex doctor --network-only for connectivity checks, and GPT-6.1 Terra in the bundled, Vertex AI and Amazon Bedrock model catalogs.

PyRIT: a refusal judge reading the wrong text

In Microsoft's PyRIT red-teaming toolkit, Crescendo is a multi-turn attack that backtracks when the target refuses. PR #3562, merged October 30, says _perform_backtrack_if_refused_async "was passing prompt_sent" into the refusal check's objective parameter. So the judge "evaluated deflection against the adversarial prompt itself," and the stored record listed the prompt as the objective. It now passes the real objective.

What remains uncertain. The ADK fix is untagged. Neither the Claude Code nor the Codex notes say how many users hit these bugs. The PyRIT PR does not measure how much the bug changed past Crescendo results, so earlier runs may have backtracked at the wrong points.

Analysis: Two tests are worth adding. First, if you expose an agent through MCP, call it with a thinking model and assert that no thought text reaches the client. A help-desk agent at Belgavi's Book Store should never send its internal notes about a customer's CASE-2291 return to an outside caller. Second, check exit codes: a CI step that runs an agent and treats exit 0 as success could have passed with no output under the old claude -p behaviour.

Sources and evidence

An October 30 ADK Python commit (untagged) stops to_mcp_server from returning a thinking model's thought parts to MCP clients; Claude Code 2.1.314 adds blockWritesOutsideWorkingDirectories and fixes a remote-policy refresh that let sessions start without policy and a claude -p that exited 0 on startup failure; Codex 0.166.0 keeps approval settings across resume and fork; and PyRIT fixed a Crescendo refusal check that judged the attack prompt instead of the objective.

Views are my own and do not represent any employer, past or present.