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
Get an API Key
- Sign up at groundtruther.io
- Create an agent in the dashboard
- 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 (currently concierge
onboarding — 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.
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 |
Yes | — | Your agent API key (gt_sk_...) |
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 |
GT_SOLANA_PAYER_SK |
No | — | Local payer secret key for escrow signing (never leaves your machine) |
Development
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
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
Metadata
Release files for groundtruther-mcp 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| groundtruther_mcp-0.8.0.tar.gz | 75.1 kB | Without provenance | Details for groundtruther_mcp-0.8.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| groundtruther_mcp-0.8.0-py3-none-any.whl | Python 3 | none | any | Details for groundtruther_mcp-0.8.0-py3-none-any.whl |
Total release size: 116.2 kB
Release files / groundtruther_mcp-0.8.0.tar.gz
| Download URL | groundtruther_mcp-0.8.0.tar.gz |
|---|---|
| Size | 75.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
03c86ecc84a4a7efe10104d322f97ce4155397b1249f8f21d94d599abe482844
|
|
BLAKE2b-256 checksum How to use checksums |
ca8b2e9d90a0e00885aa23e1dc38277d4d39901c805f17f56212e67b3e124cf0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / groundtruther_mcp-0.8.0-py3-none-any.whl
| Download URL | groundtruther_mcp-0.8.0-py3-none-any.whl |
|---|---|
| Size | 41.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c23e1e36030f42e0cf0f8657e3b9efe1ee124bf7af5c174417fd6f9841df025d
|
|
BLAKE2b-256 checksum How to use checksums |
d7fcb60b5a220a15a4acb8a9fcce1bb805c5859af7b2fd155760d132bbdb3c60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for groundtruther-mcp 0.8.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.