众包任务管理MCP服务器

GroundTruther 是一个 MCP 服务器,让 AI 代理可以雇佣人类完成真实世界任务,包括位置核实、数据收集、拍照和 QA 测试,并通过托管余额或 Solana 链上托管进行支付。

  • by brothaakhee
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 brothaakhee/groundtruther-mcp

使用说明

GroundTruther MCP Server

An MCP server that lets AI agents hire humans to complete real-world missions — verify locations, collect data, take photos, and more.

Quick Start

Install

pip install groundtruther-mcp

Or run directly with uvx:

uvx groundtruther-mcp

Wallet-native setup (one env var)

If you have a Solana wallet, you don't need to sign up at all — set GT_SOLANA_PAYER_SK and skip GT_API_KEY entirely. No wallet yet? Generate a keypair with the Solana CLI:

solana-keygen new --outfile ~/.config/solana/groundtruther.json
# GT_SOLANA_PAYER_SK accepts that file's contents verbatim (a JSON byte array)
# or a base58-encoded secret key.
{
  "mcpServers": {
    "groundtruther": {
      "command": "uvx",
      "args": ["groundtruther-mcp"],
      "env": {
        "GT_API_URL": "https://api.groundtruther.io/api/v1",
        "GT_SOLANA_PAYER_SK": "<JSON byte array or base58 secret>"
      }
    }
  }
}

On startup the server signs a SIWS (Sign-In With Solana) challenge with your key — locally, over the Anza off-chain message format; the key never leaves your machine and the signed payload can never be a transaction — and GroundTruther auto-provisions an escrow-enabled agent named agent-<pubkey prefix> with your wallet as its default payer, mints an API key, and the server stores it with 0600 permissions in ~/.groundtruther/credentials.json. You'll see a log line like authenticated as agent-AbCdEfGh via wallet ... on startup — it goes to stderr, which most MCP clients hide behind a log viewer. The client validates every challenge before signing (correct GT host, your own address, ASCII-only, nonce present, not transaction-shaped) and refuses loudly otherwise.

  • The API key is THE credential. /auth/wallet/verify returns only the API key (no session JWT); everything the agent surface does authenticates with it, and rotating it (below) is the complete revocation story.
  • Key rotation: delete the credentials entry (or hit a 401) and the server re-signs a challenge — each re-verify mints a fresh API key and revokes the old one. A 401 from a rotated/revoked key triggers exactly one automatic re-auth before failing loudly. A request timeout on an authenticated call gets the same one-shot re-auth (a stale key can surface as a stall instead of a clean 401).
  • Spend caps: auto-provisioned agents start with default daily/weekly spend limits, enforced on both custodial and on-chain missions — a leaked API key can't drain your wallet mission-by-mission.
  • Settings ceiling: wallet-native accounts have no webapp password. Settings beyond what the API exposes (raising spend caps, renaming the agent) are founder/concierge changes for now — contact the GroundTruther team.

Get an API Key (classic setup)

  1. Sign up at groundtruther.io
  2. Create an agent in the dashboard
  3. Copy the API key (gt_sk_...) — it's shown once

Configure

Add to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):

{
  "mcpServers": {
    "groundtruther": {
      "command": "groundtruther-mcp",
      "env": {
        "GT_API_KEY": "gt_sk_your_key_here",
        "GT_API_URL": "https://api.groundtruther.io/api/v1"
      }
    }
  }
}

Or with uvx (no install needed):

{
  "mcpServers": {
    "groundtruther": {
      "command": "uvx",
      "args": ["groundtruther-mcp"],
      "env": {
        "GT_API_KEY": "gt_sk_your_key_here",
        "GT_API_URL": "https://api.groundtruther.io/api/v1"
      }
    }
  }
}

Tools

Mission Management

Tool Description
post_mission Create a mission for humans to complete (title, description, location, budget, deadline; optional drop_grace_secs — worker free-withdrawal window, min 3600 / 1h, default 7200 / 2h)
check_mission_status Get current status and details of a mission
list_my_missions List all your missions with optional status/category filters
get_templates Browse available mission templates
check_balance Check your wallet balance

Mission Lifecycle

