Skip to main content
The Claude Agent SDK adapter lets you run AgentMark prompts as agentic tasks using Anthropic’s Claude Agent SDK, with tool use, budget controls, and tracing. Available for both TypeScript and Python; every section below shows both side by side.
The Python adapter (agentmark-claude-agent-sdk-v0) is in alpha. The API surface documented here is stable, but expect occasional changes ahead of the v1 release. For type-safe structured outputs across all major providers, Pydantic AI is the recommended general-purpose Python adapter. Reach for Claude Agent SDK when you specifically need Claude’s agentic capabilities.

Installation

npm install @agentmark-ai/claude-agent-sdk-v0-adapter @anthropic-ai/claude-agent-sdk

Setup

Create your AgentMark client with a ClaudeAgentModelRegistry. The registry creator is a function that receives the model name and returns a ModelConfig. Use createDefault() for a pass-through registry, or register models explicitly if you need per-model options like maxThinkingTokens:
agentmark.client.ts
import { createAgentMarkClient, ClaudeAgentModelRegistry } from "@agentmark-ai/claude-agent-sdk-v0-adapter";

// Option 1: pass-through registry
const modelRegistry = ClaudeAgentModelRegistry.createDefault();

// Option 2: explicit registration with per-model config
const modelRegistry = new ClaudeAgentModelRegistry()
  .registerModels(["claude-sonnet-4-20250514"], (name) => ({ model: name }))
  .registerModels(["claude-opus-4-20250514"], (name) => ({
    model: name,
    maxThinkingTokens: 10000,
  }));

export const client = createAgentMarkClient({
  loader,
  modelRegistry,
});

Running prompts

The adapter returns { query: { prompt, options }, messages, telemetry }. Pass adapted.query directly to query() from @anthropic-ai/claude-agent-sdk:
import { client } from "./agentmark.client";
import { query } from "@anthropic-ai/claude-agent-sdk";

const prompt = await client.loadTextPrompt("task.prompt.mdx");
const adapted = await prompt.format({
  props: { task: "Analyze the auth module and suggest improvements" },
});

for await (const message of query(adapted.query)) {
  console.log(message);
}

Adapter options

Adapter options are configured at client construction time (via createAgentMarkClient), not inside prompt.format(). prompt.format() silently ignores them:
export const client = createAgentMarkClient({
  loader,
  modelRegistry,
  adapterOptions: {
    permissionMode: "bypassPermissions",
    maxTurns: 10,
    cwd: "/path/to/project",
    maxBudgetUsd: 5.00,
    allowedTools: ["Read", "Write", "Bash"],
    disallowedTools: ["WebFetch"],
    systemPromptPreset: false,
    onWarning: (warning) => {
      console.warn("Agent warning:", warning);
    },
  },
});
OptionTypeScriptPythonType / values
Permission modepermissionModepermission_mode'default' | 'acceptEdits' | 'bypassPermissions' | 'plan'
Max turnsmaxTurnsmax_turnsnumber
Working directorycwdcwdstring
Budget limitmaxBudgetUsdmax_budget_usdnumber (USD)
Allowed toolsallowedToolsallowed_toolsstring[] (whitelist)
Disallowed toolsdisallowedToolsdisallowed_toolsstring[] (blacklist)
System prompt presetsystemPromptPresetsystem_prompt_presetboolean (use Claude Code’s built-in)
Warning handleronWarningon_warning(message: string) => void

Object generation

For structured output, use object prompts:
import { client } from "./agentmark.client";
import { query } from "@anthropic-ai/claude-agent-sdk";

const prompt = await client.loadObjectPrompt("extract.prompt.mdx");
const adapted = await prompt.format({
  props: { text: "This product is amazing!" },
});

for await (const message of query(adapted.query)) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

Tools

The Claude Agent SDK adapter handles tools differently from the AI SDK adapter. Instead of registering custom tool executors, you list tool names in your prompt frontmatter. The adapter passes these names through as allowedTools to the Claude Agent SDK. Tools can be any of the SDK’s built-in tools (Read, Write, Bash, etc.) or tools provided by MCP servers. Configure MCP servers on the client:
agentmark.client.ts
import { createAgentMarkClient, ClaudeAgentModelRegistry } from "@agentmark-ai/claude-agent-sdk-v0-adapter";

export const client = createAgentMarkClient({
  loader,
  modelRegistry,
  mcpServers: {
    weather: { url: "https://weather-mcp.example.com/sse" },
  },
});
The TypeScript field is mcpServers (camelCase). The Python adapter uses mcp_servers (snake_case).
Then reference tools by name in your prompts:
task.prompt.mdx
---
name: task
text_config:
  model_name: claude-sonnet-4-20250514
  tools:
    - weather
---

<System>You are a helpful assistant with access to weather data.</System>
<User>{props.task}</User>

Evals

Register evaluation functions for scoring prompt outputs during experiments. Score schemas are defined separately in agentmark.json; eval functions are connected to scores by name.
agentmark.client.ts
import type { EvalFunction } from "@agentmark-ai/prompt-core";

const evals: Record<string, EvalFunction> = {
  exact_match: ({ output, expectedOutput }) => ({
    passed: output === expectedOutput,
    score: output === expectedOutput ? 1 : 0,
  }),
};

export const client = createAgentMarkClient({
  loader,
  modelRegistry,
  evals,
});
Reference evals in your prompt frontmatter:
---
test_settings:
  dataset: ./datasets/test.jsonl
  evals:
    - exact_match
---
Learn more about evaluations

Tracing

Wrap query with withTracing to emit OpenTelemetry spans. Pass adapted.query and adapted.telemetry in an object:
import { client } from "./agentmark.client";
import { withTracing } from "@agentmark-ai/claude-agent-sdk-v0-adapter";
import { query } from "@anthropic-ai/claude-agent-sdk";

const prompt = await client.loadTextPrompt("task.prompt.mdx");
const adapted = await prompt.format({
  props: { task: "..." },
  telemetry: { isEnabled: true },
});

const result = await withTracing(query, {
  query: adapted.query,
  telemetry: adapted.telemetry,
});

console.log("Trace ID:", result.traceId);

for await (const message of result) {
  console.log(message);
}
Learn more in Tracing setup.

Getting started (Python)

Install the adapter and its dependencies:
pip install agentmark-claude-agent-sdk-v0 agentmark-prompt-core claude-agent-sdk
Create your AgentMark client in agentmark_client.py (see the Setup section above for the full create_claude_agent_client configuration). Optionally scaffold the AgentMark config and MCP wiring with the create tool:
npm create agentmark@latest my-app
The create tool writes agentmark.json, an empty agentmark/ directory for your .prompt.mdx files, and optional IDE MCP config. It does not prompt for a language or adapter, so add the Python adapter and client yourself as shown above. Run the local dev server:
npx agentmark dev

Limitations

  • No image generation. Use the AI SDK adapter for experimental_generateImage.
  • No speech generation. Use the AI SDK adapter for experimental_generateSpeech.
  • Messages stream as the agent runs via query() / traced_query(), but the final aggregated result is only available after all turns complete.

Next steps

Prompts

Learn about prompt syntax

Tools and agents

Configure tools for your agents

Observability

Monitor your agents in production

Other integrations

Explore other AI frameworks

Have Questions?

We’re here to help! Choose the best way to reach us: