Skip to main content

SDK Framework-Adapter Migration — two-field tool identity

The AxonFlow LangGraph and computer-use SDK adapters used to pack two pieces of information — the MCP server and the tool — into a single connector_type string, joined with a dot (for example connector_type: "filesystem.read_file"). A new SDK release splits them into two fields: connector_type carries the server, and a new tool field carries the tool name. This is the request-plane mirror of the Decision API's target.server / target.tool fields.

One-line summary: if you use the LangGraph adapter (Python / TypeScript / Go / Java) or the Python computer-use adapter and you wrote policies that match the old concatenated connector_type value (like "filesystem.read_file"), those policies must be re-scoped — or restored to the old shape with the connectorTypeFn escape hatch. Everyone else needs no changes.

Who is affected

This is a framework-adapter change, not a change to how AxonFlow enforces policy. Read the table, find your row, and stop.

You are…Action required
A LangGraph adapter user (any of Python / TypeScript / Go / Java) with a policy that matches the concatenated connector_type (e.g. equals "filesystem.read_file")Yes — re-scope the policy, or use the connectorTypeFn escape hatch.
A Python computer-use adapter user with a policy that matches the concatenated connector_type (e.g. "computer_use.left_click")Yes — re-scope the policy. There is no escape hatch for this adapter.
A LangGraph / computer-use user whose policies match on other fields (tool name, statement content, tenant, PII category) — not the concatenated connector_typeNo change. Your policies do not depend on the concatenated value.
A user of direct SDK enforcement (decide / check-input / check-output), other frameworks, or the Rust SDKNo change. The Rust SDK has no LangGraph or computer-use adapter and is unaffected.
A user of the separate caller_name audit change (deprecating tool_type on audit_tool_call)No change — that is an unrelated change; see Audit tool-call: caller_name.

If you are not sure whether a policy matches the concatenated value, search your tenant policies for a connector condition (or a connector-type policy) whose value contains a dot (.). Only those are affected.

What changed

The adapters stop concatenating server and tool into connector_type. They now send the server in connector_type and the tool name in the new tool field.

LangGraph adapter:

Old (concatenated)New (two fields)
connector_type"filesystem.read_file""filesystem"
tool(not sent)"read_file"

Python computer-use adapter:

Old (concatenated)New (two fields)
connector_type"computer_use.left_click""computer_use" (a constant connector/domain marker)
tool(not sent; the tool name was discarded whenever an action was present)"computer" (the tool namecomputer / bash / text_editor)
operation(unset)"execute"

For the computer-use adapter, connector_type becomes the constant "computer_use" and the tool name moves into the tool field — the same (server, tool) split the LangGraph adapter uses, so the audit tool_name column always means the tool name. The action (left_click, screenshot, …) is not a tool identity: it is not placed in tool, and not in operation (which the agent API constrains to query / execute). It stays inside the serialized statement, where the policy engine already evaluates it — so a policy that keyed on the action keeps matching it through statement content, not through tool.

What you need to do — by consumer type

LangGraph-adapter users with a policy on the concatenated value

The policy-condition field that reads connector_type is named connector (see Policy conditions). After the split it carries just the server, so drop the .tool suffix from the value.

Before (matched the concatenated value):

{
"name": "block-filesystem-read_file",
"type": "connector",
"conditions": [
{ "field": "connector", "operator": "equals", "value": "filesystem.read_file" }
],
"actions": [ { "type": "block" } ]
}

After (matches the server):

{
"name": "block-filesystem-server",
"type": "connector",
"conditions": [
{ "field": "connector", "operator": "equals", "value": "filesystem" }
],
"actions": [ { "type": "block" } ]
}