Tool Description
list_pending_claim_requests List workers' claim requests waiting on your approval (worker stats + pitch note included)
respond_to_claim_request Approve or decline a worker's claim request (action: "approve" or "decline")
approve_mission Approve submitted proof and release payment to worker
reject_mission Reject proof with a reason — worker can resubmit
escalate_mission Escalate a disputed/stuck mission for GroundTruther arbitration
cancel_mission Cancel a mission (immediate for OPEN/CLAIMED, mutual consent for IN_PROGRESS)
respond_to_cancellation Approve or decline a worker's drop request (action: "approve" or "decline")

QA Testing

Tool Description
request_qa_test Hire a human tester to run a scripted test on a staging URL — steps JSON (instruction/expected, ids auto-assigned), budget, deadline, optional environment + credentials note. Tester claims need your approval (see respond_to_claim_request) unless auto-approval applies. Pass escrow=true to fund the mission from your own Solana wallet via on-chain escrow in the same call (devnet; see below)
get_qa_result Get the structured verdict for a QA mission — per-step pass/fail/blocked, pre-joined failed_steps + blocked_steps with repro context, screen-recording link, tester environment, a next_action hint, and claim_requested status when a tester is waiting on your approval. Escrow-aware: on missions paid from your own wallet the response carries mode: "escrow" and next_action points at release_mission instead of approve_mission

Communication

Tool Description
send_message Send a message to the worker on a mission
get_messages Get full conversation history (also marks messages as read)
poll_events Poll for events — claim_request_received, task_claimed, proof_submitted, task_completed, etc.

Reviews & Reference

Tool Description
submit_review Rate a worker 1-5 after mission completion
get_categories List available mission categories with display metadata
submit_feedback Send product feedback or a bug report to the GroundTruther team

On-chain Escrow (devnet; requires GT_ESCROW_ENABLED + GT_SOLANA_PAYER_SK for one-call signing)

Tool Description
post_mission_onchain Create a USDC escrow mission — builds the fund tx server-side, signs locally, submits
get_mission_status On-chain mission status (onchain_status, deadlines, events); refresh=true forces a chain re-sync
assign_worker_onchain Approve a worker for an on-chain mission (payer co-sign)
release_mission Pay the worker and close the mission (also withdraws a dispute you raised)
dispute_mission Dispute submitted proof during the review window
escalate_mission_onchain Request GroundTruther arbitration on a mission you've disputed
cancel_escrow_mission Cancel an unassigned funded mission and refund yourself
submit_signed_mission Mode-B fund completion: submit a fund tx signed with an external wallet

Paying from your own wallet (QA escrow, devnet)

By default request_qa_test pays testers from your custodial GroundTruther balance. With escrow=true, the same validated test contract is posted as an on-chain USDC escrow mission funded from your agent's own Solana wallet in one call: the backend builds an unsigned fund transaction, this process signs it locally with GT_SOLANA_PAYER_SK (the key never leaves your machine) and submits it. GroundTruther never holds your funds — payment releases to the tester straight from the audited escrow program.

request_qa_test(staging_url="https://staging.example.com", steps=..., budget=5.0, escrow=true)
→ {"task_id": ..., "status": "pending", "mode": "escrow", "onchain_status": "FUNDED",
   "mission_pda": ..., "fund_sig": ..., "next": ...}

The loop differs from custodial in two places: escrow QA missions are created with auto_claim (a vetted tester claims instantly via gas-sponsored transactions — no claim-approval gate), and when the verdict lands you pay with release_mission (not approve_mission) or contest with dispute_mission / escalate_mission_onchain. get_qa_result tells you which mode you're in and what to call.

Requirements: GT_SOLANA_PAYER_SK set (JSON byte array or base58 secret), a funded devnet wallet, and escrow enablement on your Agent record (wallet-native agents are escrow-enabled at provisioning; classic agents are concierge — ask the GroundTruther team). Devnet only today. Full setup, the proven end-to-end devnet run, and the contract template live in the repo's docs/qa-vertical-escrow.md.

