SDK Reference

The dkod Agent SDK is the primary interface for AI agents to interact with the platform. Available in Rust (native) and Python (for most AI agent frameworks).


Design Principles

  1. Minimal context, maximum understanding — agents get exactly the context they need, no more
  2. Structured in, structured out — all inputs and outputs are typed, never raw text
  3. Fail informatively — when something goes wrong, the agent gets structured, machine-readable feedback
  4. Token-aware — the SDK tracks context window usage and helps agents manage their token budget
  5. Streaming-first — large responses stream so agents can start processing before the full response arrives

Python SDK

Connect to a Codebase

from dkod import DkodClient

client = DkodClient("agent.dkod.io:443", auth_token="dkod_key_...")
session = client.connect("org/repo", "Refactor auth to use OAuth2")

# session.session_id — unique session identifier
# session.codebase_version — codebase snapshot version
# session.summary — languages, total_symbols, total_files

Query Semantic Context

from dkod import ContextDepth

ctx = session.context(
    query="All functions involved in user authentication",
    depth=ContextDepth.FULL,        # ContextDepth.SIGNATURES | ContextDepth.FULL | ContextDepth.CALL_GRAPH
    include_tests=True,
    include_dependencies=False,
    max_tokens=8000                 # Cap response to fit context window
)

# ctx.symbols — list of Symbol objects
# ctx.call_graph — list[CallEdge] (caller/callee edges)
# ctx.estimated_tokens — tokens consumed by this response

Submit a Changeset

from dkod import DkodClient, Change, ChangeType, ContextDepth

client = DkodClient("agent.dkod.io:443", auth_token="dkod_key_...")
session = client.connect("org/repo", "Refactor auth to use OAuth2")

changes = [
    Change(
        type=ChangeType.MODIFY_FUNCTION,
        symbol_name="authenticate_user",
        file_path="src/auth/session.py",
        new_source='def authenticate_user(request):\n    """OAuth2 authentication."""\n    ...',
        rationale="Replace session-based auth with OAuth2 flow",
    ),
    Change(
        type=ChangeType.ADD_FUNCTION,
        symbol_name="refresh_oauth_token",
        file_path="src/auth/oauth.py",
        new_source='def refresh_oauth_token(token):\n    ...',
        rationale="Add token refresh capability",
    ),
]

result = session.submit(changes, "Replaced session auth with OAuth2")

Handle Results

from dkod import SubmitStatus

if result.status == SubmitStatus.ACCEPTED:
    print(f"Changeset {result.changeset_id} accepted")
    if result.new_version:
        print(f"New version: {result.new_version}")
elif result.status == SubmitStatus.CONFLICT:
    for error in result.errors:
        print(f"Conflict: {error.message}")
        if error.file_path:
            print(f"  in {error.file_path}")
elif result.status == SubmitStatus.REJECTED:
    for error in result.errors:
        print(f"Rejected: {error.message}")

Watch for Changes

Python SDK: Watch is not yet available. Use the Rust SDK or the dk_watch MCP tool.

Rust SDK

Connect and Query

use dk_agent_sdk::{AgentClient, Change, Depth};

#[tokio::main]
async fn main() -> Result<()> {
    let mut client = AgentClient::connect("http://localhost:50051", "my-token").await?;
    let mut session = client.init("org/repo", "Refactor auth to use OAuth2").await?;

    let ctx = session.context(
        "All functions involved in user auth",
        Depth::Full,
        4000,
    ).await?;

    // ctx.symbols — Vec<SymbolResult>
    // ctx.call_graph — Vec<CallEdgeRef>
    // ctx.estimated_tokens — u32

Submit and Handle Results

    let changes = vec![
        Change::modify("src/auth/session.rs", "// updated OAuth2 implementation"),
        Change::add("src/auth/oauth.rs", "// new OAuth2 token refresh"),
    ];
    let result = session.submit(changes).await?;

    println!("Changeset {} status: {}", result.changeset_id, result.status);
    if !result.errors.is_empty() {
        for err in &result.errors {
            eprintln!("Error: {}", err.message);
        }
    }

    Ok(())
}

MCP Tools

The dkod MCP server exposes 14 tools that agents call via the Model Context Protocol. These use the dk_ prefix and are the primary interface for IDE-integrated agents (Claude Code, Cursor, Cline, Windsurf, etc.).

ToolDescription
dk_connectEstablish an isolated session workspace
dk_contextQuery semantic context (symbols, call graphs, tests)
dk_file_readRead a file from the session's workspace
dk_file_writeWrite a file to the session's overlay
dk_file_listList files in the session's workspace
dk_submitSubmit changes for verification and merge
dk_verifyRun verification gates on a changeset
dk_reviewGet full code review findings (score, severity, category, suggestions)
dk_approveApprove a submitted changeset
dk_resolveResolve merge conflicts (proceed, keep_yours, keep_theirs, manual)
dk_mergeIntegrate an approved changeset internally (AST-level)
dk_pushPush integrated changes to a feature branch on GitHub and create a PR
dk_statusGet current session state, overlay info, and active conflicts
dk_watchSubscribe to real-time codebase events from other agents (auto-started on dk_connect)

