Back to Articles

Forge Orchestrator: Coordinating Multiple AI Coding Agents Without the Chaos

[ View on GitHub ]

Forge Orchestrator: Coordinating Multiple AI Coding Agents Without the Chaos

Hook

When you run three different AI coding assistants on the same codebase simultaneously, you don’t get three times the productivity—you get merge conflicts, duplicate work, and files that multiple LLMs are fighting to edit at the same time. Forge Orchestrator is the first coordination layer built specifically to solve this multi-agent chaos.

Context

The typical developer workflow with AI assistants is fundamentally single-threaded: you ask Claude to write a function, wait for it to finish, then ask Copilot to write tests, then switch to another tool for documentation. This sequential approach leaves compute on the table—these LLMs can work in parallel, but coordinating them manually is nightmarish. You’ll encounter file conflicts when two agents try to edit the same module, duplicated effort when they don’t know what the other is doing, and architectural drift when each agent makes local decisions without global context.

Forge Orchestrator emerged from this coordination gap. It’s a Rust-based orchestration engine that treats AI coding assistants—Claude Code, Codex CLI, and Gemini CLI—as a coordinated development team rather than isolated tools. The core insight is borrowed from distributed systems: if you want multiple agents working on the same codebase, you need task scheduling, dependency tracking, file locking, and state synchronization. Forge implements all of this while adding a critical feature for AI workflows: native Model Context Protocol (MCP) support, so the AI tools themselves can query task state and claim work through a standardized interface.

Technical Insight

decompose

generate tasks

persist

load state

identify ready tasks

check file conflicts

acquire locks

modify

release locks

update status

check dependencies

SPEC.md Input

LLM Planning Brain

Task Dependency Graph

.forge/state/ JSON

Parallel Scheduler

Lock Manager

Agent Pool

Target Files

System architecture — auto-generated

At its core, Forge uses an LLM (defaulting to GPT-4, but pluggable) as a ‘planning brain’ that decomposes your SPEC.md file into a dependency graph of tasks. These tasks get persisted as JSON in .forge/state/, with metadata tracking which files each task touches, what its prerequisites are, and which agent it’s assigned to. The scheduler then uses this dependency graph to identify parallelizable work—tasks with no unmet dependencies can execute concurrently, while dependent tasks wait.

The file-locking mechanism is where things get interesting. When an agent claims a task, Forge locks all files that task will modify. Here’s what the internal lock structure looks like:

// Simplified from forge-orchestrator's locking layer
struct FileLock {
    path: PathBuf,
    task_id: TaskId,
    agent: AgentType,
    acquired_at: SystemTime,
}

struct LockManager {
    active_locks: HashMap<PathBuf, FileLock>,
}

impl LockManager {
    fn try_acquire(&mut self, task: &Task) -> Result<Vec<FileLock>> {
        // Check if any file this task needs is already locked
        for file in &task.file_paths {
            if self.active_locks.contains_key(file) {
                return Err(LockError::Conflict);
            }
        }
        
        // Atomically acquire all locks for this task
        let locks: Vec<_> = task.file_paths.iter()
            .map(|path| FileLock {
                path: path.clone(),
                task_id: task.id,
                agent: task.assigned_agent,
                acquired_at: SystemTime::now(),
            })
            .collect();
            
        for lock in &locks {
            self.active_locks.insert(lock.path.clone(), lock.clone());
        }
        
        Ok(locks)
    }
}

This prevents the classic race condition where Claude starts refactoring auth.rs while Codex is simultaneously adding new functions to it. The scheduler simply won’t assign file-conflicting tasks to multiple agents.

The Model Context Protocol integration is what elevates Forge from a task runner to a true multi-agent platform. Instead of having Forge SSH into Claude or scrape Codex output, the AI tools themselves connect to Forge’s MCP server and query: “What tasks are available? What files am I allowed to touch? What context do I need?” A typical MCP exchange looks like this:

// AI agent queries available work via MCP
{
  "method": "tasks/claim",
  "params": {
    "agent_id": "claude-code-1",
    "capabilities": ["rust", "refactoring"],
    "max_complexity": 7
  }
}

// Forge responds with assigned task + context
{
  "task_id": "t_42",
  "description": "Refactor error handling in auth module",
  "file_paths": ["src/auth.rs", "src/error.rs"],
  "dependencies_completed": true,
  "context": {
    "architecture_decisions": ["Use thiserror for error types"],
    "related_tasks": ["t_38"],
    "knowledge_base": [...]
  }
}

This protocol-driven approach means agents aren’t just executing blindly—they’re pulling relevant architectural decisions from Forge’s ‘knowledge flywheel,’ which captures design rationale during execution. When Claude completes the auth refactor, it reports back via MCP with a summary of changes, and Forge commits those changes to git with a structured commit message that links back to the task.

The TUI dashboard (built with ratatui) visualizes this in real-time: you see a dependency graph with tasks color-coded by status (pending/in-progress/completed/blocked), which agents are working on what, and which files are locked. The headless forge run mode does the same orchestration without the UI, suitable for CI/CD pipelines.

Forge’s drift detection runs periodically, using an LLM to compare completed work against the original spec. If tasks start deviating—say, an agent added features that weren’t requested—Forge flags this before it cascades. This catches scope creep that’s particularly common with creative LLMs that like to ‘improve’ things beyond the stated requirements.

Gotcha

The elephant in the room: Forge requires you to write a comprehensive SPEC.md file upfront. There’s no magic extraction from GitHub issues, Jira tickets, or existing documentation. You’re manually authoring a specification that the planning LLM can decompose, which is significant upfront work. For teams used to iterative, conversation-driven development with AI assistants, this feels heavyweight.

The adapter architecture is also more brittle than it appears. Forge currently supports exactly three AI tools via bespoke Rust adapters. Want to add Cursor, Aider, or your company’s internal LLM tool? You’re writing Rust code and contributing upstream, not dropping in a YAML config. There’s no plugin system, no script-based adapters. This will be a dealbreaker for teams with heterogeneous AI tooling or proprietary systems. Additionally, with only 15 GitHub stars and development centered in a single organization, you’re adopting a tool without significant community validation—expect breaking changes, limited third-party resources, and the risk that the project could be abandoned if the maintainers lose interest.

Verdict

Use if: You’re genuinely running multiple AI coding assistants on the same codebase and experiencing coordination pain—file conflicts, duplicated work, or agents stepping on each other. You’re comfortable with Rust tooling, can invest time in upfront specification writing, and value the MCP integration for treating AI tools as queryable team members. You’re working on medium-to-large codebases where parallelizing AI work provides real productivity gains. Skip if: You’re using a single AI assistant (the coordination overhead isn’t worth it), working on small projects where manual coordination is trivial, need a mature tool with broad community support, or require low-code extensibility to integrate proprietary tools. Also skip if you prefer iterative, conversation-driven development over specification-first workflows—Forge assumes you know what you want built before orchestration begins.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/ai-agents/nxtg-ai-forge-orchestrator.svg)](https://starlog.is/api/badge-click/ai-agents/nxtg-ai-forge-orchestrator)