Cum integrezi MCP Tools Vulcanizare Mobilă în asistentul tău AI
Vulcanizare Mobilă expune un server MCP (Model Context Protocol) care permite oricărui asistent AI compatibil să interacționeze cu platforma în numele unui utilizator autentificat. Asistentul poate vedea comenzile active, plasa cereri noi, verifica ofertele primite și accepta un vulcanizator — totul prin conversație naturală.
Cerințe
Un asistent AI cu suport MCP over SSE (Claude Desktop, ChatGPT Desktop, Cursor, sau orice client MCP custom)
Un cont de utilizator Vulcanizare Mobilă (telefon + PIN)
URL endpoint
https://api-v2.vulcanizaremobila.com/sseAcesta este singurul URL pe care trebuie să îl configurezi în asistentul tău AI. Tot restul (autentificare, descoperire tools) este automat.
Autentificare — OAuth 2.0 cu PKCE
Serverul implementează OAuth 2.0 Authorization Code Flow cu PKCE (S256), conform RFC 6749 și RFC 7636. Suportă și Dynamic Client Registration (RFC 7591), deci clienții care îl cer (ex: claude.ai) îl primesc automat.
Discovery automat
Când asistentul accesează /sse fără token, primește:
HTTP 401 Unauthorized
WWW-Authenticate: Bearer realm=”vulcanizare-mcp”,
resource_metadata=”https://api-v2.vulcanizaremobila.com/.well-known/oauth-protected-resource”De acolo, clientul descoperă automat toate endpoint-urile:
GET /.well-known/oauth-protected-resource{
“resource”: “https://api-v2.vulcanizaremobila.com”,
“authorization_servers”: [”https://api-v2.vulcanizaremobila.com”]
}GET /.well-known/oauth-authorization-server{
“issuer”: “https://api-v2.vulcanizaremobila.com”,
“authorization_endpoint”: “https://api-v2.vulcanizaremobila.com/oauth/authorize”,
“token_endpoint”: “https://api-v2.vulcanizaremobila.com/oauth/token”,
“registration_endpoint”: “https://api-v2.vulcanizaremobila.com/oauth/register”,
“response_types_supported”: [”code”],
“grant_types_supported”: [”authorization_code”],
“code_challenge_methods_supported”: [”S256”],
“token_endpoint_auth_methods_supported”: [”none”]
}Fluxul complet pas cu pas
Client AI
|
|-- 1. GET /sse ──────────────────────────────── 401 + WWW-Authenticate
|
|-- 2. GET /.well-known/oauth-protected-resource → { authorization_servers }
|
|-- 3. GET /.well-known/oauth-authorization-server → { authorization_endpoint, ... }
|
|-- 4. (opțional) POST /oauth/register ────────── { client_id }
|
|-- 5. Deschide browser:
| GET /oauth/authorize
| ?client_id=...
| &redirect_uri=...
| &response_type=code
| &code_challenge=BASE64URL(SHA256(verifier))
| &code_challenge_method=S256
| &state=RANDOM
|
Backend
|-- 6. Salvează state → { redirect_uri, code_challenge } (TTL 10 min)
|-- 7. Redirect → https://vulcanizaremobila.com/mcp-auth?state=STATE&redirect_uri=...
|
Pagina de login (browser)
|-- 8. Utilizatorul introduce telefon + PIN
|-- 9. POST /oauth/token-code { phone, pin, state } → { code }
|-- 10. Browser redirect → redirect_uri?code=CODE&state=STATE
|
Client AI
|-- 11. POST /oauth/token
| { code, code_verifier, grant_type: “authorization_code”, redirect_uri }
| → { access_token, token_type: “Bearer” }
|
|-- 12. GET /sse
| Authorization: Bearer <access_token>
| → Conexiune SSE activă
|
|-- 13. Poate apela tools MCPEndpoint-uri OAuth
POST /oauth/register — Dynamic Client Registration
POST /oauth/register
Content-Type: application/json
{
“client_name”: “MyApp”,
“redirect_uris”: [”https://myapp.com/callback”]
}{
“client_id”: “a3f8c2...”,
“client_name”: “MyApp”,
“redirect_uris”: [”https://myapp.com/callback”],
“grant_types”: [”authorization_code”],
“response_types”: [”code”],
“token_endpoint_auth_method”: “none”
}GET /oauth/authorize
Parametri query:
Răspuns: 302 Redirect → pagina de login Vulcanizare Mobilă
POST /oauth/token-code — folosit intern de pagina de login
POST /oauth/token-code
Content-Type: application/json
{
“phone”: “+40712345678”,
“pin”: “1234”,
“state”: “STATE_DIN_URL”
}{ “code”: “abc123def456...” }POST /oauth/token — Client AI schimbă codul pe token
POST /oauth/token
Content-Type: application/json
{
“grant_type”: “authorization_code”,
“code”: “abc123def456...”,
“code_verifier”: “PKCE_VERIFIER_ORIGINAL”,
“redirect_uri”: “https://myapp.com/callback”
}{
“access_token”: “eyJhbGciOiJIUzI1NiIs...”,
“token_type”: “Bearer”
}Tokenul nu are expirare. Rămâne valid pe termen nelimitat, până la logout explicit sau schimbarea cheii secrete a serverului.
Conexiunea SSE
După autentificare, clientul deschide o conexiune SSE persistentă:
GET /sse
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: text/event-streamPrimul eveniment primit indică endpoint-ul pentru trimiterea mesajelor:
event: endpoint
data: /sse-message?sessionId=abc123
Serverul trimite ping la fiecare 25 de secunde pentru a menține conexiunea vie:
: ping
Mesajele JSON-RPC se trimit via:
POST /sse-message?sessionId=abc123
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json
{ “jsonrpc”: “2.0”, “id”: 1, “method”: “tools/list” }MCP Tools disponibile
Toate tool-urile folosesc JSON-RPC 2.0 prin tools/call.
Structura unui apel
{
“jsonrpc”: “2.0”,
“id”: 1,
“method”: “tools/call”,
“params”: {
“name”: “TOOL_NAME”,
“arguments”: { }
}
}get_profile
Returnează profilul utilizatorului autentificat.
Argumente: niciuna
Exemplu răspuns:
Profilul tău
- Nume: Ion Popescu
- Telefon: +40712345678
- Tip cont: individual
- Localitate: Cluj-Napoca, Cluj
- Email: ion@example.comget_active_orders
Returnează cererile de vulcanizare active (status: pending, accepted, active, in_progress).
Argumente: niciuna
Exemplu răspuns:
Cereri active (2)
- #142 [pending] flat_tire
Adresa: Str. Mihai Eminescu 10, Cluj-Napoca
Data: 05.05.2026 14:30
Oferte primite: 3
- #139 [in_progress] puncture
Adresa: Calea Florești 5, Cluj-Napoca
Data: 05.05.2026 10:15get_order_history
Returnează ultimele 20 de cereri din istoricul utilizatorului (toate statusurile).
Argumente: niciuna
Exemplu răspuns:
Istoricul cererilor (ultimele 5)
- #142 [pending] flat_tire — 05.05.2026 14:30
Adresa: Str. Mihai Eminescu 10, Cluj-Napoca
- #135 [completed] puncture — 01.05.2026 09:00
Adresa: Piața Unirii 1, Cluj-Napocaget_request_details
Returnează detaliile complete ale unei cereri, inclusiv ofertele primite.
Argumente:
Exemplu:
{ “request_id”: 142 }Exemplu răspuns:
Cerere #142
- Status: pending
- Problema: flat_tire
- Adresa: Str. Mihai Eminescu 10, Cluj-Napoca
- Descriere: Roata din față stânga complet dezumflată
- Vehicul: car — Dacia Logan, 205/55 R16
- Data: 05.05.2026 14:30
Oferte primite (2):
#1 de la Ion Vulcanizatorul
Pret: 80.00 RON | ETA: 15 min
Status: pending
#2 de la Rapid Vulcanizare
Pret: 95.00 RON | ETA: 20 min
Status: pendinggeocode_address
Convertește o adresă text în coordonate GPS și returnează adresa formatată. Folosește acest tool înainte de create_service_request pentru a valida adresa și a obține coordonatele exacte.
Argumente:
Exemplu:
{ “address”: “Str. Mihai Eminescu 10, Cluj-Napoca” }Exemplu răspuns:
Adresa gasita: Strada Mihai Eminescu 10, Cluj-Napoca, Romania
Latitudine: 46.769785
Longitudine: 23.594559create_service_request
Plasează o nouă cerere de vulcanizare mobilă. Vulcanizatorii disponibili din zonă vor fi notificați imediat.
Argumente:
Valori valide pentru problem_type:
Exemplu:
{
“address”: “Strada Mihai Eminescu 10, Cluj-Napoca”,
“latitude”: 46.769785,
“longitude”: 23.594559,
“problem_type”: “flat_tire”,
“description”: “Roata din față stânga complet dezumflată, probabil puncție”,
“vehicle_type”: “car”,
“car_model”: “Dacia Logan”,
“tire_size”: “205/55 R16”
}Exemplu răspuns:
Cererea #143 a fost creata cu succes!
Adresa: Strada Mihai Eminescu 10, Cluj-Napoca
Problema: flat_tire
Vulcanizatorii din zona ta au fost notificati.cancel_service_request
Anulează o cerere activă. Funcționează doar pe cereri cu status pending sau accepted.
Argumente:
Exemplu:
{ “request_id”: 143 }Exemplu răspuns:
Cererea #143 a fost anulata cu succes.get_request_offers
Returnează ofertele primite de la vulcanizatori pentru o cerere activă.
Argumente:
Exemplu:
{ “request_id”: 142 }Exemplu răspuns:
Oferte pentru cererea #142 (2 oferte):
Oferta #1
- Vulcanizator: Ion Vulcanizatorul
- Pret: 80.00 RON
- Timp estimat sosire: 15 minute
- Status: pending
Oferta #2
- Vulcanizator: Rapid Vulcanizare SRL
- Pret: 95.00 RON
- Timp estimat sosire: 20 minute
- Status: pendingaccept_offer
Acceptă oferta unui vulcanizator. Vulcanizatorul este notificat imediat și se deplasează la locație.
Argumente:
Exemplu:
{
“request_id”: 142,
“offer_id”: 1
}Exemplu răspuns:
Oferta #1 acceptata cu succes pentru cererea #142!
Vulcanizatorul Ion Vulcanizatorul a fost notificat si se indreapta catre locatia ta.Integrare Claude Desktop
Deschide Claude Desktop → Settings → Connectors
Apasă Add connector
Introdu URL-ul:
https://api-v2.vulcanizaremobila.com/sseClaude Desktop deschide automat browserul pe pagina de autentificare
Introdu numărul de telefon și PIN-ul din aplicația mobilă Vulcanizare
Ești redirecționat înapoi — Claude Desktop este acum autentificat
De acum, în orice conversație poți întreba:
“Am o pană la mașină pe Str. Eminescu 10 Cluj, trimite o cerere de vulcanizare”
“Ce cereri active am?”
“Acceptă oferta cea mai ieftină pentru cererea mea”
Integrare ChatGPT Desktop (Mac)
ChatGPT Desktop suportă MCP din versiunea 1.2+.
Deschide ChatGPT Desktop → Settings → Connected apps → Add MCP Server
Introdu:
https://api-v2.vulcanizaremobila.com/sseUrmează același flow OAuth (browser → login → redirect)
Integrare custom (Python)
Exemplu minimal de client MCP cu autentificare OAuth PKCE:
import hashlib, base64, secrets, requests, json
# 1. Generare PKCE
verifier = secrets.token_urlsafe(64)
challenge = base64.urlsafe_b64encode(
hashlib.sha256(verifier.encode()).digest()
).rstrip(b”=”).decode()
state = secrets.token_urlsafe(16)
redirect_uri = “http://localhost:8888/callback”
# 2. Construieste URL de autentificare
auth_url = (
“https://api-v2.vulcanizaremobila.com/oauth/authorize”
f”?client_id=myapp&redirect_uri={redirect_uri}”
f”&response_type=code&code_challenge={challenge}”
f”&code_challenge_method=S256&state={state}”
)
print(f”Deschide in browser: {auth_url}”)
# 3. Primeste codul (din redirect callback)
code = input(”Introdu codul din URL: “)
# 4. Schimba codul pe token
resp = requests.post(
“https://api-v2.vulcanizaremobila.com/oauth/token”,
json={
“grant_type”: “authorization_code”,
“code”: code,
“code_verifier”: verifier,
“redirect_uri”: redirect_uri,
}
)
access_token = resp.json()[”access_token”]
# 5. Apeleaza un tool MCP via SSE + POST
import sseclient
response = requests.get(
“https://api-v2.vulcanizaremobila.com/sse”,
headers={”Authorization”: f”Bearer {access_token}”},
stream=True
)
client = sseclient.SSEClient(response)
for event in client.events():
if event.event == “endpoint”:
endpoint = event.data
break
# 6. Apeleaza tools/list
msg_resp = requests.post(
f”https://api-v2.vulcanizaremobila.com{endpoint}”,
headers={”Authorization”: f”Bearer {access_token}”},
json={”jsonrpc”: “2.0”, “id”: 1, “method”: “tools/list”}
)Tipuri de status pentru cereri
Erori frecvente
Securitate
Toate cererile folosesc HTTPS
Autentificarea folosește PKCE S256 — codul de autorizare nu poate fi interceptat
Fiecare token este legat de un utilizator specific — un asistent nu poate accesa datele altui utilizator
Tokenul poate fi revocat din aplicația mobilă (logout)
Documentație generată pentru API versiunea 2.0 — api-v2.vulcanizaremobila.com

