Skip to content
Conduit

mcp server

unchain

A lightweight Python agent framework for building tool-using AI runtimes.

haoxiang-xu/unchaincommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "unchain": {
      "command": "uvx",
      "args": [
        "unchain"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 25, 2026

Version Python License

Docs: English | 中文


What is unchain?

unchain is a modular agent framework that separates agent configuration from execution. It provides a harness-driven kernel loop, pluggable provider support, multi-tier memory, and a rich tool system — all composable through a clean module API.

Everything lives under one package: src/unchain/. Agent behaviour is composed by passing modules (ToolsModule, MemoryModule, PoliciesModule, OptimizersModule, SubagentModule, ToolDiscoveryModule) into Agent.

Install

pip install -e ".[dev]"

Prerequisites: Python 3.12+

uv sync --locked --all-extras installs the reviewed dependency versions. The legacy requirements.txt retains the notebook environment and can be installed alongside -e ".[dev]".

To retain Intel macOS and 32-bit Windows support, cryptography is temporarily held at >=48.0.1,<49. Three advisories remain open pending a compatible upstream fix or a separate platform-support decision: GHSA-g6cj-pr64-35w5, GHSA-jwv3-5hgf-82ww, and GHSA-m2h6-j472-rp4c.

Quick Start

from unchain import Agent
from unchain.agent import ToolsModule
from unchain.toolkits import CoreToolkit

agent = Agent(
    name="coder",
    provider="openai",
    model="gpt-5",
    instructions="You are a coding assistant.",
    modules=(
        ToolsModule(tools=(CoreToolkit(workspace_root="."),)),
    ),
)

result = agent.run("Inspect the repo and explain what matters.")
print(result.messages[-1]["content"])

Custom Tools

from unchain import Agent
from unchain.agent import ToolsModule
from unchain.tools import tool

@tool
def fetch_price(ticker: str) -> dict:
    """Fetch the latest stock price for a given ticker symbol."""
    return {"ticker": ticker, "price": 142.50}

agent = Agent(
    name="analyst",
    provider="anthropic",
    model="claude-sonnet-4",
    modules=(ToolsModule(tools=(fetch_price,)),),
)

Subagents (multi-agent work)

Team is no longer a top-level primitive. Compose multi-agent flows by giving a planner agent a SubagentModule so it can spawn typed children:

from unchain import Agent
from unchain.agent import SubagentModule
from unchain.subagents import SubagentPolicy, SubagentTemplate

planner = Agent(
    name="planner",
    provider="openai",
    model="gpt-5",
    instructions="Plan the work, then delegate.",
    modules=(
        SubagentModule(
            templates=(
                SubagentTemplate(name="researcher", instructions="Research the question."),
                SubagentTemplate(name="writer", instructions="Write a report from the research."),
            ),
            policy=SubagentPolicy(max_depth=4, max_total_agents=8),
        ),
    ),
)

result = planner.run("Write a report on recent AI trends.")

The planner gets delegate_to_subagent, handoff_to_subagent, and spawn_worker_batch tools; see docs/en/skills/agent-and-team.md for the full surface.

Architecture

Agent.run(messages)
  |
  v
AgentBuilder --> PreparedAgent --> KernelLoop.run()
                                      |
                    +------ step_once() loop ------+
                    |                              |
                    v                              v
            dispatch_phase()              fetch_model_turn()
            (harnesses run)               (provider SDK call)
                    |                              |
                    v                              v
          Memory / Optimizers             Tool Execution
          Context Injection               Confirmation Gates
                    |                     Human Input Suspend
                    v
             HarnessDelta applied to RunState
                    |
                    v
              KernelRunResult

Kernel Phases

Harnesses plug into these runtime phases:

PhaseWhenExample
bootstrapRun initializationLoad memory
before_modelBefore each LLM callInject context, optimize window
after_modelAfter LLM responseProcess response
on_tool_callPer tool invocationConfirmation gates
after_tool_batchAll tools in batch doneCommit observations
before_commitBefore memory persistFinalize state
on_suspend / on_resumePause/resumeHuman input flow

Delta-Based State

All state mutations flow through immutable HarnessDelta objects:

HarnessDelta.append(
    created_by="my_harness",
    messages=[{"role": "assistant", "content": "..."}],
    state_updates={"my_key": value},
)

Providers

ProviderModelsStreamingToolsReasoning
OpenAIgpt-5, gpt-4.1, gpt-5-codexYesYesYes (gpt-5)
Anthropicclaude-sonnet-4, claude-opus-4-6, claude-haiku-3.5YesYesYes (thinking)
Google Geminigemini-3.8-flash, gemini-3.6-flash, gemini-3.5-flash, gemini-3.1-pro-previewYesYesYes (thinking levels)
OllamaAny local modelYesYesModel-dependent
SAP Hyperspacehyperspace--claude-opus-4-6/4-7, hyperspace--claude-sonnet-4-6, hyperspace--claude-haiku-4-5YesYesYes (thinking)

Configure via environment variables:

OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=...

Built-in Toolkits

ToolkitDescription
CoreToolkitFile read/write, directory listing, text search, line editing, shell execution, LSP, web fetch, structured user questions
PlanToolkitWorkspace-backed structured planning with draft, update, read, list, and finalize tools
AgentReachToolkitRead-only Agent Reach helpers for status checks, web pages, and YouTube metadata
MCPToolkitBridge MCP (Model Context Protocol) servers as native toolkits

Toolkits are also discoverable from local directories and entry-point plugins.

Skills

Drop a SKILL.md (or flat <name>.md) file into .unchain/skills/<name>/ or .agents/skills/<name>/, add SkillsModule() to the agent's modules, and it's discovered automatically — no registration code needed. SkillsModule renders a name+description catalog, exposes a skill tool the model can call to activate one by name, and lets the user activate one directly with /name in their own message. Activations are projected into a durable <active_skills> system block that survives compaction, resume, and cold restart.

See Agent Skills for the full frontmatter contract, discovery roots, and wire format.

Memory System

Two-tier memory with pluggable backends:

from unchain.memory import MemoryConfig, MemoryManager

config = MemoryConfig(
    last_n_turns=8,
    vector_top_k=4,
    long_term_enabled=True,
)
TierStoragePurpose
Short-termIn-memory / JSON sessionsRecent conversation context
Long-termQdrant vector DBSemantic recall, fact extraction, profiles

Strategies: LastNTurns, SummaryToken, Hybrid

Modules

Agents are composed through pluggable modules:

from unchain.agent import Agent, ToolsModule, MemoryModule, PoliciesModule
from unchain.toolkits import CoreToolkit

core_toolkit = CoreToolkit(workspace_root=".")

agent = Agent(
    name="assistant",
    provider="openai",
    model="gpt-5",
    modules=(
        ToolsModule(tools=(core_toolkit,)),
        MemoryModule(memory=memory_manager),
        PoliciesModule(max_iterations=32),
    ),
)
ModulePurpose
ToolsModuleRegister tools and toolkits
MemoryModuleAttach memory manager
PoliciesModuleSet iteration limits, subagent policies
OptimizersModuleContext window optimizers
SubagentModuleRegister subagent templates

Subagents

Agents can delegate, handoff, or spawn parallel workers:

from unchain.agent import SubagentModule
from unchain.subagents import SubagentTemplate

templates = [
    SubagentTemplate(name="researcher", agent=research_agent, allowed_modes=("delegate",)),
    SubagentTemplate(name="coder", agent=code_agent, allowed_modes=("worker",), parallel_safe=True),
]

parent = Agent(
    name="coordinator",
    modules=(SubagentModule(templates=templates),),
    ...
)

Context Optimizers

Pluggable strategies for managing the context window:

OptimizerStrategy
LastNOptimizerKeep last N messages
LlmSummaryOptimizerSummarize older messages with LLM
ToolHistoryCompactionOptimizerCompress verbose tool results
PinnedContextOptimizerPreserve pinned file context
SlidingWindowOptimizerToken-aware context window truncation

Package Layout

src/
  unchain/
    __init__.py               # Public API: Agent
    agent/                    # Agent, AgentBuilder, PreparedAgent, modules
    kernel/                   # KernelLoop, RuntimeHarness, RuntimePhase, types
    providers/                # OpenAI, Anthropic, Ollama ModelIO
    tools/                    # Tool, Toolkit, registry, catalog, discovery, execution
    toolkits/                 # CoreToolkit, PlanToolkit, AgentReachToolkit, MCPToolkit
    memory/                   # MemoryManager, KernelMemoryRuntime, harnesses
    optimizers/               # Context window / token compaction harnesses
    subagents/                # Subagent executor + delegation tools
    retry/                    # Provider-agnostic retry layer
    schemas/                  # ResponseFormat (structured output)
    input/                    # Human input + media
    character/                # Persona / instruction helpers
    runtime/                  # Legacy Broth runtime kept only for LegacyBrothModelIO
    types/                    # Shared type aliases
tests/
  evals/                      # Scenario-based evaluation framework
docs/
  en/                         # English docs (skills chapters + API reference)
  zh-CN/                      # Chinese docs

Public API

# Top-level
from unchain import Agent

# Agent + modules
from unchain.agent import (
    AgentBuilder, PreparedAgent,
    ToolsModule, MemoryModule, PoliciesModule,
    OptimizersModule, SubagentModule, ToolDiscoveryModule,
)

# Kernel
from unchain.kernel import KernelLoop, KernelRunResult, RunState, RuntimeHarness, RuntimePhase

# Tools
from unchain.tools import (
    Tool, Toolkit, tool, ToolParameter, ToolkitRegistry,
    ToolkitCatalogRuntime, ToolkitCatalogConfig,
    ToolDiscoveryRuntime, ToolDiscoveryConfig,
)

# Providers
from unchain.providers import OpenAIModelIO, AnthropicModelIO, OllamaModelIO

# Toolkits
from unchain.toolkits import AgentReachToolkit, CoreToolkit, MCPToolkit, PlanToolkit

# Memory
from unchain.memory import MemoryConfig, MemoryManager, KernelMemoryRuntime

# Subagents
from unchain.subagents import SubagentPolicy, SubagentTemplate, SubagentExecutor

# Schemas
from unchain.schemas import ResponseFormat

Testing

# Setup
./scripts/init_python312_venv.sh

# Run tests
./run_tests.sh

# Or directly
PYTHONPATH=src pytest tests/ -q

Documentation

Full bilingual docs with skills chapters and API reference:

Skills Chapters: Architecture Overview, Agent & Subagents, Runtime Engine, Tool System Patterns, Memory System, Creating Toolkits, Testing Conventions

API Reference: Agents, Runtime, Interaction, Durable Jobs, Tools, Toolkits, Memory, Input/Workspace/Schemas

Appendices: Class Index (55+ classes), Export Index, Glossary, Return Shapes

See docs/README.en.md for the full reading guide.

License

Apache 2.0

↑↓ navigate openesc close