When the closed-source Manus agent went viral behind an invite-code wall, five researchers from the MetaGPT team responded the fastest way they knew how: they built an open alternative and shipped the prototype in three hours. OpenManus โ MIT-licensed, Python 3.12, installable with a single command โ has since grown far past its hackathon origins into one of the most-starred agent frameworks on GitHub. Its premise is disarmingly simple: a general agent is a state machine plus a loop plus tools. The agent thinks, decides on a tool call, executes it, observes the result, and repeats until the task is done. What makes the repository worth reading is how cleanly that premise is layered โ an abstract base class at the bottom, a ReAct loop above it, a tool-calling layer above that, and concrete agents like Manus, a browser specialist, and a coding specialist on top, all sharing one tool belt and one multi-provider LLM client.
The codebase is small enough to read in an afternoon and disciplined enough to teach real design. main.py is twenty-nine lines that create a Manus agent and run a prompt. Underneath, app/agent/ holds the hierarchy: a Pydantic-based state machine, the abstract think-act loop, and the tool caller that turns model output into executed actions. app/tool/ bundles a dozen-plus tools from persistent shell sessions to full browser control, app/flow/ adds multi-step planning that can orchestrate several agents, app/sandbox/ isolates risky execution inside containers, and protocol directories expose the agent over MCP and the agent-to-agent standard. Configuration is one TOML file with examples for OpenAI, Anthropic, Azure, Google and Ollama endpoints. As always in this series, what follows is an educational tour of published source code.
OpenManus at a glance: the CLI creates Manus, which extends the ReAct loop and the tool-calling layer; ToolCallAgent thinks through the LLM client and acts through the tool collection; the planning flow orchestrates agents against tracked step plans; and risky code runs inside an isolated sandbox.
Reading the overview from left to right:
- The CLI entry turns one prompt into a running agent with proper cleanup.
- Manus is the generalist agent with the full default tool belt.
- ReActAgent defines the think-then-act step every agent inherits.
- ToolCallAgent converts model tool calls into executed, recorded actions.
- The LLM client wraps every supported provider behind one async interface.
- The schema defines messages, memory, tool calls and agent states.
- The tool collection is the named bag of tools agents wield.
- The planning flow decomposes a prompt into tracked, assignable steps.
Why You Need This
The first reason is the agent hierarchy, which is the clearest teachable example of layered agent design this series has covered. BaseAgent is a Pydantic model that owns the state machine: an idle-running-finished-error lifecycle, a memory of messages, a step counter, and a stuck-state detector that notices when an agent repeats itself. ReActAgent is twenty-eight lines that make the pattern explicit โ an abstract think() decides whether to act, an abstract act() does it, and step() composes them. ToolCallAgent then supplies both halves: thinking asks the LLM for a tool call in a strict schema, acting executes each call through the tool collection and records tool messages back into memory. On top sit the specialists โ Manus for general tasks, a browser agent, a SWE agent, an MCP-native agent, a sandboxed agent โ each a short file that changes only the prompts and the tool subset. Reading bottom-up teaches exactly where the extension points are.
The second reason is the tool belt, which shows the craft level each tool needs. BaseTool wraps every capability as a Pydantic model with typed parameters, and the tool collection addresses them by name with safe execution. The individual tools are miniature lessons: the Bash tool keeps a persistent shell session alive across steps with timeouts; the string-replace editor โ nearly four hundred lines โ gives the agent view, create, and surgical file-edit operations with path validation; web search deduplicates results, enforces content truncation, and swaps between Google, Bing, Baidu and DuckDuckGo backend implementations; the browser tool โ the largest โ drives navigate, click, type, scroll and tab operations through a real browser; and the planning tool lets the agent manage its own step plans. There is even an ask-human tool that is seventeen lines, which is itself a lesson: a human is just another tool the agent can call.
The third reason is the infrastructure ring, which turns a demo into a system you can actually operate. The LLM client โ over six hundred lines โ handles token counting against model limits, provider-specific message formats, retries, and streaming, so agents never think about providers. The config layer reads TOML files whose example variants show supported models, search keys, and sandbox settings. The sandbox core runs shell, filesystem, and process operations inside a Docker-isolated environment, managed by a lifecycle manager and reachable from a hosted-sandbox client; a Daytona integration lives beside it. The planning flow โ three hundred and sixty lines โ is the orchestration answer: it decomposes a task into steps with the planning tool, assigns an agent per step, and re-plans when results surprise it. And the reachability ring is genuinely modern: the MCP agent discovers tools from connected MCP servers at runtime, an MCP server mode exposes OpenManus as tools for other clients, and an A2A executor serves the agent over the agent-to-agent protocol.
The detail view: entry points including the flow runner, MCP runner, MCP server and A2A executor; the agent hierarchy from BaseAgent through the specialists; the core engine of LLM, schema, config and prompts; the tool belt from shell and editor to browser and MCP bridges; the flow layer; and the sandbox stack from client to terminal.
Walking the detail diagram, one prompt is traceable end to end. python main.py --prompt ... reaches the CLI, which awaits Manus.create() โ a class method that assembles the tool belt from the collection and wires config into the LLM client. The run loop lives in BaseAgent: each iteration calls the step composed in ReActAgent, which routes through ToolCallAgent โ think asks the model with the system prompt and the current memory, act executes every returned tool call and appends results to memory. A research prompt will chain web search and the crawler; a coding prompt will chain the editor and Bash; anything destructive can route into the sandbox stack. Termination is a state, not a hope: the agent finishes when it calls the terminate tool or hits max steps, and cleanup runs regardless.
The second walkthrough is composability. The same Manus that the CLI drives is what the flow runner hands to the flow factory, which builds a planning flow that steers the agent through tracked steps. The same tool belt is what the MCP agent extends with tools discovered from external servers through the MCP bridge, and what the MCP server mode re-exports to other applications. That symmetry โ one agent, one tool belt, many front doors โ is the design decision worth stealing. It is also why the project grew so fast: adding capability means adding a Pydantic tool class and a prompt line, nothing else.
From Install to Your First Agent
Installation is two commands: clone the repo, then uv pip install -r requirements.txt (or the conda equivalent). Copy config/config.example.toml to config/config.toml and fill in an API key โ the base model can be any OpenAI-compatible endpoint, and the example variants cover Anthropic, Azure, Google and Ollama. Your first run is python main.py and a prompt; watch the terminal as the agent thinks, picks a tool, executes it, and thinks again. python run_flow.py runs the planning flow for multi-step tasks, and python run_mcp.py --serve starts the MCP server mode so other clients can call this agent as a tool. For anything that writes files or runs code, enable the sandbox configuration so execution lands in a container instead of your host.
Honest limits: the codebase is intentionally minimal, and it shows in ways both good and bad โ there is no persistence layer, no multi-tenancy, no evaluation harness, and no built-in UI beyond the browser demo on Hugging Face. Long tasks can drift as memory grows unboundedly within a run, and the stuck-state detection is heuristic rather than clever. Tool reliability is exactly as good as the model behind the config file, so weak models produce chaotic plans. And because the project moves at hackathon speed, APIs and defaults shift quickly between versions. None of that changes the verdict: OpenManus is the cleanest readable implementation of the ReAct-plus-tools pattern in circulation, and the best first source code to study before touching any larger agent framework. Enjoyed this post? Never miss out on future posts by following us