Content
# Manus MCP
[](https://pypi.org/project/manus-mcp/)
[](https://pypi.org/project/manus-mcp/)
[](https://pypistats.org/packages/manus-mcp)
[](https://github.com/aruxojuyu665/Manus-MCP/blob/main/LICENSE)
[](https://github.com/aruxojuyu665/Manus-MCP/actions/workflows/ci.yml)
[](https://github.com/aruxojuyu665/Manus-MCP/actions/workflows/live.yml)
[](https://github.com/aruxojuyu665/Manus-MCP/stargazers)
An MCP server that gives Claude Code full programmatic control over Manus.im through the official Manus API v2. Implements **all 30 documented endpoints**, **3 composite tools** for common workflows, and a **local webhook receiver** with RSA-SHA256 signature verification.
- **Status**: production-ready (single-user) — v0.1.1
- Language: Python 3.11+
- Transport: stdio (native to Claude Code)
- Base URL: `https://api.manus.ai`
## Verified coverage (v0.1.1)
| Layer | Metric |
|------|---------|
| Unit tests | 60+ (server.py dispatch, webhook ASGI app, secret-leak guard, schema stability) |
| Live e2e tests | 23 (including task.update / sendMessage / confirmAction / agent.update / website.publish) |
| Composite live | 4 (including the F2 reject check) |
| Webhook live e2e | 1 (cloudflared tunnel + receiver + Manus delivery) |
| **Manus API endpoints exercised live** | **30/30** (graceful skip only when the account lacks the prerequisite — no agents / no website) |
| Coverage | ≥ 80% (gated in CI) |
| `mypy --strict` | 0 errors |
| `ruff check` | 0 errors |
See [docs/SECURITY.md](docs/SECURITY.md) and [docs/RELEASE.md](docs/RELEASE.md) for the production flow.
## What's included
### 30 direct API wrappers
| Category | Tools |
|-----------|-------------|
| Tasks (9) | `manus_task_create`, `manus_task_detail`, `manus_task_list`, `manus_task_update`, `manus_task_stop`, `manus_task_delete`, `manus_task_send_message`, `manus_task_list_messages`, `manus_task_confirm_action` |
| Projects (2) | `manus_project_create`, `manus_project_list` |
| Skills (1) | `manus_skill_list` |
| Agents (3) | `manus_agent_list`, `manus_agent_detail`, `manus_agent_update` |
| Files (3) | `manus_file_create`, `manus_file_detail`, `manus_file_delete` |
| Webhooks (4) | `manus_webhook_create`, `manus_webhook_list`, `manus_webhook_delete`, `manus_webhook_public_key` |
| Usage (3) | `manus_usage_list`, `manus_usage_team_statistic`, `manus_usage_team_log` |
| Connectors (1) | `manus_connector_list` |
| Browser (1) | `manus_browser_online_list` |
| Website (3) | `manus_website_status`, `manus_website_list_checkpoints`, `manus_website_publish` |
### 3 composite tools
- **`manus_file_upload`** — creates a presigned URL, uploads the bytes, and waits for `status=uploaded`. Accepts `path`, `base64`, or a public `url`.
- **`manus_task_wait`** — polls a task until it reaches a terminal status (`stopped` / `waiting` / `error`) and returns new messages plus wait details (event_id + response schema).
- **`manus_website_publish_and_wait`** — publishes a site and waits until it becomes `published` or `failed`.
### 3 webhook tools (read from the local SQLite DB)
- `manus_webhook_events_list` — list received events with filters.
- `manus_webhook_events_get` — fetch an event by `event_id`.
- `manus_webhook_events_clear` — delete received events.
Total: **36 MCP tools**.
## Installation
```bash
pip install manus-mcp
```
This pulls the package from PyPI. The `manus-mcp` and `manus-mcp-webhook` console scripts become available, plus the `python -m manus_mcp` and `python -m manus_mcp.webhook_receiver` module entry points.
### From source (for contributors)
```bash
git clone https://github.com/aruxojuyu665/Manus-MCP.git
cd Manus-MCP
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS/Linux:
# source .venv/bin/activate
pip install -e ".[dev]"
```
## API key configuration
Place a `.env` file in the project root (a `.env.example` template is provided). Both variable names are accepted:
```env
MANUS_API_KEY=sk-...
# or, for backwards compatibility:
# ManusAPI=sk-...
```
Priority: `process.env` > `.env`.
Optional settings:
```env
MANUS_BASE_URL=https://api.manus.ai
MANUS_HTTP_TIMEOUT=60
MANUS_LOG_LEVEL=INFO
```
## Registering with Claude Code
Add the following to `.claude/settings.json` (project-level) or `~/.claude/settings.json` (global):
```json
{
"mcpServers": {
"manus": {
"command": "python",
"args": ["-m", "manus_mcp"],
"cwd": "path/to/Manus-MCP"
}
}
}
```
If `MANUS_API_KEY` is not set globally, pass it explicitly:
```json
{
"mcpServers": {
"manus": {
"command": "python",
"args": ["-m", "manus_mcp"],
"cwd": "path/to/Manus-MCP",
"env": { "MANUS_API_KEY": "sk-..." }
}
}
}
```
Restart Claude Code — the `manus_*` tools will appear in the tool list.
## Verification
Without launching the server:
```bash
python scripts/list_tools.py
```
Against the real API:
```bash
python scripts/smoke.py
```
Unit tests:
```bash
pytest
```
Lint and types:
```bash
ruff check .
mypy manus_mcp
```
## Usage examples from Claude Code
```
manus_task_create { "message": { "content": "Give me a 5-bullet summary of today's AI news" } }
```
The response contains a `task_id`. Then:
```
manus_task_wait { "task_id": "<id>", "timeout_sec": 600 }
```
When it finishes you get `last_assistant_message` with the final reply and `new_messages` with the conversation history.
Uploading a file and attaching it to a task:
```
manus_file_upload { "source": { "path": "C:/docs/report.pdf" } }
manus_task_create {
"message": {
"content": [
{ "type": "text", "text": "Summarize this report" },
{ "type": "file", "file_id": "<file_id>" }
]
}
}
```
## Webhook receiver (optional)
A local receiver for `task_created` / `task_stopped` events with full RSA-SHA256 signature verification per `ManusAPIDocs/webhooks/security.md`.
### 1. Configure environment variables
```env
MANUS_WEBHOOK_PUBLIC_URL=https://your-tunnel.example.com/manus/webhook
MANUS_WEBHOOK_HOST=127.0.0.1
MANUS_WEBHOOK_PORT=8787
# MANUS_WEBHOOK_DB_PATH=... # defaults to %LOCALAPPDATA%\manus-mcp\events.db on Windows
```
`MANUS_WEBHOOK_PUBLIC_URL` **must exactly match** the URL Manus calls. The Manus signing payload includes this URL, so even a typo will cause every event to be rejected.
### 2. Start a tunnel
For example, with Cloudflare Tunnel:
```bash
cloudflared tunnel --url http://localhost:8787
```
or ngrok:
```bash
ngrok http 8787
```
### 3. Run the receiver
```bash
python -m manus_mcp.webhook_receiver
# or: manus-mcp-webhook --host 127.0.0.1 --port 8787
```
### 4. Register the webhook with Manus
In Claude Code:
```
manus_webhook_create { "url": "https://your-tunnel.example.com/manus/webhook" }
```
### 5. Read events
```
manus_webhook_events_list { "event_type": "task_stopped", "limit": 20 }
manus_webhook_events_get { "event_id": "..." }
manus_webhook_events_clear { "before_received_at": 1704000000 }
```
## Architecture
```
manus_mcp/
├── __main__.py # stdio entrypoint
├── server.py # MCP Server bootstrap
├── config.py # pydantic-settings
├── logger.py # stderr-only logger
├── client/
│ ├── manus_client.py # async httpx client + retry
│ ├── rate_limiter.py # per-endpoint token bucket (from rate-limits.md)
│ ├── retry.py # exponential backoff + jitter
│ └── errors.py # ManusApiError / ManusNetworkError
├── schemas/ # pydantic models for each resource (tasks, projects, ...)
├── tools/ # @manus_tool registration for all 36 tools
│ ├── tasks.py projects.py skills.py agents.py
│ ├── files.py webhooks.py usage.py connectors.py
│ ├── browser.py website.py
│ └── composite.py # task_wait / file_upload / website_publish_and_wait
└── webhook_receiver/
├── signature.py # RSA-SHA256 verification using {ts}.{url}.{sha256_hex(body)}
├── storage.py # SQLite WAL
├── server.py # Starlette + uvicorn
├── tools.py # events_list / events_get / events_clear
└── __main__.py
```
## Rate limits
The client honours the API limits (60-second sliding window) and transparently retries 429 responses with backoff + jitter. Limits come from `ManusAPIDocs/getting-started/rate-limits.md`:
- 10/min: `task.create`, `task.sendMessage`
- 40/min: all mutations
- 100/min: all read-only calls
- 600/min: `usage.*`
## Security
- The API key is never logged.
- The webhook receiver verifies signatures and rejects timestamps older than 5 minutes.
- The public key is cached for 1 hour.
- SQLite is opened in WAL mode with `check_same_thread=False` for safe multi-reader access.
## License
MIT.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.