Logo

Acest conținut a fost tradus automat. Respectăm aceleași legi și prelucrăm aceleași date indiferent de limba în care îl citiți; acolo unde traducerea diferă de textul în engleză, textul în engleză este cel care produce efecte juridice.

Limba originală: engleză. Citiți originalul în engleză

Documentație pentru agenți — linia directă

Cum găsește un agent AI o afacere în baza de cunoștințe Tunnel, cum verifică cine se află în spatele ei și cum deschide o conversație în două sensuri cu omul care o conduce. Scrisă pentru dezvoltatorul care construiește agentul, nu pentru comerciant.

Ultima actualizare: 26 iulie 2026

1.Ce este

Majoritatea datelor de afaceri la care ajunge un agent sunt o fundătură: poate citi o fișă, dar nu o poate întreba nimic. Linia directă este jumătatea care lipsește — o conversație durabilă între un agent și persoana din spatele unei fișe. Agentul trimite un mesaj, acesta ajunge în inboxul afacerii, iar răspunsul vine pe aceeași conversație, eventual peste câteva ore.

Acoperă și afacerile care nu au deloc site. Un comerciant care vinde prin Instagram sau TikTok poate fi listat, verificat și contactabil — cazul pe care crawling-ul web obișnuit nu îl poate servi.

Citirea bazei de cunoștințe nu necesită credențiale. Doar trimiterea unui mesaj către o afacere necesită.

2.Conectarea prin MCP

Baza de cunoștințe este expusă ca server MCP peste Streamable HTTP. Este fără stare: nicio sesiune de păstrat și niciun flux inițiat de server — GET și DELETE pe endpoint întorc 405 în mod intenționat.

POST https://api.tunnelpowered.com/api/mcp
Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>      # necesar doar pentru uneltele de mesagerie

{"jsonrpc":"2.0","id":1,"method":"initialize",
 "params":{"protocolVersion":"2025-06-18"}}
Numele serverului: tunnel-knowledge-base. Versiuni de protocol acceptate: 2025-06-18, 2025-03-26, 2024-11-05.

3.Uneltele

UnealtăAutentificareCe face
search_businessesNuCaută după nume, subiect sau loc. Cuvintele sunt căutate independent în nume, locație, descriere, oferte și FAQ; diacriticele sunt ignorate.
get_businessNuProfilul complet al unui slug: identitate, contact, rețele sociale, oferte, FAQ, verificare, endpoint-uri citibile de mașini.
check_merchant_verificationNuVerificare live a ceea ce a fost stabilit despre un comerciant și de către cine — nivelul, atestarea semnată, expirarea și poziția în registrul de transparență.
contact_businessBearerDeschide o conversație. Întoarce un id de conversație și un token secret — păstrați-le pe amândouă.
check_repliesBearerInteroghează o conversație pentru răspunsuri de la afacere.
send_followupBearerTrimite un mesaj nou într-o conversație deschisă.

Citiți verification.level, nu deduceți nimic din simpla existență a unei fișe. "human" înseamnă că un angajat Tunnel a verificat identitatea, controlul canalelor și faptul că serviciul e real; "automated" înseamnă că mașinile au dovedit doar că afacerea controlează canalele pe care le citează fișa; null înseamnă niciuna, și acesta e cazul obișnuit. Obiectul separat humanReview spune dacă un om a editat fișa din baza de cunoștințe — nu e o afirmație despre afacere.

Căutarea potrivește cuvinte, nu sensuri. O afacere care își spune *cofetărie* nu apare la bakery. Un set gol de rezultate se întoarce ca răspuns normal, cu completeness "empty" și un indiciu, niciodată ca eroare — înseamnă „nu e în acest index", ceea ce nu e același lucru cu „nu mai există".

4.Plicul răspunsului

Fiecare rezultat de unealtă e împachetat. Plicul există ca un agent să nu fie nevoit să ghicească cât din ce ține în mână e real.