This now matches every tool on the filesystem server. There is no tool policy-condition field — the new tool value is not something a conditions block can match — so a connector condition can no longer be narrowed to one tool. If you need per-tool control:

  • Keep the concatenated value with the connectorTypeFn escape hatch below — no policy change, "filesystem.read_file" keeps matching; or
  • Match on request content with a custom policy that carries a regex pattern — the tool name and arguments remain in the request text the policy engine evaluates. (A dynamic content-type tenant policy does not run on the MCP check-input plane, so use a pattern policy, not a content-type condition policy.)

If you cannot re-scope yet — the connectorTypeFn escape hatch (LangGraph only)

Every LangGraph adapter exposes a callback that computes connector_type yourself. Returning the old server + "." + tool string restores the exact pre-migration connector_type, so no policy change is needed. The new tool field is still sent alongside — the escape hatch only changes connector_type. The callback receives the tool request; read the server and tool name off it:

  • Python: connector_type_fn on the LangGraph options — connector_type_fn=lambda req: f"{req.server_name}.{req.name}"
  • TypeScript: connectorTypeFn on the adapter options — connectorTypeFn: (req) => req.serverName + "." + req.name
  • Go: ConnectorTypeFn on MCPInterceptorOptionsConnectorTypeFn: func(serverName, toolName string) string { return serverName + "." + toolName }
  • Java: connectorTypeFn on the adapter builder — .connectorTypeFn(req -> req.getServerName() + "." + req.getName())

The same option is also available on the per-tool GovernedTool wrapper in each SDK.

Python computer-use adapter users

The computer-use adapter has no connectorTypeFn escape hatch. If you wrote a policy against the concatenated connector_type — a value like "computer_use.left_click", a bare tool name like "bash", or a computer_use.* prefix match — you must re-scope it. After the split, connector_type is the constant "computer_use", so the connector condition can only match the whole connector:

Before (matched the concatenated value):

{ "field": "connector", "operator": "equals", "value": "computer_use.left_click" }

After (matches all computer-use traffic):

{ "field": "connector", "operator": "equals", "value": "computer_use" }

To target a specific tool (computer / bash / text_editor) or action (left_click, screenshot), the connector condition alone is not enough — the tool name is in the tool field (not a condition field) and the action stays inside the request content. Use a custom policy with a regex pattern to match the tool name or action, which the adapter still sends in the serialized request. (A dynamic content-type tenant policy does not run on the MCP check-input plane — use a pattern policy.)

Everyone else

No action. Direct SDK enforcement, other framework adapters, the Rust SDK, and the caller_name audit change are all unaffected.

SDK versions that carry this change

This ships as a breaking change in a new SDK release per language. The exact version numbers are being finalized with the release; this table will be pinned to the released versions.

SDKVersion carrying the two-field identity
PythonTBD — pin at release
TypeScriptTBD — pin at release
GoTBD — pin at release
JavaTBD — pin at release
RustNot affected (no LangGraph / computer-use adapter)

This page documents behavior from SDK changes that are being finalized; the version numbers above and the exact field shapes are pinned to the released SDKs before this guide is considered current.

Minimum platform

  • The tool field on POST /api/v1/mcp/check-input is honored on platform v9.10.0 and later. On older platforms the field is accepted but ignored, so request-plane tool scoping requires v9.10.0+.
  • Response-plane tool scoping (the tool field on check-output) lands in platform v9.11.0. On platforms below v9.11.0, response-phase policies for de-concatenated adapters scope to the server (connector_type) only, not the individual tool.

Getting help

If a policy stopped matching after upgrading an adapter, the most useful information for support:

  1. The adapter and SDK version you upgraded to.
  2. The policy condition (connector_type / tool field, operator, and value).
  3. An audit record for a call that should have matched — the policy_details.tool_server and policy_details.tool_name fields show what the platform actually received.

[email protected] — please mention "SDK tool-identity migration" in the subject so it routes correctly.

See also

  • Decision Mode — the target.server / target.tool fields this mirrors on the decide plane.
  • Agent API Endpoints — the connector_type and tool request fields on check-input.
  • Audit Logging — how tool_server / tool_name appear in the audit detail.