Skip to main content

Pydantic AI model adapter for Claude Code CLI

Project description

claude-code-model

Pydantic AI model adapter for Claude Code CLI — type-safe agents on your Max subscription.

Use Pydantic AI's powerful agent framework with Claude Code CLI instead of API calls. Get structured outputs, tool calling, and full type safety without per-token costs.

Why Use This?

Approach Cost Type Safety Structured Output Tool Calling
Raw claude -p $0
Pydantic AI + API $$$ per token
claude-code-model $0

If you have a Claude Max subscription ($100-200/month), you get unlimited Claude access via CLI. This adapter lets you use that access with Pydantic AI's excellent developer experience.

Installation

# 1. Install Claude Code CLI (if not already installed)
npm install -g @anthropic-ai/claude-code

# 2. Authenticate
claude auth

# 3. Install this package
pip install claude-code-model

Quick Start

Structured Output

Get type-safe responses with automatic validation:

from pydantic import BaseModel
from pydantic_ai import Agent
from claude_code_model import ClaudeCodeModel

class ReviewResult(BaseModel):
    verdict: str  # APPROVE, REQUEST_CHANGES, COMMENT
    issues: list[str]
    suggestions: list[str]

agent = Agent(
    ClaudeCodeModel(),
    result_type=ReviewResult,
    system_prompt="You are a code reviewer. Return structured JSON."
)

result = agent.run_sync("Review this code: def add(a,b): return a+b")

# Result is fully typed!
print(result.data.verdict)  # IDE autocomplete works
print(result.data.issues)   # Type checking works

Tool Calling

Give your agent functions it can call:

from pydantic_ai import Agent
from claude_code_model import ClaudeCodeModel

agent = Agent(ClaudeCodeModel())

@agent.tool_plain
def read_file(path: str) -> str:
    """Read a file from disk."""
    return Path(path).read_text()

@agent.tool_plain
def list_files(directory: str = ".") -> list[str]:
    """List files in a directory."""
    return [f.name for f in Path(directory).iterdir()]

result = agent.run_sync("What Python files are in the current directory?")
# Agent automatically calls list_files() and uses the results

Multi-Agent Systems

Different models for different tasks:

from claude_code_model import ClaudeCodeModel

# Fast agent for quick tasks
researcher = Agent(
    ClaudeCodeModel(model="haiku"),
    system_prompt="Quick research"
)

# Powerful agent for analysis
analyst = Agent(
    ClaudeCodeModel(model="sonnet"),
    system_prompt="Deep analysis"
)

# Analyst can delegate to researcher
@analyst.tool_plain
async def research(topic: str) -> str:
    result = await researcher.run(f"Research {topic}")
    return result.data

Features

  • Zero API Costs: Uses your Claude Max subscription
  • Full Pydantic AI Compatibility: Structured outputs, tools, deps, async
  • Type Safety: Full IDE autocomplete and type checking
  • Multiple Models: sonnet (default), opus, haiku
  • Tool Calling: Give agents functions to call
  • Async Support: Full async/await support
  • Simple: <500 lines of code, easy to audit

Configuration

from claude_code_model import ClaudeCodeModel
from pathlib import Path

model = ClaudeCodeModel(
    model="sonnet",      # "sonnet" | "opus" | "haiku"
    timeout=300,         # seconds
    cwd=Path("/path"),   # working directory for CLI
)

Examples

The examples/ directory contains working examples:

  • simple.py: Structured output for code review
  • with_tools.py: File system tools with interactive chat
  • multi_agent.py: Multi-agent delegation pattern

Run them:

uv run python examples/simple.py
uv run python examples/with_tools.py

How It Works

┌─────────────────────────────────────────┐
│  Your Code                              │
│  agent = Agent(ClaudeCodeModel())       │
│  result = agent.run_sync("prompt")      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Pydantic AI                            │
│  - Manages conversation state           │
│  - Handles tool calls and retries       │
│  - Validates output against schema      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  claude-code-model                      │
│  - Converts messages → prompt string    │
│  - Adds JSON schema instructions        │
│  - Calls CLI wrapper                    │
│  - Parses response → ModelResponse      │
└──────────────┬──────────────────────────┘
               │
               ▼