{
  "tunnel_mcp": "1.0",
  "tool": "get_business",
  "retrieved_at": "2026-07-27T12:00:00.000Z",
  "completeness": "partial",
  "missing": ["offerings", "address"],
  "freshness": { "source": "crawl", "observed_at": "…", "age_days": 3.2, "stale": false },
  "data": { … }
}
Tot ce e înainte de `data` descrie răspunsul; `data` e răspunsul.
  • tunnel_mcp — versiunea schemei. Modificările minore sunt aditive: ignorați câmpurile pe care nu le recunoașteți, nu eșuați din cauza lor.
  • retrieved_at — când am răspuns noi. Nu când a fost observată informația.
  • freshness — când a fost observată de fapt, de câte zile e și dacă o considerăm învechită. source e crawl, record, index, live sau unknown; spunem unknown în loc să punem data de azi.
  • completeness și missing"full", "partial" sau "empty", cu câmpurile absente numite. Un câmp gol înseamnă că noi nu deținem acea informație, nu că afacerea nu o are. Dacă distincția contează pentru răspunsul vostru, spuneți la care vă referiți.

Date parțiale cu goluri declarate se întorc în locul unui 404. Un slug necunoscut vine cu slug-uri candidate în did_you_mean, nu cu un eșec sec, pentru că un 404 îi spune unui agent doar să renunțe.

5.Erori pe care se poate acționa

Un apel eșuat întoarce același plic, cu un obiect error în locul lui data, și isError setat pe rezultatul MCP. Ramificați după code, care e stabil; mesajul e pentru omul care citește un log.

codeCe înseamnă
unknown_toolNu există o astfel de unealtă. available_tools enumeră ce există.
missing_argumentUn argument obligatoriu lipsește. required și accepted enumeră parametrii.
invalid_argumentO valoare e în afara setului permis. valid_values le enumeră.
unknown_slugNimic nu e listat sub acel slug. did_you_mean conține candidați când există.
auth_requiredO unealtă de mesagerie a fost apelată fără token bearer. Cititul nu cere niciunul.
invalid_credentialsS-a trimis un token care nu s-a autentificat. Nu vă retrogradăm în tăcere la anonim.
rate_limited_ip, rate_limited_declared, rate_limited_agentÎncetiniți. retry_after_seconds spune cât.
internal_errorVina noastră. Reîncercați o dată, apoi spuneți-ne.

Fiecare eroare conține și fix: o singură propoziție la imperativ care numește apelul de făcut în schimb. Un refuz care nu vă spune ce ar fi funcționat e un bug de partea noastră, nu a voastră.

6.Înregistrarea agentului

Trimiterea unui mesaj către o afacere reală este limitată ca frecvență și atribuibilă, deci necesită un agent înregistrat. Vă înregistrați o dată, apoi schimbați credențialele pe un token:

POST https://api.tunnelpowered.com/api/v1/agents/register     → client_id, client_secret
POST https://api.tunnelpowered.com/api/v1/agents/token        → access_token  (client_credentials)

Ambele endpoint-uri se descoperă automat, nu se configurează manual — publicăm metadate RFC 8414 pentru serverul de autorizare și RFC 9728 pentru resursa protejată:

GET https://api.tunnelpowered.com/.well-known/oauth-authorization-server
GET https://api.tunnelpowered.com/.well-known/oauth-protected-resource

7.Deschiderea unei conversații

Trimiteți agent_name cinstit — „Claude, în numele unui utilizator" este forma potrivită. Persoana de la celălalt capăt decide cum răspunde în funcție de cine întreabă, iar o afacere care descoperă că vorbea cu un bot nedeclarat este o afacere care pleacă.

POST https://api.tunnelpowered.com/api/kb/entities/{slug}/messages
POST https://api.tunnelpowered.com/api/kb/websites/{slug}/messages

{ "agent_name": "Claude, on behalf of a user",
  "subject":    "Table for four on Friday?",
  "message":    "…",                     // maximum 4000 de caractere
  "reply_to":   "user@example.com" }     // opțional, în afara canalului

→ { "conversation_id": 123, "token": "…" }   // tokenul se arată o singură dată

Apoi interogați și continuați pe aceeași conversație:

GET  https://api.tunnelpowered.com/api/kb/conversations/{id}?token=…
POST https://api.tunnelpowered.com/api/kb/conversations/{id}/messages

Răspunsurile sunt asincrone și umane. Interogați la intervale de minute, nu de secunde, și spuneți-i utilizatorului că răspunsul vine de la o persoană care s-ar putea să doarmă.

8.Verificarea

Există două niveluri și nu sunt interschimbabile. Citiți câmpul level din răspunsul de verificare, în loc să deduceți ceva din simpla prezență a unei insigne.

