Claude Agent SDK + AxonFlow Integration
Prerequisites: Node.js 18+, AxonFlow running (Getting Started), npm install @axonflow/sdk
What the Claude Agent SDK Is
The Claude Agent SDK is Anthropic's framework for building custom AI agents that use MCP-based tools. It provides a structured way to define tools, manage agent loops, and handle tool execution results. Agents built with the SDK can connect to MCP servers for database access, API calls, file operations, and other external interactions.
The SDK handles the agent loop (prompt, tool selection, execution, response), tool result formatting, and conversation management. When an agent decides to use a tool, the SDK manages the serialization of inputs, dispatches the call, and feeds the result back into the conversation for the next reasoning step.
What the SDK does not provide is governance over those tool calls. There is no built-in mechanism for policy enforcement on tool inputs, PII detection on tool outputs, or compliance-ready audit trails for tool execution. These are the concerns AxonFlow addresses.
How AxonFlow Integrates
The Claude Agent SDK uses the MCP protocol for tool execution. AxonFlow's TypeScript SDK already includes mcpCheckInput() and mcpCheckOutput() methods that evaluate MCP tool calls against your policy engine. No new SDK code or adapters are needed.
The integration pattern is straightforward: call mcpCheckInput() before executing a tool to enforce input policies (SQL injection, PII in queries, dangerous operations), then call mcpCheckOutput() after execution to enforce output policies (PII redaction, exfiltration detection, response filtering).
Agent Loop → Tool Selected → mcpCheckInput() → Tool Execution
↓
Agent Response ← mcpCheckOutput() ← Tool Result
This works with any MCP tool the agent uses, whether it connects to a database, calls an API, or accesses a file system.
TypeScript Integration Pattern
Wrap your agent's tool execution with AxonFlow policy checks:
import { AxonFlow } from '@axonflow/sdk';
const client = new AxonFlow({
endpoint: process.env.AXONFLOW_ENDPOINT!,
clientId: process.env.AXONFLOW_CLIENT_ID!,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
});
// Before tool execution: check input against policies
async function checkToolInput(
toolName: string,
toolInput: Record<string, unknown>
): Promise<{ allowed: boolean; blockReason?: string }> {
const inputCheck = await client.mcpCheckInput({
connectorType: `agent_sdk.${toolName}`,
statement: JSON.stringify(toolInput),
operation: 'execute',
});
if (!inputCheck.allowed) {
return { allowed: false, blockReason: inputCheck.block_reason };
}
return { allowed: true };
}
// After tool execution: check output for PII, exfiltration
async function checkToolOutput(
toolName: string,
toolResult: unknown
): Promise<{ data: unknown; redacted: boolean }> {
const outputCheck = await client.mcpCheckOutput({
connectorType: `agent_sdk.${toolName}`,
message: typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult),
});
if (outputCheck.redacted_data) {
return { data: outputCheck.redacted_data, redacted: true };
}
return { data: toolResult, redacted: false };
}
Full Agent Example
import { AxonFlow } from '@axonflow/sdk';
const client = new AxonFlow({
endpoint: process.env.AXONFLOW_ENDPOINT!,
clientId: process.env.AXONFLOW_CLIENT_ID!,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
});
// Governed tool execution wrapper
async function executeGovernedTool(
toolName: string,
toolInput: Record<string, unknown>,
executeFn: (input: Record<string, unknown>) => Promise<unknown>
): Promise<{ result: unknown; blocked: boolean; redacted: boolean }> {
// 1. Pre-execution policy check
const inputCheck = await client.mcpCheckInput({
connectorType: `agent_sdk.${toolName}`,
statement: JSON.stringify(toolInput),
operation: 'execute',
});
if (!inputCheck.allowed) {
console.log(`Tool "${toolName}" blocked: ${inputCheck.block_reason}`);
return { result: null, blocked: true, redacted: false };
}
// 2. Execute the tool
const rawResult = await executeFn(toolInput);
// 3. Post-execution policy check
const outputCheck = await client.mcpCheckOutput({
connectorType: `agent_sdk.${toolName}`,
message: typeof rawResult === 'string' ? rawResult : JSON.stringify(rawResult),
});
if (outputCheck.redacted_data) {
return { result: outputCheck.redacted_data, blocked: false, redacted: true };
}
return { result: rawResult, blocked: false, redacted: false };
}
// Usage with a database query tool
const { result, blocked, redacted } = await executeGovernedTool(
'query_customers',
{ query: 'SELECT name, email FROM customers WHERE region = $1', params: ['US'] },
async (input) => {
// Your actual tool execution logic
return [
{ name: 'Jane Smith', email: '[email protected]' },
{ name: 'Bob Johnson', email: '[email protected]' },
];
}
);
if (blocked) {
console.log('Tool execution was blocked by policy');
} else if (redacted) {
console.log('Tool result contained PII that was redacted');
}
Connector Type Naming Convention
When calling mcpCheckInput() and mcpCheckOutput(), use the connectorType field to identify the tool. The recommended convention for Claude Agent SDK tools is:
agent_sdk.{tool_name}
Examples:
| Tool | Connector Type |
|---|---|
| Database query tool | agent_sdk.query_customers |
| File reader tool | agent_sdk.read_file |
| API caller tool | agent_sdk.call_api |
| Email sender tool | agent_sdk.send_email |
This naming convention lets you write policies that target specific tools or all Agent SDK tools:
- All Agent SDK tools: Match
agent_sdk.*in your policy conditions - Specific tool: Match
agent_sdk.query_customersfor per-tool rules - Tool categories: Use naming like
agent_sdk.db_*for all database tools
What Gets Governed
Input Checks (mcpCheckInput)
| Check | What It Catches | Example |
|---|---|---|
| SQL injection detection | Malicious SQL in tool inputs | DROP TABLE users; -- |
| PII in queries | Sensitive data sent to tools | SSN or credit card in search parameters |
| Dangerous operations | Destructive actions | DELETE FROM without WHERE clause |
| Custom policies | Your tenant-specific rules | Block production database access |
Output Checks (mcpCheckOutput)
| Check | What It Catches | Example |
|---|---|---|
| PII redaction | Sensitive data in results | Email, phone, SSN in returned records |
| Exfiltration detection | Large-scale data extraction | Tool returning 10,000+ rows |
| Response filtering | Policy-matched content | Credit card numbers in API responses |
| Custom policies | Your tenant-specific rules | Block certain data classifications |
Every check (both input and output) creates an audit entry. Blocked requests never reach the tool. Redacted responses replace sensitive values with placeholders like [REDACTED:ssn] before the data returns to the agent.
For details on configuring these policies, see MCP Policy Enforcement. System policies (PII, SQL injection) are active by default. Tenant policies let you add custom rules for specific tools or data classifications.
Latency Impact
| Operation | Typical Latency |
|---|---|
mcpCheckInput | 2-5ms |
mcpCheckOutput | 2-5ms |
| Audit write (async) | 0ms (non-blocking) |
| Total per tool call | 4-10ms |
For agent workflows where tool calls typically take 50-500ms (database queries, API calls), the governance overhead is negligible.
Differences from Claude Code Integration
If you are also using Claude Code, here is how the two integrations compare:
| Aspect | Claude Code | Claude Agent SDK |
|---|---|---|
| Integration point | Shell hooks (pre/post tool) | TypeScript SDK methods |
| Protocol | HTTP calls to AxonFlow agent | mcpCheckInput / mcpCheckOutput |
| Scope | Developer CLI tool governance | Custom agent tool governance |
| Runtime | Bash scripts | Node.js / TypeScript |
| Use case | Governing developer interactions | Governing production agent tools |
Both integrations use the same AxonFlow policy engine and audit trail. Policies configured for one apply to the other when the connector types match.
Observe Mode
If you want to evaluate AxonFlow's governance without blocking any tool calls, start in observe mode. Set the PII_ACTION environment variable to log on your AxonFlow instance:
PII_ACTION=log
In this mode, all policy evaluations are logged and audited, but no tool calls are blocked and no responses are redacted. Review the audit trail to understand what policies would have triggered, then switch to redact or block when you are ready to enforce.
Related Resources
- MCP Policy Enforcement for the full policy evaluation reference
- Per-Tool Governance for governing tools within workflow steps
- TypeScript SDK for SDK setup and configuration
- Gateway Mode for routing all LLM calls through AxonFlow
- Claude Code Integration for governing the Claude Code CLI
- Audit Logging for querying and exporting audit trails
Platform Version: v5.4.0 | SDKs: Python v5.4.0, Go/TypeScript/Java v4.3.0
