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_typevalue (like"filesystem.read_file"), those policies must be re-scoped — or restored to the old shape with theconnectorTypeFnescape 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_type | No 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 SDK | No 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 name — computer / 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
connectorTypeFnescape 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 dynamiccontent-type tenant policy does not run on the MCP check-input plane, so use apatternpolicy, not acontent-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_fnon the LangGraph options —connector_type_fn=lambda req: f"{req.server_name}.{req.name}" - TypeScript:
connectorTypeFnon the adapter options —connectorTypeFn: (req) => req.serverName + "." + req.name - Go:
ConnectorTypeFnonMCPInterceptorOptions—ConnectorTypeFn: func(serverName, toolName string) string { return serverName + "." + toolName } - Java:
connectorTypeFnon 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.
| SDK | Version carrying the two-field identity |
|---|---|
| Python | TBD — pin at release |
| TypeScript | TBD — pin at release |
| Go | TBD — pin at release |
| Java | TBD — pin at release |
| Rust | Not 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
toolfield onPOST /api/v1/mcp/check-inputis 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
toolfield oncheck-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:
- The adapter and SDK version you upgraded to.
- The policy condition (
connector_type/toolfield, operator, and value). - An audit record for a call that should have matched — the
policy_details.tool_serverandpolicy_details.tool_namefields 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.toolfields this mirrors on the decide plane. - Agent API Endpoints — the
connector_typeandtoolrequest fields oncheck-input. - Audit Logging — how
tool_server/tool_nameappear in the audit detail.