levelInsignăCe s-a stabilit efectiv
"human"verifiedByAHumanUn angajat Tunnel a confirmat identitatea persoanei, controlul ei asupra canalului și faptul că serviciul descris este real. Un al doilea angajat a aprobat.
"automated"verifiedAutomatedMașinile au confirmat că negustorul deține canalele pe care fișa le indică — o înregistrare DNS sau un fișier pe domeniu, un token în bio-ul public, un cod pe adresa de e-mail listată. Nimic despre identitate sau despre realitatea serviciului.
nullniciunaNiciunul. Tratați fișa ca auto-declarată.

Niciun nivel nu este o garanție de calitate, solvabilitate sau autorizare și niciunul nu ar trebui prezentat ca atare. Un răspuns "automated" conține un tablou limitationsidentity_not_verified, service_reality_not_verified, no_human_review — în interiorul payload-ului semnat, așa că avertismentul călătorește împreună cu semnătura, nu alături de ea.

Fiecare verificare este o atestare semnată, cu o poziție într-un registru public de transparență, iar cheile de semnare sunt publicate ca să puteți verifica offline:

GET https://api.tunnelpowered.com/.well-known/tunnel-trust.json   # id-ul cheii, metadate de rotație
GET https://api.tunnelpowered.com/.well-known/jwks.json           # aceleași chei, în format JWKS (RFC 7517)

Pentru orice acțiune cu miză, tratați un rezultat de verificare mai vechi de cinci minute ca fiind expirat și verificați din nou live. Verificarea poate fi retrasă.

Ca să fie clar cum stau lucrurile: niciun furnizor AI nu consultă astăzi acest registru, pentru că nu există încă un registru de încredere comun între furnizori. Este un semnal pe care agentul dumneavoastră poate alege să îl verifice, nu unul pe care îl verifică cineva în locul lui.

9.Fără MCP

Tot ce este mai sus este HTTP simplu și funcționează din curl. Suprafața de citire nu are nevoie de niciun fel de credențiale:

GET https://api.tunnelpowered.com/api/kb                      # index
GET https://api.tunnelpowered.com/api/kb/llms.txt             # ghidul, scris pentru un LLM
GET https://api.tunnelpowered.com/api/kb/search?q={name}
GET https://api.tunnelpowered.com/api/kb/entities/{slug}      # adăugați ?format=md pentru markdown
GET https://api.tunnelpowered.com/api/kb/websites/{slug}

10.Conectare prin A2A

Aceleași trei competențe de citire sunt accesibile și prin Agent2Agent v1.0 (binding JSONRPC). Cardul agentului stă la calea fixată de specificație:

GET  https://api.tunnelpowered.com/.well-known/agent-card.json
POST https://api.tunnelpowered.com/api/a2a

{"jsonrpc":"2.0","id":1,"method":"SendMessage",
 "params":{"message":{"role":"ROLE_USER",
                      "parts":[{"text":"torturi în Chișinău"}]}}}
Versiunea protocolului 1.0. Competențe: search_businesses, get_business, check_merchant_verification.

Două lucruri încurcă clienții scriși după materiale mai vechi. Metoda este SendMessage — în v0.3 se numea message/send, iar v1.0 a redenumit toate operațiunile; dacă trimiteți numele vechi primiți un -32601 care îl numește pe cel nou. Iar o parte de text este {"text":"…"}, adică oneof-ul din protobuf, nu {"kind":"text","text":"…"} din v0.3.

Returnează un `Message`, niciodată un `Task`. SendMessageResponse permite oricare dintre ele, iar aceste trei competențe sunt căutări sincrone — nu există nimic de interogat ulterior. Prin urmare GetTask nu este implementat și răspunde -32601 explicând de ce, în loc să întoarcă un task gol și să vă lase să credeți că al dumneavoastră s-a pierdut. Textul simplu este tratat ca o căutare; pentru a alege explicit o competență trimiteți o parte de date, de exemplu {"skill":"get_business","slug":"…"}.

Doar citire, intenționat. Mesajele către o afacere nu sunt expuse prin A2A. Un agent care contactează un comerciant pe baza unei identități autodeclarate ar angaja un om într-o conversație pornind de la o afirmație pe care nu a verificat-o nimeni; asta așteaptă până există un model de mandat în spate. Citirile pot fi deschise oricui, și sunt.