┌─────────────────────────────────────────┐
│  Claude Code CLI                        │
│  $ claude -p "prompt" --model sonnet    │
│  > {"verdict": "APPROVE", "issues": []} │
└─────────────────────────────────────────┘

The adapter translates between Pydantic AI's message format and Claude CLI's prompt-response model. It handles:

  • System prompts, user messages, tool calls, tool results
  • JSON extraction from various response formats
  • Tool call detection and parsing
  • Structured output validation

API Reference

ClaudeCodeModel

Main model class implementing Pydantic AI's Model interface.

@dataclass
class ClaudeCodeModel(Model):
    model: Literal["sonnet", "opus", "haiku"] = "sonnet"
    timeout: int = 300  # seconds
    cwd: Path | None = None

Exceptions

from claude_code_model import (
    ClaudeCodeError,           # Base exception
    ClaudeCodeNotFoundError,   # CLI not installed
    ClaudeCodeTimeoutError,    # Command timed out
    ClaudeCodeExecutionError,  # Non-zero exit code
)

Limitations

  • No streaming: CLI doesn't support streaming well
  • No token counting: CLI doesn't report usage (returns 0)
  • No concurrent calls: Run one request at a time
  • Text-only: No image inputs (CLI limitation)
  • Rate limits: Subject to Claude Max rate limits

Development

# Setup
git clone https://github.com/yourusername/claude-code-model.git
cd claude-code-model
uv sync

# Run tests
uv run pytest

# Run tests with coverage
uv run pytest --cov=claude_code_model

# Type check
uv run mypy src/

# Lint
uv run ruff check src/ tests/
uv run ruff format src/ tests/

# Run example
uv run python examples/simple.py

Requirements

  • Python 3.11+
  • Claude Code CLI installed and authenticated
  • Claude Max subscription (for unlimited CLI access)
  • pydantic-ai >= 0.1.0
  • pydantic >= 2.0.0

Contributing

Contributions welcome! Please:

  1. Keep changes focused and small (<200 lines)
  2. Add tests for new functionality
  3. Ensure pytest, mypy, and ruff all pass
  4. Update README if adding features

See CLAUDE.md for development guide.

License

MIT License - see LICENSE file for details.

Credits

Built with:

Disclaimer

This is an unofficial adapter, not affiliated with Anthropic. Use in accordance with Claude's Terms of Service. You are responsible for ensuring your usage complies with Anthropic's policies.

Support

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_code_model-0.2.1.tar.gz (232.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_code_model-0.2.1-py3-none-any.whl (10.0 kB view details)

Uploaded Python 3

File details

Details for the file claude_code_model-0.2.1.tar.gz.

File metadata

  • Download URL: claude_code_model-0.2.1.tar.gz
  • Upload date:
  • Size: 232.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for claude_code_model-0.2.1.tar.gz
Algorithm Hash digest
SHA256 a6647135fad846c1d87ad56791876ac8db0044c8964484549394e8ff8b0f138a
MD5 103033180c239e390bb9b37b1f2aa9be
BLAKE2b-256 af29623f3ec596d7ae165b82132392063256516adb03b516adae693d3fc66c36

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_code_model-0.2.1.tar.gz:

Publisher: publish.yml on aleksandr-bogdanov/claude-code-model

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_code_model-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_code_model-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a2d8643fdf7e044bee828ef26616dbdd37942b8fdbddf1cfdd62ef812d5020dd
MD5 b6450261778fdeeb0cb80f36bb4b3388
BLAKE2b-256 e7e26964df2473c45e4c810ecf4919694a0ea339687c6199973e62a0332493ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_code_model-0.2.1-py3-none-any.whl:

Publisher: publish.yml on aleksandr-bogdanov/claude-code-model

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page