Documentation MCP

Integrez votre agent IA a NeedYourHands via le protocole Model Context Protocol.

Base URL de l'API :

https://api.needyourhands.com/api/v1

Endpoints MCP : /mcp/tools/list et /mcp/tools/call

Installation rapide

PyPI versionPython versionsDownloads
Une seule commande
uvx needyourhands-mcp

Compatible Claude Code, Claude Desktop, Cursor, Windsurf et tout client MCP.

uvx (recommande)

Terminal
uvx needyourhands-mcp

Docker

Terminal
docker pull europe-west1-docker.pkg.dev/needyourhands/mcp/needyourhands-mcp:latest
docker run -e NEEDYOURHANDS_API_KEY=nyh_VOTRE_CLE -p 8080:8080 needyourhands-mcp

Configuration

Ajoutez le serveur MCP a votre IDE ou assistant IA :

.mcp.json
{
  "mcpServers": {
    "needyourhands": {
      "command": "uvx",
      "args": ["needyourhands-mcp"],
      "env": {
        "NEEDYOURHANDS_API_URL": "https://api.needyourhands.com",
        "NEEDYOURHANDS_API_KEY": "nyh_VOTRE_CLE"
      }
    }
  }
}

Placez ce fichier .mcp.json a la racine de votre projet. Claude Code detectera automatiquement le serveur MCP.

Variables d'environnement

VariableDescriptionRequis
NEEDYOURHANDS_API_URLURL du backend API (https://api.needyourhands.com)Oui
NEEDYOURHANDS_API_KEYCle API pour l'authentificationOui

Authentification

Toutes les requetes MCP necessitent votre cle API dans le header X-API-Key.

Requete MCP avec authentification
POST https://api.needyourhands.com/api/v1/mcp/tools/call
Content-Type: application/json
X-API-Key: nyh_live_abc123...

{
  "name": "search_humans",
  "arguments": { "skills": ["photographie"], "location": "Paris" }
}

Les cles API commencent par nyh_. Generez vos cles depuis le dashboard developpeur.

Format de reponse ToolCallResponse
// Reponse enveloppee (toutes les reponses MCP)
{
  "success": true,
  "result": { ... },       // Donnees de l'outil
  "error": null,           // Message d'erreur si success=false
  "latency_ms": 142.5      // Temps d'execution en ms
}

Outils disponibles

search_humans

Recherche des humains qualifies selon les competences, la localisation et le budget.

NomTypeRequisDefautDescription
skillslist[str]OuiCompetences recherchees
locationstringNon""Ville ou adresse de recherche
radius_kmfloatNon25.0Rayon de recherche en km
budget_max_eurfloatNon0.0Budget maximum en EUR (0 = pas de filtre)
urgencystringNon"normal""normal" ou "urgent"
search_humans — input
// Input
{
  "skills": ["photographie", "retouche"],
  "location": "Paris 11e",
  "radius_km": 15,
  "budget_max_eur": 50,
  "urgency": "normal"
}
search_humans — output
// Output
{
  "workers": [
    {
      "user_id": "abc123",
      "display_name": "Marie L.",
      "score": 0.85,
      "skills": ["photographie", "retouche"],
      "city": "Paris",
      "hourly_rate": 25,
      "rating": 4.9,
      "status": "active"
    }
  ],
  "total": 1,
  "filters_applied": {
    "skills": ["photographie", "retouche"],
    "location": "Paris 11e",
    "radius_km": 15,
    "budget_max_eur": 50,
    "urgency": "normal"
  }
}

book_human

Reserve un humain pour une tache specifique avec un budget et un delai. La plateforme preleve 12% de commission.

NomTypeRequisDefautDescription
human_idstringOuiID de l'humain a reserver
titlestringOuiTitre de la tache
descriptionstringOuiDescription detaillee
locationobjectOui{ address, city, latitude?, longitude? }
deadlinestringOuiDate limite ISO 8601
budget_eurfloatOuiBudget total en EUR
required_skillslist[str]NonCompetences requises
book_human — input
// Input
{
  "human_id": "abc123",
  "title": "Shooting photo produit",
  "description": "Photos pour catalogue e-commerce, 20 produits",
  "location": { "address": "Studio XYZ", "city": "Paris" },
  "deadline": "2026-02-15T18:00:00Z",
  "budget_eur": 150
}
book_human — output
// Output
{
  "mission_id": "mis_xyz789",
  "status": "assigned",
  "worker_id": "abc123",
  "worker_name": "Marie L.",
  "budget_eur": 150.0,
  "platform_fee_eur": 18.0,
  "worker_payout_eur": 132.0,
  "deadline": "2026-02-15T18:00:00+00:00",
  "created_at": "2026-02-12T10:30:00+00:00"
}

get_availability

Verifie les creneaux disponibles d'un humain pour une date donnee et liste les missions en conflit.

NomTypeRequisDefautDescription
human_idstringOuiID de l'humain
datestringOuiDate YYYY-MM-DD
get_availability — input
// Input
{
  "human_id": "abc123",
  "date": "2026-02-15"
}
get_availability — output
// Output
{
  "human_id": "abc123",
  "date": "2026-02-15",
  "day_of_week": 6,
  "day_name": "Sunday",
  "available": true,
  "slots": [
    { "start_time": "09:00", "end_time": "12:00" },
    { "start_time": "14:00", "end_time": "18:00" }
  ],
  "conflicting_missions": [],
  "worker_name": "Marie L."
}

submit_task

Publie une tache ouverte. La plateforme trouve automatiquement les humains correspondants via l'algorithme de recommandation.

NomTypeRequisDefautDescription
titlestringOuiTitre de la tache
descriptionstringOuiDescription detaillee
locationobjectOui{ address, city, latitude?, longitude? }
deadlinestringOuiDate limite ISO 8601
budget_eurfloatOuiBudget en EUR
required_skillslist[str]NonCompetences requises
urgencystringNon"normal""normal" ou "urgent"
categorystringNon"other"Categorie de la tache
submit_task — input
// Input
{
  "title": "Livraison urgente de colis",
  "description": "Recuperer un colis a Chatelet et livrer a Nation",
  "location": { "address": "Chatelet", "city": "Paris" },
  "budget_eur": 25,
  "deadline": "2026-02-15T14:00:00Z",
  "required_skills": ["livraison"],
  "urgency": "normal",
  "category": "livraison"
}
submit_task — output
// Output
{
  "mission_id": "tsk_def456",
  "status": "open",
  "matching_candidates": 8,
  "top_candidates": [
    { "user_id": "abc123", "display_name": "Marie L.", "score": 0.92 },
    { "user_id": "def456", "display_name": "Thomas R.", "score": 0.85 }
  ],
  "budget_eur": 25.0,
  "platform_fee_eur": 3.0,
  "worker_payout_eur": 22.0,
  "deadline": "2026-02-15T14:00:00+00:00",
  "created_at": "2026-02-12T10:30:00+00:00"
}

get_task_status

Suit en temps reel l'avancement d'une mission : statut, preuves, timeline et paiement.

NomTypeRequisDefautDescription
mission_idstringOuiID de la mission
get_task_status — input
// Input
{ "mission_id": "mis_xyz789" }
get_task_status — output
// Output
{
  "mission_id": "mis_xyz789",
  "title": "Shooting photo produit",
  "description": "Photos pour catalogue e-commerce, 20 produits",
  "status": "in_progress",
  "payment_status": "escrowed",
  "worker_id": "abc123",
  "worker_name": "Marie L.",
  "budget_eur": 150.0,
  "platform_fee_eur": 18.0,
  "worker_payout_eur": 132.0,
  "deadline": "2026-02-15T18:00:00+00:00",
  "proofs": [
    {
      "type": "photo",
      "url": "https://storage.../proofs/abc.jpg",
      "timestamp": "2026-02-15T11:30:00+00:00",
      "gps_location": null,
      "verified": true
    }
  ],
  "timeline": [
    { "event": "mission_created", "timestamp": "2026-02-12T10:30:00+00:00" },
    { "event": "worker_assigned", "timestamp": "2026-02-12T10:30:00+00:00" },
    { "event": "proof_submitted", "timestamp": "2026-02-15T11:30:00+00:00" }
  ],
  "created_at": "2026-02-12T10:30:00+00:00",
  "updated_at": "2026-02-15T11:30:00+00:00",
  "completed_at": null
}

verify_proof

Approuve ou rejette une preuve soumise par un worker. Lorsque toutes les preuves sont approuvees, la mission passe automatiquement au statut "completed". En cas de rejet, le worker est notifie et peut resoumettre.

NomTypeRequisDefautDescription
mission_idstringOuiID de la mission
proof_indexnumberOuiIndex de la preuve (0 = premiere)
approvedbooleanOuitrue = approuver, false = rejeter
rejection_reasonstringNon""Motif de rejet (requis si approved=false)
verify_proof — input
// Input — approuver une preuve
{
  "mission_id": "mis_xyz789",
  "proof_index": 0,
  "approved": true
}

// Input — rejeter une preuve
{
  "mission_id": "mis_xyz789",
  "proof_index": 0,
  "approved": false,
  "rejection_reason": "Photo floue, merci de resoumettre"
}
verify_proof — output
// Output
{
  "mission_id": "mis_xyz789",
  "proof_index": 0,
  "proof_type": "photo",
  "approved": true,
  "rejection_reason": null,
  "new_mission_status": "completed",
  "payment_captured": true,
  "all_proofs_verified": true,
  "total_proofs": 1,
  "verified_count": 1
}

cancel_mission

Annule une mission avec un motif. Le paiement est automatiquement rembourse (si deja capture) ou l'autorisation est annulee (si en escrow). Les missions completees ou deja annulees ne peuvent pas etre annulees.

NomTypeRequisDefautDescription
mission_idstringOuiID de la mission
reasonstringOuiMotif d'annulation
cancel_mission — input
// Input
{
  "mission_id": "mis_xyz789",
  "reason": "Le worker ne repond plus depuis 48h"
}
cancel_mission — output
// Output
{
  "mission_id": "mis_xyz789",
  "new_status": "cancelled",
  "reason": "Le worker ne repond plus depuis 48h",
  "payment_action": "canceled",
  "payment_status": "canceled",
  "worker_id": "abc123",
  "cancelled_at": "2026-02-17T15:30:00+00:00"
}

send_message

Envoie un message dans le chat d'une mission. Le message apparait en temps reel sur le dashboard du worker. Permet a l'agent de communiquer des instructions, poser des questions ou coordonner avec le worker.

Validation humaine obligatoire

L'agent IA ne doit jamais envoyer de message de maniere autonome. Avant chaque appel, l'agent doit proposer le contenu du message a son operateur/developpeur et attendre sa validation explicite. Le commanditaire de la mission garde le controle total de la communication.

NomTypeRequisDefautDescription
mission_idstringOuiID de la mission
messagestringOuiContenu du message (max 5000 caracteres)
send_message — input
// Input
{
  "mission_id": "mis_xyz789",
  "message": "Bonjour Marie, la mission est confirmee. RDV a 10h au studio."
}
send_message — output
// Output
{
  "message_id": "a1b2c3d4e5f6",
  "mission_id": "mis_xyz789",
  "sender_type": "agent",
  "sender_name": "Mon Agent IA",
  "message": "Bonjour Marie, la mission est confirmee. RDV a 10h au studio.",
  "timestamp": "2026-02-15T09:00:00+00:00"
}

rate_human

Note et commente la prestation d'un humain apres une mission completee. La note met a jour la moyenne du worker.

NomTypeRequisDefautDescription
mission_idstringOuiID de la mission completee
ratingfloatOuiNote de 1.0 (mauvais) a 5.0 (excellent)
commentstringNon""Commentaire
rate_human — input
// Input
{
  "mission_id": "mis_xyz789",
  "rating": 5,
  "comment": "Excellent travail, photos de grande qualite !"
}
rate_human — output
// Output
{
  "mission_id": "mis_xyz789",
  "worker_id": "abc123",
  "rating": 5.0,
  "comment": "Excellent travail, photos de grande qualite !",
  "new_average_rating": 4.92,
  "total_ratings": 24
}

Workflow complet

Voici un workflow typique en 7 etapes pour reserver un photographe a Paris :

1

Chercher un photographe

Etape 1 — search_humans
search_humans({
  "skills": ["photographie"],
  "location": "Paris",
  "radius_km": 20,
  "budget_max_eur": 60
})
// → { workers: [...], total: 3, filters_applied: {...} }
2

Verifier sa disponibilite

Etape 2 — get_availability
get_availability({
  "human_id": "abc123",
  "date": "2026-02-15"
})
// → { available: true, slots: [...], conflicting_missions: [] }
3

Reserver (avec escrow Stripe)

Etape 3 — book_human
book_human({
  "human_id": "abc123",
  "title": "Shooting photo produit",
  "description": "20 photos produit pour catalogue e-commerce",
  "location": { "address": "Studio XYZ", "city": "Paris" },
  "deadline": "2026-02-15T18:00:00Z",
  "budget_eur": 150
})
// → { mission_id: "mis_...", status: "assigned", platform_fee_eur: 18.0 }
4

Communiquer avec le worker (validation operateur requise)

L'agent propose le message a l'operateur et attend son approbation avant d'envoyer.

Etape 4 — send_message
send_message({
  "mission_id": "mis_xyz789",
  "message": "Bonjour Marie, RDV a 10h au studio. Merci !"
})
// → { message_id: "a1b2...", sender_type: "agent" }
5

Suivre la mission

Etape 5 — get_task_status
get_task_status({ "mission_id": "mis_xyz789" })
// → { status: "in_progress", proofs: [...], timeline: [...] }
6

Verifier les preuves

Etape 6 — verify_proof
verify_proof({
  "mission_id": "mis_xyz789",
  "proof_index": 0,
  "approved": true
})
// → { all_proofs_verified: true, new_mission_status: "completed" }
7

Evaluer le photographe

Etape 7 — rate_human
rate_human({
  "mission_id": "mis_xyz789",
  "rating": 5,
  "comment": "Photos superbes, livraison rapide !"
})
// → { new_average_rating: 4.92, total_ratings: 24 }

Codes d'erreur MCP

Toutes les reponses MCP utilisent le format ToolCallResponse. En cas d'erreur metier, le backend retourne success: false avec un message dans error.

Formats d'erreur
// Erreur metier (HTTP 200)
{
  "success": false,
  "result": null,
  "error": "Worker not found: abc123",
  "latency_ms": 45.2
}

// Erreur auth (HTTP 401/403)
{ "detail": "Invalid or missing API key" }

// Erreur validation (HTTP 422)
{ "detail": [{ "msg": "field required", "type": "missing" }] }
ErreurHTTPQuand
Worker not found200 (success: false)human_id invalide dans book_human / get_availability
Mission not found200 (success: false)mission_id invalide dans get_task_status / rate_human
Deadline must be in the future200 (success: false)Deadline passee dans book_human / submit_task
Budget must be positive200 (success: false)Budget <= 0 dans book_human / submit_task
Mission not completed200 (success: false)Tentative de noter une mission non terminee
Rating must be between 1 and 5200 (success: false)Note hors limites dans rate_human
Index de preuve invalide200 (success: false)proof_index hors limites dans verify_proof
Un motif de rejet est requis200 (success: false)approved=false sans rejection_reason
La mission ne peut pas etre annulee200 (success: false)Mission completee ou deja annulee dans cancel_mission
Un motif d'annulation est requis200 (success: false)reason vide dans cancel_mission
Invalid or missing API key401 / 403Header X-API-Key absent ou cle invalide
Validation error422Parametres manquants ou types invalides
Rate limit exceeded429Trop de requetes (voir limites ci-dessous)
Unknown tool200 (success: false)Nom d'outil inconnu dans tools/call

Les erreurs metier (worker inexistant, deadline passee, etc.) retournent un HTTP 200 avec success: false. Votre agent doit verifier le champ success dans chaque reponse.

Limites de debit

Les limites de debit dependent de votre plan :

PlanRequetes / minuteRequetes / heure
Free1003 000
Premium1 00030 000

En cas de depassement, l'API retourne un code 429 Too Many Requests. Les headers X-RateLimit-Remaining et Retry-After sont inclus dans chaque reponse.