Skip to main content

Introduction

Craft Agents is a flexible AI agent framework built around workspaces, sessions, and agent backends. The architecture emphasizes isolation boundaries, multi-provider support, and extensibility through sources (MCP servers and API connections).

Core Architecture

Workspaces

Project-scoped configuration with isolated sources and sessions

Sessions

Conversation boundaries with 1:1 SDK session mapping

Agent Backends

Provider-agnostic agent implementations (Claude, Pi, OpenAI)

Sources

MCP servers and API connections for external data

Key Design Principles

Sessions as Primary Boundary

Sessions are the primary isolation boundary in Craft Agents, not workspaces:
  • Each session maps 1:1 with an SDK session (Claude Agent SDK, Pi SDK, etc.)
  • Sessions have their own permission mode, working directory, and conversation history
  • Multiple sessions can coexist in the same workspace with different configurations
  • Sessions persist their complete state (messages, token usage, metadata) in JSONL format
Why sessions? This design allows multiple conversations with different contexts to run in the same project without contaminating each other’s state.

Multi-Provider Support

The BaseAgent abstract class provides a unified interface across AI providers:
import type { AgentBackend } from '@craft-agent/shared/agent';

// All backends implement the same interface
interface AgentBackend {
  chat(message: string): AsyncGenerator<AgentEvent>;
  abort(reason?: string): Promise<void>;
  getModel(): string;
  setModel(model: string): void;
  getPermissionMode(): PermissionMode;
  // ... and more
}
Supported backends:
  • ClaudeAgent - Anthropic Claude models via Claude Agent SDK
  • PiAgent - Pi coding agents via Pi SDK (subprocess)
  • CodexAgent - OpenAI models via Codex app-server (planned)
  • CopilotAgent - GitHub Copilot integration (planned)

Source Architecture

Sources are workspace-scoped external data connections that provide tools to agents:
Model Context Protocol servers running as subprocesses:
{
  "type": "mcp",
  "slug": "linear",
  "name": "Linear",
  "command": "npx",
  "args": ["-y", "@linear/mcp"],
  "env": { "LINEAR_API_KEY": "{{credential}}" }
}
Direct HTTP API integrations with authentication:
{
  "type": "api",
  "slug": "github",
  "name": "GitHub",
  "baseUrl": "https://api.github.com",
  "authType": "bearer",
  "endpoints": [
    {
      "method": "GET",
      "path": "/repos/{owner}/{repo}/issues",
      "description": "List repository issues"
    }
  ]
}
Local filesystem directories with custom tools:
{
  "type": "local",
  "slug": "knowledge-base",
  "name": "Knowledge Base",
  "paths": ["/path/to/docs"]
}

Permission System

Three-level permission modes provide granular control over agent actions:
ModeDisplayBehavior
safeExploreRead-only, blocks all write operations
askAsk to EditPrompts for bash commands (default)
allow-allAutoAuto-approves all commands
Permission mode is per-session, allowing different trust levels for different conversations in the same workspace.

Data Flow

Event Stream

All agent backends emit standardized AgentEvent types:
type AgentEvent =
  | { type: 'text'; text: string }
  | { type: 'tool_start'; toolName: string; input: unknown }
  | { type: 'tool_result'; result: string }
  | { type: 'permission_request'; requestId: string; toolName: string }
  | { type: 'complete' }
  | { type: 'error'; message: string };
The event stream provides a provider-agnostic interface for rendering agent activity in the UI.

Storage Layout

All data is stored under ~/.craft-agent/:
~/.craft-agent/
├── config.json                 # Global config, LLM connections
├── credentials.enc             # Encrypted credentials (AES-256-GCM)
├── docs/                       # Bundled documentation
├── workspaces/
│   └── {workspace-id}/
│       ├── config.json         # Workspace metadata
│       ├── theme.json          # Workspace theme overrides
│       ├── permissions.json    # Workspace permission rules
│       ├── statuses/           # Custom workflow statuses
│       ├── sources/
│       │   └── {slug}/
│       │       ├── config.json # Source configuration
│       │       └── guide.md    # Usage guidelines
│       └── sessions/
│           └── {session-id}/
│               ├── session.jsonl      # Messages + header
│               ├── attachments/       # File attachments
│               ├── plans/            # Plan files
│               ├── data/             # Transform output
│               └── long_responses/   # Summarized results
JSONL Format: Sessions use JSONL (JSON Lines) for efficient streaming writes and incremental reads. Line 1 is the header (metadata), subsequent lines are messages.

Package Structure

The codebase is organized as a monorepo:
packages/
├── core/              # Shared TypeScript types
├── shared/            # Business logic (agent, auth, config)
├── ui/                # React components
├── session-mcp-server/    # Session-scoped MCP tools
├── pi-agent-server/       # Pi SDK subprocess wrapper
└── bridge-mcp-server/     # API source bridge (planned)

apps/
├── electron/          # Main Electron app
└── web-viewer/        # Standalone session viewer

Next Steps

Workspaces

Learn about workspace configuration and storage

Sessions

Understand session lifecycle and persistence

Agents

Explore agent backends and the BaseAgent class

Sources

Configure MCP servers and API connections

Build docs developers (and LLMs) love