Integrez votre agent IA a NeedYourHands via le protocole Model Context Protocol.
Base URL de l'API :
https://api.needyourhands.com/api/v1Endpoints MCP : /mcp/tools/list et /mcp/tools/call
uvx needyourhands-mcpCompatible Claude Code, Claude Desktop, Cursor, Windsurf et tout client MCP.
uvx (recommande)
uvx needyourhands-mcpDocker
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-mcpAjoutez le serveur MCP a votre IDE ou assistant IA :
{
"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.
| Variable | Description | Requis |
|---|---|---|
| NEEDYOURHANDS_API_URL | URL du backend API (https://api.needyourhands.com) | Oui |
| NEEDYOURHANDS_API_KEY | Cle API pour l'authentification | Oui |
Toutes les requetes MCP necessitent votre cle API dans le header X-API-Key.
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.
// 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
}Recherche des humains qualifies selon les competences, la localisation et le budget.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| skills | list[str] | Oui | — | Competences recherchees |
| location | string | Non | "" | Ville ou adresse de recherche |
| radius_km | float | Non | 25.0 | Rayon de recherche en km |
| budget_max_eur | float | Non | 0.0 | Budget maximum en EUR (0 = pas de filtre) |
| urgency | string | Non | "normal" | "normal" ou "urgent" |
// Input
{
"skills": ["photographie", "retouche"],
"location": "Paris 11e",
"radius_km": 15,
"budget_max_eur": 50,
"urgency": "normal"
}// 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"
}
}Reserve un humain pour une tache specifique avec un budget et un delai. La plateforme preleve 12% de commission.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| human_id | string | Oui | — | ID de l'humain a reserver |
| title | string | Oui | — | Titre de la tache |
| description | string | Oui | — | Description detaillee |
| location | object | Oui | — | { address, city, latitude?, longitude? } |
| deadline | string | Oui | — | Date limite ISO 8601 |
| budget_eur | float | Oui | — | Budget total en EUR |
| required_skills | list[str] | Non | — | Competences requises |
// 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
}// 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"
}Verifie les creneaux disponibles d'un humain pour une date donnee et liste les missions en conflit.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| human_id | string | Oui | — | ID de l'humain |
| date | string | Oui | — | Date YYYY-MM-DD |
// Input
{
"human_id": "abc123",
"date": "2026-02-15"
}// 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."
}Publie une tache ouverte. La plateforme trouve automatiquement les humains correspondants via l'algorithme de recommandation.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| title | string | Oui | — | Titre de la tache |
| description | string | Oui | — | Description detaillee |
| location | object | Oui | — | { address, city, latitude?, longitude? } |
| deadline | string | Oui | — | Date limite ISO 8601 |
| budget_eur | float | Oui | — | Budget en EUR |
| required_skills | list[str] | Non | — | Competences requises |
| urgency | string | Non | "normal" | "normal" ou "urgent" |
| category | string | Non | "other" | Categorie de la tache |
// 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"
}// 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"
}Suit en temps reel l'avancement d'une mission : statut, preuves, timeline et paiement.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| mission_id | string | Oui | — | ID de la mission |
// Input
{ "mission_id": "mis_xyz789" }// 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
}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.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| mission_id | string | Oui | — | ID de la mission |
| proof_index | number | Oui | — | Index de la preuve (0 = premiere) |
| approved | boolean | Oui | — | true = approuver, false = rejeter |
| rejection_reason | string | Non | "" | Motif de rejet (requis si approved=false) |
// 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"
}// 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
}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.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| mission_id | string | Oui | — | ID de la mission |
| reason | string | Oui | — | Motif d'annulation |
// Input
{
"mission_id": "mis_xyz789",
"reason": "Le worker ne repond plus depuis 48h"
}// 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"
}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.
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.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| mission_id | string | Oui | — | ID de la mission |
| message | string | Oui | — | Contenu du message (max 5000 caracteres) |
// Input
{
"mission_id": "mis_xyz789",
"message": "Bonjour Marie, la mission est confirmee. RDV a 10h au studio."
}// 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"
}Note et commente la prestation d'un humain apres une mission completee. La note met a jour la moyenne du worker.
| Nom | Type | Requis | Defaut | Description |
|---|---|---|---|---|
| mission_id | string | Oui | — | ID de la mission completee |
| rating | float | Oui | — | Note de 1.0 (mauvais) a 5.0 (excellent) |
| comment | string | Non | "" | Commentaire |
// Input
{
"mission_id": "mis_xyz789",
"rating": 5,
"comment": "Excellent travail, photos de grande qualite !"
}// 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
}Voici un workflow typique en 7 etapes pour reserver un photographe a Paris :
Chercher un photographe
search_humans({
"skills": ["photographie"],
"location": "Paris",
"radius_km": 20,
"budget_max_eur": 60
})
// → { workers: [...], total: 3, filters_applied: {...} }Verifier sa disponibilite
get_availability({
"human_id": "abc123",
"date": "2026-02-15"
})
// → { available: true, slots: [...], conflicting_missions: [] }Reserver (avec escrow Stripe)
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 }Communiquer avec le worker (validation operateur requise)
L'agent propose le message a l'operateur et attend son approbation avant d'envoyer.
send_message({
"mission_id": "mis_xyz789",
"message": "Bonjour Marie, RDV a 10h au studio. Merci !"
})
// → { message_id: "a1b2...", sender_type: "agent" }Suivre la mission
get_task_status({ "mission_id": "mis_xyz789" })
// → { status: "in_progress", proofs: [...], timeline: [...] }Verifier les preuves
verify_proof({
"mission_id": "mis_xyz789",
"proof_index": 0,
"approved": true
})
// → { all_proofs_verified: true, new_mission_status: "completed" }Evaluer le photographe
rate_human({
"mission_id": "mis_xyz789",
"rating": 5,
"comment": "Photos superbes, livraison rapide !"
})
// → { new_average_rating: 4.92, total_ratings: 24 }Toutes les reponses MCP utilisent le format ToolCallResponse. En cas d'erreur metier, le backend retourne success: false avec un message dans error.
// 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" }] }| Erreur | HTTP | Quand |
|---|---|---|
| Worker not found | 200 (success: false) | human_id invalide dans book_human / get_availability |
| Mission not found | 200 (success: false) | mission_id invalide dans get_task_status / rate_human |
| Deadline must be in the future | 200 (success: false) | Deadline passee dans book_human / submit_task |
| Budget must be positive | 200 (success: false) | Budget <= 0 dans book_human / submit_task |
| Mission not completed | 200 (success: false) | Tentative de noter une mission non terminee |
| Rating must be between 1 and 5 | 200 (success: false) | Note hors limites dans rate_human |
| Index de preuve invalide | 200 (success: false) | proof_index hors limites dans verify_proof |
| Un motif de rejet est requis | 200 (success: false) | approved=false sans rejection_reason |
| La mission ne peut pas etre annulee | 200 (success: false) | Mission completee ou deja annulee dans cancel_mission |
| Un motif d'annulation est requis | 200 (success: false) | reason vide dans cancel_mission |
| Invalid or missing API key | 401 / 403 | Header X-API-Key absent ou cle invalide |
| Validation error | 422 | Parametres manquants ou types invalides |
| Rate limit exceeded | 429 | Trop de requetes (voir limites ci-dessous) |
| Unknown tool | 200 (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.
Les limites de debit dependent de votre plan :
| Plan | Requetes / minute | Requetes / heure |
|---|---|---|
| Free | 100 | 3 000 |
| Premium | 1 000 | 30 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.