Skip to content

fix(adapters): wrap redacted MCP output in CallToolResult#120

Open
gzak wants to merge 1 commit intomainfrom
fix/mcp-interceptor-redacted-return-type
Open

fix(adapters): wrap redacted MCP output in CallToolResult#120
gzak wants to merge 1 commit intomainfrom
fix/mcp-interceptor-redacted-return-type

Conversation

@gzak
Copy link
Contributor

@gzak gzak commented Mar 16, 2026

Summary

  • mcp_tool_interceptor was returning output_check.redacted_data (a plain str) when a redaction policy applied to an MCP tool result
  • langchain-mcp-adapters expects the interceptor to return MCPToolCallResult (CallToolResult | ToolMessage | Command) and unconditionally accesses .content on the return value, causing AttributeError: 'str' object has no attribute 'content'
  • Now wraps the redacted string in CallToolResult(content=[TextContent(type="text", text=...)]), which is the correct type for the interceptor contract
  • Adds mcp>=1.0.0 as a new langgraph optional extra (pip install 'axonflow[langgraph]') and to dev dependencies
  • Uses a lazy import with a clear ImportError message if mcp is not installed

Fixes #119

Test plan

  • test_returns_redacted_data_when_present updated to assert the return is a CallToolResult with the correct TextContent
  • All 15 TestMCPToolInterceptor tests pass
  • Full suite: 631 passed, 22 skipped

@gzak gzak force-pushed the fix/mcp-interceptor-redacted-return-type branch 4 times, most recently from e3446dc to edb3e4e Compare March 16, 2026 20:39
Copy link
Member

@saurabhjain1592 saurabhjain1592 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good fix — the CallToolResult wrapping is correct and the OptionalX | None modernization is a nice cleanup.

CI is red because the test matrix in .github/workflows/ci.yml still includes 3.9:

python-version: ['3.9', '3.10', '3.11', '3.12']

The 3.9 job fails on requires-python >= 3.10, which triggers fail-fast and cancels the other jobs. Drop 3.9 from the matrix and it should go green.

Also check if release.yml has a similar matrix or 3.9 reference that needs updating.

Copy link
Member

@saurabhjain1592 saurabhjain1592 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two blocking issues before this can merge. The redaction fix itself is correct.


[P1] Top-level mcp import makes the LangGraph adapter unusable without the extra

from mcp.types import CallToolResult, TextContent is now at module level in langgraph.py. This means from axonflow.adapters import AxonFlowLangGraphAdapter fails with ImportError unless mcp is installed, even for users who only use the workflow-gating parts of the adapter and never call mcp_tool_interceptor().

This is a regression from the current optional-dependency model and contradicts the PR description ("Uses a lazy import with a clear ImportError message if mcp is not installed").

Fix: move the mcp import inside mcp_tool_interceptor() or the redaction branch, and raise a helpful ImportError there instead.


[P1] Bugfix PR quietly drops advertised Python 3.9 support

pyproject.toml now sets requires-python = ">=3.10" and masfeat.py rewrites all types to X | None (3.10+ syntax), but the rest of the repo still advertises and tests 3.9. The PR's own test (3.9) job is already failing at install time: Package 'axonflow' requires a different Python: 3.9.25 not in '>=3.10'.

Dropping 3.9 is fine (it's EOL), but it should be an explicit, separate change with:

  • CI matrix updated (.github/workflows/ci.yml and release.yml) to remove 3.9
  • README compatibility section updated
  • Release notes calling out the compatibility break

Recommendation: split this PR into two:

  1. The CallToolResult bugfix (with lazy import) — can ship as a patch release
  2. The Python 3.9 drop + Optional modernization — ships as a minor or major version bump

That way the bugfix isn't blocked on the compatibility discussion and users on 3.9 still get the fix.

Copy link
Member

@saurabhjain1592 saurabhjain1592 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues I'd strongly recommend fixing before merging. The redaction fix itself is correct.


[P1] Top-level mcp import breaks LangGraph adapter for users who don't have mcp installed

from mcp.types import CallToolResult, TextContent is now at module level in langgraph.py. This means from axonflow.adapters import AxonFlowLangGraphAdapter fails with ImportError unless mcp is installed, even for users who only use the workflow-gating parts of the adapter and never call mcp_tool_interceptor().

This is a regression from the current optional-dependency model and contradicts the PR description ("Uses a lazy import with a clear ImportError message if mcp is not installed").

Fix: move the mcp import inside mcp_tool_interceptor() or the redaction branch, and raise a helpful ImportError there instead.


[P1] Bugfix PR quietly drops advertised Python 3.9 support

pyproject.toml now sets requires-python = ">=3.10" and masfeat.py rewrites all types to X | None (3.10+ syntax), but the rest of the repo still advertises and tests 3.9. The PR's own test (3.9) job is already failing at install time: Package 'axonflow' requires a different Python: 3.9.25 not in '>=3.10'.

Dropping 3.9 is fine (it's EOL), but it should be an explicit, separate change with:

  • CI matrix updated (.github/workflows/ci.yml and release.yml) to remove 3.9
  • README compatibility section updated
  • Release notes calling out the compatibility break

Recommendation: split this PR into two:

  1. The CallToolResult bugfix (with lazy import) — can ship as a patch release
  2. The Python 3.9 drop + Optional modernization — ships as a minor or major version bump

That way the bugfix isn't blocked on the compatibility discussion and users on 3.9 still get the fix.

@gzak gzak force-pushed the fix/mcp-interceptor-redacted-return-type branch 4 times, most recently from ffbecd5 to f069e61 Compare March 17, 2026 20:26
When mcp_check_output returns redacted_data, the interceptor was
returning a plain str. langchain-mcp-adapters expects MCPToolCallResult
(CallToolResult | ToolMessage | Command) and calls .content on the
return value, causing AttributeError at runtime.

Now wraps the redacted string in a CallToolResult with a single
TextContent block, which is the correct return type for the interceptor
protocol. Also adds mcp>=1.0.0 as a new 'langgraph' optional extra and
to dev dependencies, with a lazy import that surfaces a clear error
message if mcp is not installed.

Fixes #119
@gzak gzak force-pushed the fix/mcp-interceptor-redacted-return-type branch from f069e61 to 2b0e967 Compare March 20, 2026 00:51
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.

fix(adapters): mcp_tool_interceptor returns raw str for redacted output, breaking langchain-mcp-adapters

2 participants