Funding the wallet (honest devnet notes): SOL for transaction fees is self-serve — solana airdrop 1 <your pubkey> --url devnet. Test-USDC is concierge for now: there is no faucet, so ask the GroundTruther team for a top-up before your first escrow mission. If you try to fund with an empty wallet, the error tells you exactly what's missing (SOL vs USDC, with current balances) — and note the mission is still created but unfunded in that case: retry with a new request_qa_test after topping up, or clean up with cancel_mission(task_id) (the error message includes the id).

Example Workflow

Agent: "I need someone to photograph the hours sign at 123 Main St"

1. post_mission(title="Photograph store hours", budget_amount="15.00", ...)
   → Mission created, $15 reserved

2. poll_events()
   → Event: mission claimed by worker

3. send_message(mission_uuid, "Please make sure the hours are legible in the photo")
   → Message sent

4. poll_events()
   → Event: proof_submitted

5. check_mission_status(mission_uuid)
   → See submitted proof with photo URL

6. approve_mission(mission_uuid)
   → Payment released to worker, mission COMPLETED

7. submit_review(mission_uuid, rating=5, comment="Great photos, fast turnaround")
   → Review saved

Mission Statuses

OPEN → CLAIMED → IN_PROGRESS → PROOF_SUBMITTED → COMPLETED
                                      ↓
                                 (reject) → IN_PROGRESS (worker resubmits)

Missions can also be CANCELLED (by agent) or EXPIRED (past deadline).

Environment Variables

Variable Required Default Description
GT_API_KEY One of these two — Your agent API key (gt_sk_...). Takes precedence when set
GT_SOLANA_PAYER_SK One of these two — Local payer secret key (JSON byte array or base58). Enables wallet-native auto-auth (an agent + API key are provisioned from a wallet signature) and escrow signing. Never leaves your machine
GT_API_URL No http://localhost:8001/api/v1 API base URL (default matches the local docker-compose stack)
GT_ESCROW_ENABLED No false Enable the on-chain escrow tools without a payer key (Mode B)
GT_CREDENTIALS_PATH No ~/.groundtruther/credentials.json Where wallet-native minted API keys are stored (0600)
GT_HTTP_TIMEOUT No 30 Per-request timeout in seconds. Raise this (e.g. 60–90) when using escrow: fund/release calls block server-side on Solana RPC confirmation and can exceed 30s. In wallet-native mode a timeout on an authenticated call also triggers one automatic re-auth (a stale key can stall instead of returning 401)

Development

pip install -e ".[dev]"

# Run tests
pytest tests/ -v

In-process use (no stdio server)

The MCP stdio transport is the supported integration, but every tool is a plain async function you can import and call directly — useful for test harnesses and embedding:

from groundtruther_mcp.tools_qa import request_qa_test, get_qa_result

result = await request_qa_test(staging_url="https://staging.example.com",
                               steps='[{"instruction": "...", "expected": "..."}]')

Configuration still comes from the environment (GT_API_KEY/GT_API_URL, or wallet-native via GT_SOLANA_PAYER_SK — call await groundtruther_mcp.wallet_auth.ensure_wallet_credentials() once at startup to run the same auto-auth bootstrap the server performs). Tools return JSON strings, errors as {"error": "..."}.

Troubleshooting

Install fails building cryptography on Intel (x86_64) macOS

Symptom: pip install groundtruther-mcp on an Intel Mac fails compiling cryptography from source with an error about a missing Rust toolchain (error: can't find Rust compiler / a maturin/cargo build failure).

Why: mcp depends on pyjwt[crypto], which pulls in cryptography. cryptography ≥ 49 ships arm64-only macOS wheels, so on Intel Macs pip falls back to the sdist — which needs Rust to build. cryptography 48.x is the last series with universal2 macOS wheels that still cover x86_64.

Fix — pin cryptography to the last Intel-wheel series:

pip install "cryptography<49" groundtruther-mcp

From v0.7.2 the package applies this constraint automatically on Intel macOS (environment marker in pyproject.toml), so a plain pip install works. If you specifically need cryptography ≥ 49 on an Intel Mac, install a Rust toolchain first (curl https://sh.rustup.rs -sSf | sh) and let it build from source.

Publishing

Bump the version in pyproject.toml and src/groundtruther_mcp/__init__.py, then run:

./publish.sh

The script builds and uploads to PyPI via Docker. It reads PYPI_TOKEN from the environment or from ../.env.

License

MIT