Skip to main content

A terminal code agent powered by AI

Project description

ApeCode ๐Ÿฆง

A nano terminal code agent in Python โ€” a minimal but complete implementation of a tool-calling AI agent (like Claude Code / Codex CLI / Kimi CLI), built for learning and experimentation.

Powered by ApeCode.ai

Features

  • Tool-calling agent loop โ€” user โ†’ model โ†’ tool calls โ†’ tool results โ†’ model โ†’ response, with configurable max-steps guard
  • Multi-provider model adapters โ€” OpenAI, Anthropic, and Kimi (OpenAI-compatible), all conforming to a unified ChatModel protocol
  • 7 built-in tools โ€” list_files, read_file, write_file, replace_in_file, grep_files, exec_command, update_plan
  • Sandbox + approval model โ€” SandboxMode (read-only / workspace-write / danger-full-access) restricts path mutations; ApprovalPolicy (on-request / always / never) controls interactive confirmation for mutating operations
  • Plugin system โ€” declarative apecode_plugin.json manifests contribute tools, slash commands, and skills
  • MCP integration โ€” load external tools from .mcp.json / apecode_mcp.json via the fastmcp SDK
  • Slash commands โ€” /help, /tools, /skills, /skill, /plan, /subagents, /delegate, /exit
  • Subagent delegation โ€” isolated read-only agents with three default profiles: general, reviewer, researcher
  • Skill templates โ€” discoverable from skills/*/SKILL.md directories or plugins
  • REPL + one-shot mode โ€” interactive session with prompt-toolkit (history, tab-completion, multi-line via Alt+Enter) or single-prompt execution
  • Thinking model support โ€” displays reasoning_content from thinking models (e.g. Kimi K2.5)
  • AGENTS.md chain โ€” walks from workspace root to filesystem root, loading AGENTS.md files for project-specific instructions

Installation

uv sync

Dependencies: openai, anthropic, fastmcp, typer, rich, prompt-toolkit.

Usage

API keys

export OPENAI_API_KEY=your_key       # for provider=openai (default)
export ANTHROPIC_API_KEY=your_key    # for provider=anthropic
export KIMI_API_KEY=your_key         # for provider=kimi

Interactive REPL

uv run ape

One-shot mode

uv run ape "read README.md and summarize project structure"

CLI flags

uv run ape --provider openai --model gpt-4.1-mini    # default
uv run ape --provider anthropic --model claude-sonnet-4-20250514
uv run ape --provider kimi --model kimi-k2.5
uv run ape --max-steps 30 --timeout 180
uv run ape --cwd /path/to/repo
uv run ape --sandbox-mode read-only --approval-policy never
uv run ape --plugin-dir ./plugins
uv run ape --mcp-config ./.mcp.json
uv run ape --skill-dir ./custom-skills
uv run ape --yolo "apply a simple refactor in src/"
uv run ape --version

Slash commands (inside REPL)

/help                                          โ€” list all commands
/tools                                         โ€” list registered tools
/skills                                        โ€” list discovered skills
/skill concise-review review src/apecode/cli.py โ€” run a skill with extra request
/plan                                          โ€” show the current task plan
/subagents                                     โ€” list subagent profiles
/delegate reviewer:: review src/apecode/cli.py โ€” delegate to a subagent
/exit                                          โ€” quit

Architecture

user input
    โ”‚
    โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  cli.py โ€” Typer app, _build_runtime, REPL    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  NanoCodeAgent (agent.py)              โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ ChatModel โ”‚โ—„โ”€โ”€โ”‚ openai_client.py  โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ protocol  โ”‚   โ”‚ OpenAI/Anthropic/ โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚           โ”‚   โ”‚ Kimi adapters     โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚  โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚ ToolRegistry (tools.py)          โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚  7 built-in + plugin + MCP tools โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ”‚  ToolContext: sandbox + approval  โ”‚  โ”‚  โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  commands.py โ€” slash command registry        โ”‚
โ”‚  plugins.py  โ€” apecode_plugin.json loader    โ”‚
โ”‚  mcp.py      โ€” fastmcp stdio bridge          โ”‚
โ”‚  skills.py   โ€” SKILL.md discovery + catalog  โ”‚
โ”‚  subagents.py โ€” isolated read-only delegates โ”‚
โ”‚  system_prompt.py โ€” prompt builder + AGENTS.mdโ”‚
โ”‚  console.py  โ€” Rich + prompt-toolkit I/O     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Module breakdown

Module Purpose
cli.py Typer entry point, assembles runtime (_build_runtime), runs REPL or one-shot
agent.py NanoCodeAgent โ€” the core tool-calling loop with ChatModel protocol
tools.py ToolRegistry, ToolContext (sandbox/approval), 7 built-in tool handlers
openai_client.py OpenAIChatCompletionsClient, AnthropicMessagesClient, KimiChatCompletionsClient โ€” all adapters convert to/from internal OpenAI message format
commands.py CommandRegistry + SlashCommand โ€” /help, /tools, /exit, etc.
plugins.py Loads apecode_plugin.json manifests; registers tools, commands, skills
mcp.py Parses .mcp.json, connects via fastmcp.Client, registers MCP tools
skills.py SkillCatalog โ€” discovers SKILL.md files, supports plugin-contributed skills
subagents.py SubagentRunner โ€” spawns isolated agents with read-only tools and capped steps
system_prompt.py Builds system prompt with environment info, AGENTS.md chain, skill catalog
console.py Rich console output (panels, spinners, tool call display) + prompt-toolkit input session

Environment Variables

Variable Default Description
APECODE_PROVIDER openai Model provider (openai / anthropic / kimi)
APECODE_MODEL gpt-4.1-mini Model name
APECODE_SANDBOX_MODE workspace-write Sandbox mode (read-only / workspace-write / danger-full-access)
APECODE_APPROVAL_POLICY on-request Approval policy (on-request / always / never)
OPENAI_API_KEY โ€” OpenAI API key
OPENAI_BASE_URL https://api.openai.com/v1 Custom OpenAI-compatible endpoint
ANTHROPIC_API_KEY โ€” Anthropic API key
ANTHROPIC_BASE_URL https://api.anthropic.com/v1 Custom Anthropic endpoint
ANTHROPIC_API_VERSION 2023-06-01 Anthropic API version header
KIMI_API_KEY โ€” Kimi API key
KIMI_BASE_URL https://api.moonshot.cn/v1 Kimi endpoint

Plugin System

Place a plugin manifest as apecode_plugin.json in a plugin directory:

{
  "name": "EchoPlugin",
  "tools": [
    {
      "name": "echo_text",
      "description": "Echo text from JSON args",
      "parameters": {
        "type": "object",
        "properties": { "text": { "type": "string" } },
        "required": ["text"],
        "additionalProperties": false
      },
      "argv": ["python3", "/absolute/path/to/tool.py"],
      "mutating": false,
      "timeout_sec": 60
    }
  ],
  "commands": [
    {
      "name": "quick-review",
      "description": "Run plugin prompt template",
      "usage": "/quick-review <task>",
      "output": "Running quick review...",
      "agent_input_template": "Review this task:\\n{args}"
    }
  ],
  "skills": [
    {
      "name": "plugin-skill",
      "description": "A plugin-provided skill",
      "content": "# Plugin Skill\\n\\nKeep output concise."
    }
  ]
}
  • Tools use either argv (recommended) or command to specify the executable.
  • Tool processes receive JSON arguments on stdin and write results to stdout.
  • Commands support {args} placeholder in agent_input_template.
  • Skills can use inline content or a file path relative to the manifest.

MCP Config

Load MCP tools from .mcp.json or apecode_mcp.json in workspace root, or via --mcp-config:

{
  "mcpServers": {
    "demo": {
      "command": "python3",
      "args": ["/absolute/path/to/mcp_server.py"],
      "timeout_sec": 30
    }
  }
}

Skills

Create a skill as skills/<name>/SKILL.md:

# concise-review

Review code and answer with concise bullet points.

Use inside REPL:

/skill concise-review review src/apecode/agent.py

Development

# Install dev dependencies
uv sync

# Run tests
uv run pytest

# Run a single test file
uv run pytest tests/test_tools.py -v

# Lint
uv run ruff check src/ tests/

# Lint with auto-fix
uv run ruff check --fix src/ tests/

# Format
uv run ruff format src/ tests/

Project Structure

src/apecode/
โ”œโ”€โ”€ __init__.py          # package version
โ”œโ”€โ”€ __main__.py          # python -m apecode entry
โ”œโ”€โ”€ cli.py               # Typer CLI app + runtime assembly
โ”œโ”€โ”€ agent.py             # NanoCodeAgent core loop
โ”œโ”€โ”€ tools.py             # tool registry + built-in tools
โ”œโ”€โ”€ openai_client.py     # model adapters (OpenAI/Anthropic/Kimi)
โ”œโ”€โ”€ commands.py          # slash command framework
โ”œโ”€โ”€ plugins.py           # plugin manifest loader
โ”œโ”€โ”€ mcp.py               # MCP stdio bridge
โ”œโ”€โ”€ skills.py            # skill discovery + catalog
โ”œโ”€โ”€ subagents.py         # subagent delegation
โ”œโ”€โ”€ system_prompt.py     # system prompt builder
โ””โ”€โ”€ console.py           # Rich + prompt-toolkit I/O
tests/
โ”œโ”€โ”€ test_agent.py
โ”œโ”€โ”€ test_commands.py
โ”œโ”€โ”€ test_mcp.py
โ”œโ”€โ”€ test_model_adapters.py
โ”œโ”€โ”€ test_plugins.py
โ”œโ”€โ”€ test_skills.py
โ”œโ”€โ”€ test_subagents.py
โ””โ”€โ”€ test_tools.py

License

Apache-2.0

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

apecode-0.0.2.tar.gz (90.2 kB view details)

Uploaded Source

Built Distribution

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

apecode-0.0.2-py3-none-any.whl (37.9 kB view details)

Uploaded Python 3

File details

Details for the file apecode-0.0.2.tar.gz.

File metadata

  • Download URL: apecode-0.0.2.tar.gz
  • Upload date:
  • Size: 90.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.15

File hashes

Hashes for apecode-0.0.2.tar.gz
Algorithm Hash digest
SHA256 d50380038d64310c4e47aeca74b2b891b555996063698ef57a0b923a8b60eef7
MD5 7d23ecd4cd386ebc61fbb06366c46612
BLAKE2b-256 713c07a541e11afbe60fd31df2e538761f8f45bd0094895f38edebfc5a62ffd7

See more details on using hashes here.

File details

Details for the file apecode-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: apecode-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 37.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.15

File hashes

Hashes for apecode-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 631daeecc7145925f93f49bf8627831c2187c11e0998719f353d304a015c7828
MD5 bab6ab32635e080f69ff159e45fabb33
BLAKE2b-256 911e6482faf87de2a62fd367e565b0d1129ef96c99d3ee5c41f1055215487910

See more details on using hashes here.

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