manus-mcp-server
manus-mcp-server
A Remote MCP server that wraps the Manus API and exposes a generate_image
tool, so Claude (web/app) can request images and have Manus generate them.
How it works
Manus's API is a general task API, not a dedicated image endpoint. This server:
Receives a
generate_imagetool call from Claude (prompt, optional style/aspect ratio).Creates a Manus task asking the agent to produce an image and return it as a file.
Polls the task until it completes (or times out after 4 minutes).
Returns the resulting file URL(s) back to Claude as the tool result.
1. Deploy on Railway
Push this repo to GitHub.
In Railway: New Project → Deploy from GitHub repo → select this repo.
Railway will detect
railway.jsonand use Nixpacks to runnpm install && npm run build, thennpm start.In the Railway project, go to Variables and set:
MANUS_API_KEY— your Manus API key.MANUS_API_BASE_URL— defaults tohttps://api.manus.im/v1; check your Manus API docs/dashboard and adjust if different.ADMIN_PASSWORD— a strong password only you know. This gates the/authorizelogin page so a stranger who finds your server's URL can't mint themselves an access token.PUBLIC_BASE_URL— set this to your Railway public domain once you have it (step 5 below), e.g.https://manus-mcp-server-production.up.railway.app. If left unset, the server tries to infer it from request headers, which usually works on Railway but is safer to set explicitly.PORT— Railway sets this automatically; no action needed.
Once deployed, go to Settings → Networking → Generate Domain to get a public HTTPS URL, e.g.
https://manus-mcp-server-production.up.railway.app.Confirm it's alive: visit
https://<your-domain>/health— should return{"status":"ok"}.
2. Verify the Manus API endpoint shape
The exact paths (/tasks, response field names like task_id vs id) can
vary by account/API version. Before relying on this in production:
Check
https://manus.im/docs/integrations/manus-api(or your account's API reference) for the current create-task and get-task endpoints and response fields.If they differ from what's in
src/manusClient.ts, adjust the constants at the top of that file (CREATE_TASK_PATH,GET_TASK_PATH, and the field names read increateImageTask/getTask) and redeploy.Easiest way to check without guessing: make one manual
curlcall to create a task and print the raw JSON, then match the field names.
3. Connect it to Claude
This server now implements a real OAuth 2.0 flow (dynamic client registration + authorization code + PKCE), which is what Claude's "Add custom connector" screen expects.
In Claude (web or app): Settings → Connectors → Add custom connector.
URL:
https://<your-railway-domain>/mcpClaude will auto-discover the OAuth endpoints via
https://<your-railway-domain>/.well-known/oauth-authorization-server, register itself as a client, then redirect you to a login page.On that login page, enter the
ADMIN_PASSWORDyou set in Railway. This approves the connection and Claude receives an access token.
Once connected, you can just ask Claude for an image and it will call the
generate_image tool automatically.
Notes on this OAuth implementation
It's intentionally minimal: in-memory storage, single admin password, tokens expire after 1 hour and refresh automatically via the refresh token Claude stores.
Restarting/redeploying the Railway service clears all registered clients and tokens — you'll need to remove and re-add the connector in Claude if that happens.
This is appropriate for personal, single-user use. It is not a general-purpose identity provider — don't hand this URL to other people.
Local development
npm install
cp .env.example .env # fill in your real values
npm run devServer runs at http://localhost:3000/mcp.