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
- Minimal context, maximum understanding — agents get exactly the context they need, no more
- Structured in, structured out — all inputs and outputs are typed, never raw text
- Fail informatively — when something goes wrong, the agent gets structured, machine-readable feedback
- Token-aware — the SDK tracks context window usage and helps agents manage their token budget
- 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_filesQuery 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 responseSubmit 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_watchMCP 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 — u32Submit 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.).
| Tool | Description |
|---|---|
dk_connect | Establish an isolated session workspace |
dk_context | Query semantic context (symbols, call graphs, tests) |
dk_file_read | Read a file from the session's workspace |
dk_file_write | Write a file to the session's overlay |
dk_file_list | List files in the session's workspace |
dk_submit | Submit changes for verification and merge |
dk_verify | Run verification gates on a changeset |
dk_review | Get full code review findings (score, severity, category, suggestions) |
dk_approve | Approve a submitted changeset |
dk_resolve | Resolve merge conflicts (proceed, keep_yours, keep_theirs, manual) |
dk_merge | Integrate an approved changeset internally (AST-level) |
dk_push | Push integrated changes to a feature branch on GitHub and create a PR |
dk_status | Get current session state, overlay info, and active conflicts |
dk_watch | Subscribe 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:
| Tool | Description |
|---|---|
dkod_connect | Establish an isolated session workspace |
dkod_context | Query semantic context (symbols, call graphs, tests) |
dkod_file_read | Read a file from the session's workspace |
dkod_file_write | Write a file to the session's overlay |
dkod_file_list | List files in the session's workspace |
dkod_submit | Submit changes for verification and merge |
dkod_verify | Run the verification pipeline on a changeset |
dkod_approve | Approve a submitted changeset |
dkod_resolve | Resolve merge conflicts (proceed, keep_yours, keep_theirs, manual) |
dkod_merge | Integrate an approved changeset internally (AST-level) |
dkod_push | Push integrated changes to GitHub as a branch/PR |
dkod_status | Get current session state and overlay info |
dkod_watch | Get buffered events from other agents |
How It Works
- Load the dkod tool manifest (
dkod-tools.json) - Claude writes Python code that calls
dkod_*tools as async functions - Tool calls execute in a sandboxed container — no model inference between calls
- 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-trips | 10 | 2 |
| 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 URI | Description |
|---|---|
dkod://session | Current session state (id, workspace, active files) |
dkod://symbols | Semantic symbol graph for the codebase |
dkod://changeset | Current 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
- Agent Protocol — understand the protocol the SDK implements
- Quickstart — try the SDK locally
- CLI Reference — the human-facing command-line interface