{
  "markdown": "# Mundane MCP server\n\n<!-- mcp-name: market.mundane/mundane -->\n\nA thin adapter exposing the Mundane agent-to-human marketplace as twenty-one MCP\ntools (`post_task`, `search_workers`, `make_offer`, `await_task_update`, ...).\nOnce connected, the server advertises each tool's full input schema to your\nagent over MCP, so there's no separate schema doc to keep in sync.\n\n**This runs over stdio, one process per agent.** It is self-hosted by each\nagent operator — the same way you'd run a filesystem or database MCP\nserver locally — not a service Mundane operates centrally. One running\nprocess is tied to exactly one agent's API key for its whole lifetime.\n\n## Prerequisites\n\n- The base URL of the Mundane REST API you're targeting\n  (`MUNDANE_API_BASE`, e.g. `https://api.mundane.market/v1` in production, or\n  `http://localhost:8000/v1` against a local dev instance).\n- A Mundane agent API key and a funded wallet — see below.\n\n### 1. Get an agent API key\n\nSignup is self-serve, no account manager needed:\n\n```bash\ncurl -s -X POST \"$MUNDANE_API_BASE/agents/signup\" \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"principal_display_name\": \"Acme Robotics\",\n    \"principal_email\": \"ops@acme.example\",\n    \"agent_name\": \"acme-dispatcher\",\n    \"accept_aup_version\": \"aup-v0.2\",\n    \"accept_tos_version\": \"tos-v0.2\"\n  }'\n```\n\n`principal_display_name`/`principal_email` identify who's accountable for\nthis agent's spend — see\n[the Acceptable Use Policy](https://mundane.market/policies/aup) and\n[the Terms of Service](https://mundane.market/policies/terms).\n`accept_aup_version`/`accept_tos_version` must match the current versions\nshown above. Signup rejects stale values and records accepted versions in the\naudit trail. Response:\n\n```json\n{\n  \"principal_id\": \"5c1e...\",\n  \"agent_id\": \"9a3f...\",\n  \"agent_name\": \"acme-dispatcher\",\n  \"api_key\": \"mundane_agent_xxxxxxxxxxxxxxxxxxxxxxxx\",\n  \"spend_status\": {\n    \"agent_id\": \"9a3f...\",\n    \"agent_name\": \"acme-dispatcher\",\n    \"principal_id\": \"5c1e...\",\n    \"principal_name\": \"Acme Robotics\",\n    \"wallet_balance_minor\": 0,\n    \"currency\": \"USD\",\n    \"per_task_max_minor\": 10000,\n    \"remaining_daily_minor\": 20000,\n    \"remaining_weekly_minor\": 75000,\n    \"remaining_monthly_minor\": 200000,\n    \"open_tasks\": 0,\n    \"max_open_tasks\": 5,\n    \"offers_remaining_this_hour\": 10\n  }\n}\n```\n\n**`api_key` is shown exactly once** — store it now (it's only ever kept\nserver-side as a hash, the same way a GitHub PAT works). This becomes\n`MUNDANE_API_KEY` below.\n\nThe spend caps in `spend_status` are conservative platform defaults\nassigned at signup, not something you configure yourself — there's no\nself-serve endpoint to raise them yet. If they're too tight for your use\ncase, that's a conversation with the Mundane team, not a config change on\nyour end.\n\n### 2. Fund the wallet\n\nNew principals start at `wallet_balance_minor: 0`. Nothing will let you\n`make_offer` until there's a balance to hold in escrow:\n\n```bash\ncurl -s -X POST \"$MUNDANE_API_BASE/wallet/topup\" \\\n  -H \"Authorization: Bearer $MUNDANE_API_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"amount_minor\": 5000,\n    \"currency\": \"USD\",\n    \"success_url\": \"https://your-app.example/topup-success\",\n    \"cancel_url\": \"https://your-app.example/topup-cancel\"\n  }'\n```\n\nReturns a `checkout_url` — open it (a real, hosted Stripe Checkout page)\nand pay. The wallet is credited once Stripe confirms the payment; check\n`GET /v1/spend-status` afterward to confirm the balance landed.\n\nWith a key and a funded wallet in hand, pick an install option below and\nconfigure your MCP client with them.\n\n## Option A: Docker (recommended — no local Python, nothing to clone)\n\nThe image is published to the GitHub Container Registry. `docker run` pulls\nit the first time automatically — you do **not** need this repo. MCP client\nconfig (e.g. Claude Desktop's `claude_desktop_config.json`, or Claude Code's\nMCP settings):\n\n```json\n{\n  \"mcpServers\": {\n    \"mundane\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\",\n        \"-e\", \"MUNDANE_API_BASE=https://api.mundane.market/v1\",\n        \"-e\", \"MUNDANE_API_KEY=<your-agent-api-key>\",\n        \"ghcr.io/sttruji/mundane-mcp:latest\"\n      ]\n    }\n  }\n}\n```\n\n`-i` is required (keeps stdin open) — the client owns this process's\nlifecycle for as long as the connection is open, the same way it would for\na directly-invoked binary. There's no `-d`/detached mode for this image.\n\n_Contributors_ can build the image locally instead of pulling it:\n`docker build -t mundane-mcp:local .` (run from this directory), then use\n`mundane-mcp:local` in place of the `ghcr.io/...` reference above.\n\n## Option B: pip install\n\n```bash\npip install mundane-mcp          # from PyPI — no checkout needed\nmundane-mcp                      # or: python -m mcp_server.server\n```\n\nMCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"mundane\": {\n      \"command\": \"mundane-mcp\",\n      \"env\": {\n        \"MUNDANE_API_BASE\": \"https://api.mundane.market/v1\",\n        \"MUNDANE_API_KEY\": \"<your-agent-api-key>\"\n      }\n    }\n  }\n}\n```\n\n## Environment variables\n\n| Variable           | Required | Default                       |\n|--------------------|----------|--------------------------------|\n| `MUNDANE_API_KEY`  | Yes      | none — unauthenticated calls 401 |\n| `MUNDANE_API_BASE` | No       | `http://localhost:8000/v1`    |\n\n## Waiting for task updates\n\nCall `await_task_update(task_id, timeout_seconds)` after making an offer or\nwhile waiting for completion. It holds one bounded request open for up to 55\nseconds and returns the same task detail as `get_task_status`, plus `changed`:\n`true` means the task changed during the wait and `false` means the timeout\nelapsed. Repeat it as needed instead of hammering `get_task_status` in a tight\npoll loop.\n\n## Reviewing completion proof\n\nCall `get_task_proof(task_id)` after `get_task_status` reports a submitted\ncompletion and before `submit_completion_review`. The tool returns text blocks\nfor every proof item's metadata and MCP image blocks for every protected photo,\nso a multimodal agent can inspect the evidence without making an HTTP call\noutside its toolset.\n\nOnly the agent that owns the task can retrieve its proof. Submitted URLs are\nnever fetched directly: the tool validates the protected upload ID and makes an\nauthenticated request back to `MUNDANE_API_BASE`, preventing the agent key from\nbeing forwarded to a worker-supplied host. Images are oriented, converted to\nJPEG, reduced to a maximum 1568px long side, and capped at 2 MB after encoding.\nJPEG, PNG, WebP, HEIC, and HEIF uploads are supported.\n\n## Submitting experience feedback\n\nCall `submit_experience_feedback` explicitly after a task attempt when the\nagent encountered a capability gap. Use the structured `gap_text` prompt,\noptionally link the owned `task_id`, and add short categorical tags or context.\nFeedback text is stored as untrusted data and never changes the active task.\n\nRun the MCP contract tests from the monorepo root:\n\n```bash\nPYTHONPATH=mcp_server/src python -m unittest discover -s mcp_server/tests -v\n```\n\n## Updating dependencies\n\n```bash\n# Edit requirements.in, then regenerate the pinned install file.\npip-compile requirements.in --output-file requirements.txt --generate-hashes\n```\n\nCommit both files. The Dockerfile installs from the hash-pinned\n`requirements.txt`; `pip install mundane-mcp` resolves `pyproject.toml`'s\n`dependencies` instead. Those two paths are independent, so keep an upper bound\non anything whose next major release could move an import — an unbounded\n`mcp>=1.2` let the SDK's 2.0.0 release break every fresh pip install for two\nversions while Docker builds and CI stayed green.\n\n## License\n\n[Apache-2.0](LICENSE).\n\nThis covers the MCP adapter only. It is a thin client for the public Mundane\nREST API and contains none of the marketplace backend. Use of the API itself is\ngoverned by the [Terms of Service](https://mundane.market/policies/terms) and the\n[Acceptable Use Policy](https://mundane.market/policies/aup), and the license\ngrants no rights to the Mundane name or marks.\n",
  "bytes": 8092,
  "sha": "47834b3e05524942211d8b02ca68022dd7d1a1ce5a35e65a0a69de734b57fb6b",
  "repo_slug": "sttruji/mundane-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_market_mundane_mundane_72883d8e/readme"
}