Plan Forge
MCP server for iterative AI planning loops - planner and reviewer agents refine plans until approved
Ask AI about Plan Forge
Powered by Claude Β· Grounded in docs
I know everything about Plan Forge. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
plan-forge
A CLI tool for iterative AI-driven development planning. Uses LLM agents to generate comprehensive development plans, review them for quality, and refine based on feedback.
Table of Contents
- Features
- Installation
- Quick Start
- Usage
- Writing Effective Tasks
- Configuration
- Providers
- MCP Extensions
- Architecture
- MCP Server
- Development
- Contributing
- License
- Changelog
Features
- Iterative Plan-Review Loop: Generates plans, reviews them for gaps and clarity, and refines until quality threshold is met
- Multiple LLM Providers: Supports Anthropic, OpenAI, LiteLLM, Microsoft Foundry, and other providers via goose
- MCP Server: Expose planning tools to AI assistants (Claude Code, Cursor, VS Code)
- Customizable Recipes: Configure prompts, models, and MCP server extensions via YAML files
- Structured Output: Plans are validated against JSON schemas and exported as markdown
- Resume Workflow: Pick up where you left off with feedback-driven refinement
Installation
Shell Installer (Recommended)
The easiest way to install plan-forge on Linux or macOS:
curl -sSL https://raw.githubusercontent.com/andrey-moor/plan-forge/main/install.sh | sh
Note: Review the install.sh script before running if you prefer to inspect it first.
Options:
# Install specific version
VERSION=v0.1.0 curl -sSL https://raw.githubusercontent.com/andrey-moor/plan-forge/main/install.sh | sh
# Install to custom directory
INSTALL_DIR=/opt/bin curl -sSL https://raw.githubusercontent.com/andrey-moor/plan-forge/main/install.sh | sh
Binary Downloads
Pre-built binaries are available from GitHub Releases.
Supported platforms:
| Platform | Architecture | Archive |
|---|---|---|
| Linux | x86_64 | plan-forge-x86_64-unknown-linux-gnu.tar.gz |
| Linux | aarch64 (ARM64) | plan-forge-aarch64-unknown-linux-gnu.tar.gz |
| macOS | x86_64 (Intel) | plan-forge-x86_64-apple-darwin.tar.gz |
| macOS | aarch64 (Apple Silicon) | plan-forge-aarch64-apple-darwin.tar.gz |
| Windows | x86_64 | plan-forge-x86_64-pc-windows-msvc.zip |
macOS Gatekeeper: If you get a security warning, run:
xattr -d com.apple.quarantine /path/to/plan-forge
Build from Source
Requires Rust 1.91+ (edition 2024).
# Clone the repository
git clone https://github.com/andrey-moor/plan-forge.git
cd plan-forge
# Build
cargo build --release
# Or install directly
cargo install --path .
Quick Start
Prerequisites
- An API key for your chosen LLM provider
Build from source requirements (if not using binary releases):
| Platform | Requirements |
|---|---|
| Linux | Rust 1.91+, system libraries: sudo apt-get install libxcb1-dev libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libdbus-1-dev |
| macOS | Rust 1.91+ |
| Windows | Rust 1.91+, Visual Studio Build Tools with "Desktop Development with C++" |
First Run
# Set your API key (Linux/macOS)
export ANTHROPIC_API_KEY="your-key-here"
# Windows PowerShell
$env:ANTHROPIC_API_KEY="your-key-here"
# Windows cmd.exe
set ANTHROPIC_API_KEY=your-key-here
# Generate a plan
cargo run -- run --task "Add user authentication to the web app"
Usage
Basic Commands
# Generate a plan from a task description
cargo run -- run --task "your task description"
# Read task from a file
cargo run -- run --path requirements.md
# Task from file with additional context
cargo run -- run --path requirements.md --task "Focus on security aspects"
# Resume from an existing plan with feedback
cargo run -- run --path plans/active/my-task/ --task "Use JWT instead of sessions"
# Verbose logging
cargo run -- run --task "your task" --verbose
# Using LiteLLM proxy (all subagents)
LITELLM_HOST=http://localhost:4000 \
LITELLM_API_KEY=sk-your-key \
PLAN_FORGE_ORCHESTRATOR_PROVIDER=litellm \
PLAN_FORGE_ORCHESTRATOR_MODEL=claude-opus-4.5 \
PLAN_FORGE_PLANNER_PROVIDER=litellm \
PLAN_FORGE_PLANNER_MODEL=claude-opus-4.5 \
PLAN_FORGE_REVIEWER_PROVIDER=litellm \
PLAN_FORGE_REVIEWER_MODEL=claude-opus-4.5 \
cargo run -- run --task "your task" --max-total-tokens -1
CLI Options
| Option | Short | Description |
|---|---|---|
--task | -t | Task description (or feedback when resuming) |
--path | -p | Path to task file or existing plan directory |
--working-dir | -w | Working directory for the planning task |
--config | -c | Path to configuration file |
--planner-model | Override LLM model for planning | |
--reviewer-model | Override LLM model for review | |
--planner-provider | Override provider (anthropic, openai, litellm) | |
--reviewer-provider | Override provider for review | |
--max-iterations | Maximum iterations before stopping (default: 10) | |
--output | -o | Output directory for plan files (default: ./plans/active) |
--threshold | Review pass threshold 0.0-1.0 (default: 0.8) | |
--verbose | -v | Enable debug logging |
--orchestrator-model | Override orchestrator model | |
--orchestrator-provider | Override orchestrator provider | |
--max-total-tokens | Maximum total tokens for orchestrator session (-1 for unlimited) | |
--session-id | Session ID to resume (alternative to --path for orchestrator) | |
--feedback | Feedback for resuming paused orchestrator sessions |
Writing Effective Tasks
The quality of your task definition directly impacts the quality of generated plans. Plans must score >= 0.80 to pass review.
Quick template:
Task: [Short, descriptive title]
Objective: [Clear, specific goal]
Success Criteria: [Testable outcomes]
Context: [Relevant file paths, patterns to follow]
The five qualities of effective tasks:
- Specific: "Add JWT auth to /api/login" not "Add authentication"
- Grounded: Reference existing patterns and files
- Testable: Define measurable success criteria
- Deterministic: No "maybe" or "as needed"
- Scoped: Clear boundaries on what to change
See docs/writing-tasks.md for the complete guide with examples and anti-patterns.
Configuration
Environment Variables
API Keys (required for your chosen provider):
| Variable | Provider |
|---|---|
ANTHROPIC_API_KEY | Anthropic |
OPENAI_API_KEY | OpenAI |
LITELLM_HOST | LiteLLM |
LITELLM_API_KEY | LiteLLM |
MICROSOFT_FOUNDRY_RESOURCE | Microsoft Foundry |
MICROSOFT_FOUNDRY_API_KEY | Microsoft Foundry |
Plan-Forge Configuration (optional overrides):
| Variable | Description | Default |
|---|---|---|
PLAN_FORGE_THRESHOLD | Review pass threshold (0.0-1.0) | 0.8 |
PLAN_FORGE_MAX_ITERATIONS | Maximum planning iterations | 5 |
PLAN_FORGE_PLANNER_PROVIDER | Override planner provider | - |
PLAN_FORGE_PLANNER_MODEL | Override planner model | - |
PLAN_FORGE_REVIEWER_PROVIDER | Override reviewer provider | - |
PLAN_FORGE_REVIEWER_MODEL | Override reviewer model | - |
PLAN_FORGE_ORCHESTRATOR_PROVIDER | Override orchestrator provider | - |
PLAN_FORGE_ORCHESTRATOR_MODEL | Override orchestrator model | - |
PLAN_FORGE_RECIPE_DIR | Directory to search for recipes | - |
PLAN_FORGE_PLAN_DIR | Output directory for plan files | plans/active |
PLAN_FORGE_LOG_ALL | Show logs from all crates (goose, etc.) | - |
RUST_LOG | Full control over log filtering (e.g., goose=debug) | - |
Environment variables override config file values but are themselves overridden by CLI arguments.
Config File
Create a config.yaml or use the default at config/default.yaml:
planning:
recipe: recipes/planner.yaml
provider_override: null # Override provider from recipe
model_override: null # Override model from recipe
review:
recipe: recipes/reviewer.yaml
provider_override: null
model_override: null
output:
runs_dir: ./.plan-forge # Session JSON files
active_dir: ./plans/active # Final markdown output
guardrails:
max_iterations: 10 # Max plan-review cycles
max_total_tokens: 500000 # Token budget
score_threshold: 0.8 # Score needed to pass review (0.0-1.0)
Recipe Customization
Recipes define LLM agent behavior. To customize, place recipe files in .plan-forge/recipes/:
Recipe resolution priority:
- Explicit path in config (if it exists)
- Project-local
.plan-forge/recipes/planner.yamlor.plan-forge/recipes/reviewer.yaml - Bundled defaults (no external files required)
Recipe format:
version: "1.0.0"
title: "Strategic Planner"
description: "Generates comprehensive development plans"
# System prompt for the LLM
instructions: |
You are an elite strategic planning specialist...
## Planning Process
1. Understand the Task
2. Explore the Codebase
3. Identify Patterns
...
# MCP server extensions
extensions:
- name: developer
type: builtin
description: "Developer tools for file operations"
timeout: 300
- name: context7
type: stdio
cmd: npx
args: ["-y", "@upstash/context7-mcp@latest"]
description: "Up-to-date documentation for libraries"
timeout: 60
# Default provider and model
settings:
goose_provider: anthropic
goose_model: claude-opus-4-5-20251101
# Output schema (JSON Schema)
response:
json_schema:
type: object
properties:
title: { type: string }
phases: { type: array, ... }
...
Providers
Anthropic (Default)
export ANTHROPIC_API_KEY="sk-ant-..."
cargo run -- run --task "your task"
Or override in recipe:
settings:
goose_provider: anthropic
goose_model: claude-opus-4-5-20251101
OpenAI
export OPENAI_API_KEY="sk-..."
cargo run -- run --task "your task" --planner-provider openai --planner-model gpt-4o
LiteLLM
LiteLLM allows you to use various model providers through a unified proxy. This is useful for accessing models via GitHub Copilot, Azure, or other backends.
Setup with Docker:
# Run litellm proxy
docker run -d \
-p 4000:4000 \
-v /path/to/config.yaml:/app/config.yaml:ro \
ghcr.io/berriai/litellm:main-latest
# Example litellm config.yaml for GitHub Copilot
general_settings:
master_key: sk-
model_list:
- model_name: '*'
litellm_params:
model: github_copilot/*
extra_headers:
Editor-Version: vscode/1.100.0
Environment variables:
export LITELLM_HOST=http://localhost:4000
export LITELLM_API_KEY=sk-
Recipe configuration:
settings:
goose_provider: litellm
goose_model: claude-opus-4.5 # Note: dot notation, not dashes
Available models via GitHub Copilot:
claude-opus-4.5,claude-sonnet-4.5,claude-sonnet-4gpt-4o,gpt-4-turbo- And other models supported by your Copilot subscription
Using LiteLLM with MCP Server
When running plan-forge as an MCP server, configure LiteLLM via environment variables or config file.
Option 1: Environment variables
export LITELLM_HOST=http://localhost:4000
export LITELLM_API_KEY=sk-xxx
export PLAN_FORGE_PLANNER_PROVIDER=litellm
export PLAN_FORGE_PLANNER_MODEL=claude-opus-4.5
export PLAN_FORGE_REVIEWER_PROVIDER=litellm
export PLAN_FORGE_REVIEWER_MODEL=claude-opus-4.5
plan-forge mcp plan-forge
Option 2: Config file (.plan-forge/config.yaml)
planning:
provider_override: litellm
model_override: claude-opus-4.5
review:
provider_override: litellm
model_override: claude-opus-4.5
Then set only the LiteLLM connection variables:
export LITELLM_HOST=http://localhost:4000
export LITELLM_API_KEY=sk-xxx
plan-forge mcp plan-forge
Note: CLI arguments like --planner-provider only work with the run subcommand, not the MCP server.
Microsoft Foundry
Microsoft Foundry (Azure AI Foundry) provides access to Claude and other models through Azure.
Note: Requires the forked goose with Foundry support.
Environment variables:
export MICROSOFT_FOUNDRY_RESOURCE="your-resource-name"
export MICROSOFT_FOUNDRY_API_KEY="your-api-key"
Usage:
MICROSOFT_FOUNDRY_RESOURCE="foundry-myresource" \
MICROSOFT_FOUNDRY_API_KEY="your-key" \
PLAN_FORGE_ORCHESTRATOR_PROVIDER="microsoft_foundry" \
PLAN_FORGE_ORCHESTRATOR_MODEL="claude-opus-4-5" \
PLAN_FORGE_PLANNER_PROVIDER="microsoft_foundry" \
PLAN_FORGE_PLANNER_MODEL="claude-opus-4-5" \
PLAN_FORGE_REVIEWER_PROVIDER="microsoft_foundry" \
PLAN_FORGE_REVIEWER_MODEL="claude-opus-4-5" \
cargo run -- run --task "your task" --max-total-tokens -1
MCP Extensions
Model Context Protocol (MCP) servers provide tools to the LLM agent.
Built-in Extensions
extensions:
- name: developer
type: builtin
description: "File operations, shell commands, codebase exploration"
timeout: 300
External Extensions (via stdio)
extensions:
# Documentation lookup
- name: context7
type: stdio
cmd: npx
args: ["-y", "@upstash/context7-mcp@latest"]
timeout: 60
# Custom MCP server
- name: my-tools
type: stdio
cmd: /path/to/mcp-server
args: ["--config", "server.json"]
timeout: 120
Popular MCP Servers
- context7: Up-to-date library documentation (
npx -y @upstash/context7-mcp@latest) - filesystem: File system operations
- github: GitHub API integration
- postgres/sqlite: Database access
See MCP Servers for more options.
Architecture
Plan-forge supports two execution modes:
Legacy Mode (Default)
The deterministic loop controller runs a fixed plan-review-update cycle:
Task Description
β
βΌ
βββββββββββββββββββ
β Planner β β Recipe: planner.yaml
β (LLM Agent) β β Extensions: developer, context7
ββββββββββ¬βββββββββ
β Plan (JSON)
βΌ
βββββββββββββββββββ
β Reviewer β β Recipe: reviewer.yaml
β (LLM Agent) β β Hard checks + LLM review
ββββββββββ¬βββββββββ
β ReviewResult
βΌ
ββββββ΄βββββ
β Passed? β
ββββββ¬βββββ
No β Yes
β β β
βΌ β βΌ
Update β Output
Plan β Markdown
β β
ββββββ
Orchestrator Mode (Default)
The LLM-powered orchestrator is now the default mode. It makes dynamic decisions about the planning workflow:
- Uses goose's in-process MCP extension pattern for tool coordination
- Enforces 6 mandatory conditions that require human approval (security, sensitive files, low scores, iteration limits, API changes, data deletion)
- Implements hard stops for token budget, max iterations, and timeouts
- Supports pausing for human input and resuming sessions
# Run with orchestrator (default)
cargo run -- run --task "your task"
# With token budget limit
cargo run -- run --task "your task" --max-total-tokens 100000
# Unlimited tokens
cargo run -- run --task "your task" --max-total-tokens -1
With LiteLLM proxy:
LITELLM_HOST=http://localhost:4000 \
LITELLM_API_KEY=sk- \
PLAN_FORGE_ORCHESTRATOR_PROVIDER=litellm \
PLAN_FORGE_ORCHESTRATOR_MODEL=claude-opus-4.5 \
PLAN_FORGE_PLANNER_PROVIDER=litellm \
PLAN_FORGE_PLANNER_MODEL=claude-opus-4.5 \
PLAN_FORGE_REVIEWER_PROVIDER=litellm \
PLAN_FORGE_REVIEWER_MODEL=claude-opus-4.5 \
cargo run -- run --path requirements.md --max-total-tokens -1
Orchestrator Guardrails:
The orchestrator enforces hard stops that cannot be bypassed:
| Hard Stop | Trigger |
|---|---|
| MaxIterations | Exceeds configured max iterations (default: 10) |
| TokenBudget | Exceeds max total tokens |
| Timeout | Exceeds execution timeout |
Human input is requested only when the LLM reviewer flags requires_human_input: true for security concerns, ambiguous requirements, or architectural decisions.
Review pass/fail is determined deterministically: score >= threshold (default 0.80).
Core Flow
- Planner generates a structured plan using the LLM with codebase exploration tools
- Hard Checks validate plan structure (has phases, tasks, acceptance criteria)
- Reviewer evaluates gaps, clarity, and feasibility via LLM
- Loop Controller (or Orchestrator) decides: refine (score < threshold) or accept (score >= threshold)
- Output writes final markdown files to
./plans/active/<task-slug>/
Output Structure
Session files (JSON, in .plan-forge/):
.plan-forge/<task-slug>/
βββ plan-iteration-1.json
βββ plan-iteration-2.json
βββ review-iteration-1.json
βββ review-iteration-2.json
Final output (Markdown, committed):
./plans/active/<task-slug>/
βββ <task-slug>-plan.md # Consolidated execution plan (phases, tasks, criteria, risks, context)
βββ <task-slug>-dag.json # Execution DAG for automation (optional, when instructions present)
MCP Server
Plan-forge can run as an MCP (Model Context Protocol) server, exposing planning tools to AI assistants like Claude Code, Cursor, and VS Code.
Running the MCP Server
# Run the plan-forge MCP server
plan-forge mcp plan-forge
# With custom config
plan-forge mcp plan-forge --config ./config/default.yaml
# Or run the developer tools server (from goose)
plan-forge mcp developer
The MCP server automatically:
- Detects config (in priority order):
.plan-forge/config.yaml(recommended)plan-forge.yaml.plan-forge.yamlconfig/default.yaml
- Applies
PLAN_FORGE_*environment variable overrides - Bundles default recipes (no external recipe files required)
Configuring with Claude Code
Add to your project's .mcp.json:
{
"mcpServers": {
"plan-forge": {
"command": "plan-forge",
"args": ["mcp", "plan-forge"]
}
}
}
Available Tools
| Tool | Description |
|---|---|
plan_run | Create or resume a planning session |
plan_status | Get session status (ready/in_progress/needs_input/approved/max_turns) |
plan_list | List all planning sessions |
plan_get | Read plan, tasks, or context markdown files |
plan_approve | Force approve a plan and write to plans/active/ |
plan_run parameters:
| Parameter | Description |
|---|---|
task | Task description (required for new sessions) |
session_id | Resume an existing session |
reset_turns | Reset turn counter when resuming |
use_orchestrator | Enable LLM-powered orchestrator mode |
human_response | Provide human response when resuming paused session |
Session Status
| Status | Meaning |
|---|---|
ready | Session created but no planning started |
in_progress | Planning loop is running |
needs_input | Reviewer flagged need for human input |
approved | Plan passed review (score >= threshold) |
max_turns | Max iterations reached without approval |
See integrations/claude-code/README.md for detailed integration instructions.
Development
# Build
cargo build
# Run tests
cargo test
# Check for errors
cargo check
# Format code
cargo fmt
# Run linter
cargo clippy
Contributing
See CONTRIBUTING.md for guidelines on:
- Development setup
- Code style
- Pull request process
- Issue reporting
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
See CHANGELOG.md for version history.
Acknowledgments
Built on goose by Block, Inc. Uses a fork with Microsoft Foundry support.