Programmatic Tool Calling

For Claude-based agents using the Anthropic API, a subset of dkod operations are exposed as programmatically callable tools. These use the dkod_ prefix and enable multi-step workflows without model re-sampling between steps — reducing token cost by ~6x and wall-clock time by ~6x.

MCP vs Programmatic: MCP tools (dk_*) are called by agents through the MCP protocol — each call is a model round-trip. Programmatic tools (dkod_*) are called from within Claude's code execution sandbox — multiple calls execute without re-sampling the model. Use MCP for interactive agent workflows; use programmatic calling for batch operations where latency matters.

Programmatic Tools

The dkod-tools.json manifest defines tools for Anthropic's allowed_callers mechanism. Each dkod_* tool mirrors its dk_* MCP counterpart:

ToolDescription
dkod_connectEstablish an isolated session workspace
dkod_contextQuery semantic context (symbols, call graphs, tests)
dkod_file_readRead a file from the session's workspace
dkod_file_writeWrite a file to the session's overlay
dkod_file_listList files in the session's workspace
dkod_submitSubmit changes for verification and merge
dkod_verifyRun the verification pipeline on a changeset
dkod_approveApprove a submitted changeset
dkod_resolveResolve merge conflicts (proceed, keep_yours, keep_theirs, manual)
dkod_mergeIntegrate an approved changeset internally (AST-level)
dkod_pushPush integrated changes to GitHub as a branch/PR
dkod_statusGet current session state and overlay info
dkod_watchGet buffered events from other agents

How It Works

  1. Load the dkod tool manifest (dkod-tools.json)
  2. Claude writes Python code that calls dkod_* tools as async functions
  3. Tool calls execute in a sandboxed container — no model inference between calls
  4. Only the final output enters Claude's context window

Example: Full Agent Workflow

# Claude writes this. Each await pauses, calls the dkod tool,
# and resumes. The model is NOT re-sampled between calls.

import json

# 1. Connect — get an isolated workspace
session = await dkod_connect(
    repo="org/my-app",
    intent="Refactor auth from sessions to OAuth2"
)
session = json.loads(session)
sid = session["session_id"]

# 2. Query context
auth = await dkod_context(
    session_id=sid,
    query="All functions handling user authentication",
    depth="FULL"
)
auth = json.loads(auth)

# 3. Read and filter files (in code, not in model context)
files = {}
for sym in auth["symbols"]:
    content = await dkod_file_read(session_id=sid, path=sym["file_path"])
    files[sym["file_path"]] = json.loads(content)

relevant = {p: f for p, f in files.items() if "Session" in f["content"]}

# 4. Write updated files and check for conflicts
for path, content in relevant.items():
    new_code = content["content"].replace("Session", "OAuthToken")
    result = await dkod_file_write(session_id=sid, path=path, content=new_code)
    result = json.loads(result)

    if result.get("conflict_warnings"):
        for w in result["conflict_warnings"]:
            print(f"WARNING: {w['symbol_name']} also modified by {w['conflicting_agent']}")

# 5. Print summary — only this enters Claude's context
print(f"Found {len(auth['symbols'])} auth symbols")
print(f"{len(relevant)} files reference sessions")

Performance Comparison

Traditional tool use (MCP)Programmatic calling
Model round-trips102
Tokens consumed~50,000~8,000
Wall-clock time~30 seconds~5 seconds

MCP Tool Responses

dk_watch — event stream

Parameters: session_id (optional), filter (optional, default "*" for all events). The filter accepts predefined values or glob patterns: "all" or "*" (all events), "symbols" (symbol-change events only), "files" (file-change events only), or glob patterns like "changeset.*" and "*.merged". The Rust SDK provides a Filter enum for the common cases: All"all", Symbols"symbols", Files"files". Returns buffered watch events since last call.

{
  "events": [
    {
      "event_type": "symbol.modified",
      "changeset_id": "cs_xyz789",
      "agent_id": "claude-code-v3",
      "session_id": "sess_d4e5f6",
      "affected_symbols": ["authenticate_user"],
      "affected_files": ["src/auth/handler.rs"],
      "details": "Agent modified authenticate_user"
    }
  ]
}

dk_file_write — with soft conflict warning

When writing to a symbol that another active session has already modified, the write succeeds but returns a warning:

{
  "new_hash": "a3f8c2...",
  "detected_changes": [
    { "symbol_name": "authenticate_user", "change_type": "modified" }
  ],
  "conflict_warnings": [
    {
      "file_path": "src/auth/handler.rs",
      "symbol_name": "authenticate_user",
      "conflicting_agent": "claude-code-v3",
      "conflicting_session_id": "sess_x7y8z9",
      "message": "Symbol 'authenticate_user' was already modified by claude-code-v3"
    }
  ]
}

dk_submit — success

{
  "status": "accepted",
  "changeset_id": "cs_abc123",
  "review_summary": {
    "tier": "local",
    "score": 4,
    "findings_count": 1,
    "top_severity": "warning"
  }
}

dk_submit — hard conflict

When the same symbol was modified incompatibly by another session that already merged:

{
  "status": "conflict",
  "conflicting_symbols": [
    {
      "symbol": "authenticate_user",
      "file": "src/auth/handler.rs",
      "base_version": "fn authenticate_user(req: &Request) -> Result<User>",
      "their_change": {
        "description": "Added rate_limit parameter",
        "change_type": "modified"
      },
      "your_change": {
        "description": "Changed return type to Result<AuthToken>",
        "change_type": "modified"
      }
    }
  ],
  "suggested_action": "proceed",
  "available_actions": ["proceed", "keep_yours", "keep_theirs", "manual"]
}

dk_verify — result

{
  "status": "passed",
  "gates": [
    { "name": "typecheck", "status": "passed", "duration_ms": 1200 },
    { "name": "lint", "status": "passed", "duration_ms": 400 },
    { "name": "affected_tests", "status": "passed", "duration_ms": 8500 }
  ]
}

dk_merge — success

Parameters: force (bool, optional, default false) — force merge even when recently-merged symbols would be overwritten (bypasses OverwriteWarning).

{
  "status": "integrated",
  "merged_version": "v1848",
  "commit_hash": "e4f7a2b..."
}

dk_push — success

{
  "status": "pushed",
  "branch": "dkod/oauth2-refactor-a1b2c3",
  "pull_request_url": "https://github.com/org/repo/pull/42"
}

dk_merge — overwrite warning

Returned when your changeset would overwrite symbols recently merged by another agent. Use force: true to bypass.

{
  "status": "overwrite_warning",
  "warnings": [
    {
      "file_path": "src/auth/handler.rs",
      "symbol_name": "authenticate_user",
      "other_agent": "claude-code-v3",
      "merged_at": "2026-03-21T10:30:00Z"
    }
  ],
  "available_actions": ["proceed", "review", "abort"]
}

dk_merge — integration conflict

If another agent's changes were integrated between verification and this integration:

{
  "status": "conflict",
  "conflicting_symbols": [
    {
      "symbol": "authenticate_user",
      "file": "src/auth/handler.rs",
      "base_version": "fn authenticate_user(req: &Request) -> Result<User>",
      "their_change": { "description": "Modified by agent-2 after verification", "change_type": "modified" },
      "your_change": { "description": "Your verified changeset", "change_type": "modified" }
    }
  ],
  "suggested_action": "proceed",
  "available_actions": ["proceed", "keep_yours", "keep_theirs", "manual"]
}

See Conflict Types for the full taxonomy of auto-resolved, soft, and hard conflicts.

MCP Resources

The MCP server exposes three resources for agents to read session state:

Resource URIDescription
dkod://sessionCurrent session state (id, workspace, active files)
dkod://symbolsSemantic symbol graph for the codebase
dkod://changesetCurrent changeset info (pending changes, verification status)

SDK Features

Context Management

  • Semantic context queries (natural language or structured)
  • Symbol-level retrieval (specific functions, classes, modules)
  • Call graph traversal ("what calls this function?")
  • Dependency analysis ("what packages does this symbol use?")
  • Token-aware responses (count included, limits supported)
  • Incremental context updates (only what changed since last query)
  • Streaming for large responses

Changeset Submission

  • AST-level change descriptions
  • Atomic, all-or-nothing submission
  • Structured rationale per change
  • Verification gate selection
  • Auto-rebase on concurrent changes (if compatible)

Verification Integration

  • Real-time verification status streaming
  • Structured failure reports with AST context
  • Suggested fixes from the platform
  • Resubmit-after-fix flow (no reconnect needed)

Multi-Agent Coordination

  • Watch/subscribe to symbol changes
  • Conflict detection before submission
  • Agent-to-agent messaging via the platform
  • Work queue — platform assigns tasks to agents
  • Lock mechanism — exclusive write access to specific symbols

Session Lifecycle

  • Sessions may expire after a period of inactivity
  • Reconnect with the same intent to resume work

Observability

  • Session telemetry (queries, submissions, rejections)
  • Token usage tracking per session
  • Latency metrics
  • Complete audit trail (every agent action is logged)

Next Steps