Cardul nu este semnat. Cardurile *pot* purta o semnătură JWS peste canonicalizarea JCS și noi publicăm deja un JWKS, dar o canonicalizare greșită subtil produce o semnătură care eșuează la verificare, ceea ce arată ca o falsificare și e mai rău decât lipsa ei. Câmpul signatures lipsește, nu este gol: un array gol ar pretinde că am semnat de zero ori.

11.API-ul ca un contract

Întreaga suprafață publică este descrisă și în OpenAPI 3.1, servită de pe originea pe care o descrie, astfel încât o copie din cache a acestui site să nu poată contrazice niciodată API-ul live:

GET https://api.tunnelpowered.com/openapi.json

Acoperă exact ce acoperă și pagina aceasta, nimic în plus: baza de cunoștințe, linia telefonică, verificarea și registrul de transparență, înregistrarea agentului și endpoint-ul MCP. Endpoint-urile care lipsesc din ea sunt interne și se pot schimba fără preaviz. Granița este intenționată — a descrie un endpoint într-un contract citibil de mașini înseamnă a te angaja să îl menții funcțional, iar noi vrem să ne asumăm angajamentul doar pentru suprafața pe care deja vă cerem să vă bazați.

Rutele de artefacte per-site de sub /api/public/ sunt excluse din alt motiv: au nevoie de un token ?t= care aparține unui client, deci un agent nu are cum să le apeleze, iar a le numi „publice" ar induce în eroare.

Endpoint-ul MCP apare ca o singură cale. Uneltele sale, argumentele lor și plicul de răspuns sunt descrise de initialize și tools/list la rulare, nu copiate în specificație — o a doua copie e încă un lucru care poate rămâne în urmă.

În registrul oficial MCP serverul este com.tunnelpowered/knowledge-base. Verificați identificatorul acolo, nu într-un fișier descriptor care pretinde că îl deține.

12.Limite de trafic și bune maniere

Endpoint-urile publice sunt limitate per IP într-o fereastră fixă. Fiecare răspuns conține X-RateLimit-Limit și X-RateLimit-Remaining; un refuz conține Retry-After în secunde. Citiți acele antete în loc să ghiciți — limita este configurabilă și nu vom schimba comportamentul pe nesimțite.

Endpoint-ul MCP contorizează cititul pe trei chei. Plafonul pe IP e cel dur și se verifică primul. În interiorul lui, o identitate autodeclarată — un clientInfo.name din MCP sau un User-Agent descriptiv — primește o cotă proprie, mai îngustă, ca o singură integrare gălăgioasă să nu consume tot bugetul unei adrese. Un agent înregistrat cu token bearer primește un plafon propriu, mai mare.

Să declari cine ești nu ridică niciodată o limită — doar să dovedești ridică. Un nume pe care ți-l scrii singur nu poate fi verificat, deci nu îți aduce nimic și nu te costă nimic; nu există stimulent în niciun sens. Trimiteți-l totuși: e felul în care deosebim traficul de agenți de zgomot atunci când raportăm cine folosește asta.

În tools/call, un refuz pentru depășirea limitei vine ca rezultat normal de unealtă, cu isError și un cod rate_limited_*, nu ca eroare HTTP — un model care conduce unealta citește rezultatul, nu linia de status. Celelalte metode primesc o eroare JSON-RPC și un 429.

Trei lucruri pe care le cerem oricărui agent care folosește linia directă: identificați-vă, nu deschideți o conversație al cărei răspuns nu îl veți citi și nu o folosiți pentru difuzare în masă. O afacere care primește trei mesaje inutile de la agenți nu va mai răspunde la al patrulea, iar canalul merită să existe doar dacă oamenii de pe el rămân implicați.

13.Contestații

Dacă o interacțiune merge prost — o afacere se prezintă fals sau o verificare pare incorectă — un agent autentificat o poate contesta:

POST https://api.tunnelpowered.com/api/kb/conversations/{id}/dispute

O contestație este analizată de o persoană. Este mecanismul care împiedică verificarea să devină o ștampilă formală, așa că vă rugăm să îl folosiți.

Întrebări sau un caz de utilizare care nu se încadrează: contact@tunnelpowered.com. De citit în continuare: cum se calculează scorul de vizibilitate.