Logo

Этот текст переведён автоматически. Мы соблюдаем одни и те же законы и обрабатываем одни и те же данные независимо от языка, на котором вы читаете; если перевод расходится с английским текстом, юридическую силу имеет английский текст.

Язык оригинала: английский. Читать оригинал на английском

Документация для агентов — прямая линия

Как AI-агент находит бизнес в базе знаний Tunnel, проверяет, кто за ним стоит, и открывает двусторонний диалог с человеком, который им управляет. Написано для разработчика агента, а не для продавца.

Последнее обновление: 26 июля 2026 г.

1.Что это

Большинство доступных агенту бизнес-данных — тупик: запись прочитать можно, а спросить у неё ничего нельзя. Прямая линия — недостающая половина: устойчивый диалог между агентом и человеком за профилем. Агент отправляет сообщение, оно попадает во входящие этого бизнеса, а ответ приходит в тот же диалог — возможно, через несколько часов.

Это работает и для бизнесов вообще без сайта. Продавца, работающего через Instagram или TikTok, можно перечислить, проверить и сделать доступным для связи — случай, который обычный веб-обход не покрывает.

Для чтения базы знаний учётные данные не нужны. Они нужны только для отправки сообщения бизнесу.

2.Подключение по MCP

База знаний доступна как MCP-сервер поверх Streamable HTTP. Он без состояния: сессию хранить не нужно, потока со стороны сервера нет — GET и DELETE на этом адресе намеренно возвращают 405.

POST https://api.tunnelpowered.com/api/mcp
Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>      # нужен только для инструментов обмена сообщениями

{"jsonrpc":"2.0","id":1,"method":"initialize",
 "params":{"protocolVersion":"2025-06-18"}}
Имя сервера: tunnel-knowledge-base. Поддерживаемые версии протокола: 2025-06-18, 2025-03-26, 2024-11-05.

3.Инструменты

ИнструментАвторизацияЧто делает
search_businessesНетПоиск по названию, теме или месту. Слова ищутся независимо в названии, локации, описании, предложениях и FAQ; диакритика игнорируется.
get_businessНетПолный профиль по slug: идентичность, контакты, соцсети, предложения, FAQ, верификация, машиночитаемые адреса.
check_merchant_verificationНетЖивая проверка того, что именно установлено о продавце и кем — уровень, подписанная аттестация, срок и позиция в журнале прозрачности.
contact_businessBearerОткрывает диалог. Возвращает id диалога и секретный токен — сохраните оба.
check_repliesBearerОпрашивает диалог на предмет ответов от бизнеса.
send_followupBearerОтправляет ещё одно сообщение в открытый диалог.

Читайте verification.level, а не выводите что-либо из самого факта наличия записи. "human" означает, что сотрудник Tunnel проверил личность, контроль над каналами и реальность услуги; "automated" — что машины доказали лишь контроль бизнеса над каналами, которые указаны в записи; null — ни то, ни другое, и это обычный случай. Отдельный объект humanReview говорит о том, редактировал ли человек саму запись в базе знаний, — это не утверждение о бизнесе.

Поиск сопоставляет слова, а не смыслы. Бизнес, называющий себя *cofetărie*, не найдётся по запросу bakery. Пустой результат возвращается как обычный ответ с completeness "empty" и подсказкой, а не как ошибка: он означает «нет в этом индексе», что не то же самое, что «не работает».

4.Конверт ответа

Каждый результат инструмента обёрнут. Обёртка нужна, чтобы агенту не приходилось догадываться, насколько то, что у него в руках, соответствует действительности.

{
  "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": { … }
}
Всё, что до `data`, описывает ответ; `data` — сам ответ.
  • tunnel_mcp — версия схемы. Минорные изменения аддитивны: игнорируйте незнакомые поля, а не падайте на них.
  • retrieved_at — когда ответили мы. Не когда данные были получены.
  • freshness — когда данные были получены на самом деле, сколько им дней и считаем ли мы их устаревшими. sourcecrawl, record, index, live или unknown; мы говорим unknown, а не подставляем сегодняшнюю дату.
  • completeness и missing"full", "partial" или "empty", с перечислением отсутствующих полей. Пустое поле означает, что этих данных нет у нас, а не что их нет у бизнеса. Если различие влияет на ваш ответ, скажите, что именно вы имеете в виду.

Частичные данные с названными пробелами возвращаются вместо 404. Неизвестный slug приходит с вариантами в did_you_mean, а не сухим отказом: 404 говорит агенту только одно — сдавайся.

5.Ошибки, с которыми можно работать

Неудачный вызов возвращает тот же конверт с объектом error вместо data и с isError в результате MCP. Ветвитесь по code — он стабилен; сообщение предназначено человеку, читающему лог.

codeЧто означает
unknown_toolТакого инструмента нет. available_tools перечисляет существующие.
missing_argumentОбязательный аргумент отсутствует. required и accepted перечисляют параметры.
invalid_argumentЗначение вне допустимого набора. valid_values его перечисляет.
unknown_slugПод таким slug ничего нет. did_you_mean содержит варианты, если они есть.
auth_requiredИнструмент отправки вызван без bearer-токена. Для чтения он не нужен.
invalid_credentialsТокен был прислан и не прошёл проверку. Мы не понижаем вас молча до анонима.
rate_limited_ip, rate_limited_declared, rate_limited_agentСбавьте темп. retry_after_seconds говорит, на сколько.
internal_errorНаша вина. Повторите один раз, потом сообщите нам.

В каждой ошибке есть и fix: одно предложение в повелительном наклонении с указанием, какой вызов сделать вместо этого. Отказ, который не говорит, что сработало бы, — это баг на нашей стороне, а не на вашей.

6.Регистрация агента

Сообщение реальному бизнесу ограничено по частоте и атрибутируемо, поэтому нужен зарегистрированный агент. Регистрируетесь один раз, затем меняете учётные данные на токен:

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)

Оба адреса обнаруживаются автоматически, а не прописываются вручную — мы публикуем метаданные сервера авторизации по RFC 8414 и защищённого ресурса по RFC 9728:

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

7.Открытие диалога

Указывайте agent_name честно — «Claude, on behalf of a user» это правильная форма. Человек на другом конце решает, как отвечать, исходя из того, кто спрашивает, а бизнес, который обнаружил, что говорил с необъявленным ботом, — это бизнес, который уходит.

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":    "…",                     // не более 4000 символов
  "reply_to":   "user@example.com" }     // необязательно, вне канала

→ { "conversation_id": 123, "token": "…" }   // токен показывается один раз

Затем опрашивайте и продолжайте в том же диалоге:

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

Ответы асинхронные и человеческие. Опрашивайте с интервалом в минуты, а не в секунды, и скажите пользователю, что отвечает человек, который может спать.

8.Проверка верификации

Уровней два, и они не взаимозаменяемы. Читайте поле level в ответе о верификации, а не делайте выводов из самого наличия знака.

levelЗнакЧто действительно установлено
"human"verifiedByAHumanСотрудник Tunnel подтвердил личность человека, его контроль над каналом и реальность описанной услуги. Второй сотрудник это одобрил.
"automated"verifiedAutomatedМашины подтвердили, что продавец владеет каналами, указанными в записи, — DNS-запись или файл на домене, токен в публичном описании профиля, код на указанный почтовый ящик. Ничего о личности или реальности услуги.
nullнетНи то, ни другое. Считайте запись самозаявленной.

Ни один из уровней не является подтверждением качества, платёжеспособности или наличия лицензии, и подавать так не следует ни один. Ответ "automated" содержит массив limitationsidentity_not_verified, service_reality_not_verified, no_human_review — внутри подписанного payload, поэтому оговорка путешествует вместе с подписью, а не рядом с ней.

Каждая верификация — подписанная аттестация с позицией в публичном журнале прозрачности, а ключи подписи опубликованы, чтобы вы могли проверить её офлайн:

GET https://api.tunnelpowered.com/.well-known/tunnel-trust.json   # id ключа, метаданные ротации
GET https://api.tunnelpowered.com/.well-known/jwks.json           # те же ключи в формате JWKS (RFC 7517)

Для любых значимых действий считайте результат проверки старше пяти минут устаревшим и запрашивайте его заново. Верификацию можно отозвать.

Чтобы было ясно, как обстоят дела: сегодня ни один AI-вендор не обращается к этому реестру, потому что общего межвендорного реестра доверия пока не существует. Это сигнал, который ваш агент может проверить сам, а не тот, который кто-то проверяет за него.

9.Без MCP

Всё описанное выше — обычный HTTP и работает из curl. Для чтения не нужны вообще никакие учётные данные:

GET https://api.tunnelpowered.com/api/kb                      # индекс
GET https://api.tunnelpowered.com/api/kb/llms.txt             # руководство, написанное для LLM
GET https://api.tunnelpowered.com/api/kb/search?q={name}
GET https://api.tunnelpowered.com/api/kb/entities/{slug}      # добавьте ?format=md для markdown
GET https://api.tunnelpowered.com/api/kb/websites/{slug}

10.Подключение по A2A

Те же три навыка чтения доступны и по Agent2Agent v1.0 (биндинг JSONRPC). Карточка агента лежит по пути, который фиксирует спецификация:

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":"торты в Кишинёве"}]}}}
Версия протокола 1.0. Навыки: search_businesses, get_business, check_merchant_verification.

Две вещи сбивают клиентов, написанных по старым материалам. Метод называется SendMessage — в v0.3 это был message/send, и v1.0 переименовала все операции; на старое имя придёт -32601, называющий новое. И текстовая часть — это {"text":"…"}, то есть oneof из protobuf, а не {"kind":"text","text":"…"} из v0.3.

Возвращается `Message`, никогда не `Task`. SendMessageResponse допускает и то, и другое, а эти три навыка — синхронные запросы, опрашивать нечего. Поэтому GetTask не реализован и отвечает -32601 с объяснением, вместо того чтобы вернуть пустую задачу и позволить вам решить, что ваша потерялась. Обычный текст трактуется как поиск; чтобы выбрать навык явно, отправьте часть с данными, например {"skill":"get_business","slug":"…"}.

Только чтение, намеренно. Отправка сообщений бизнесу по A2A не открыта. Агент, обращающийся к продавцу на основании самопровозглашённой личности, вовлёк бы живого человека в разговор по утверждению, которое никто не проверил; это подождёт до появления модели мандата. Чтение безопасно открывать всем — оно и открыто.

Карточка не подписана. Карточки *могут* нести подпись JWS поверх канонизации JCS, и JWKS мы уже публикуем, но незаметно неверная канонизация даёт подпись, которая не проходит проверку, — это выглядит как подделка и хуже, чем её отсутствие. Поле signatures отсутствует, а не пусто: пустой массив утверждал бы, что мы подписали ноль раз.

11.API как контракт

Вся публичная поверхность описана и в виде OpenAPI 3.1. Документ отдаётся с того же источника, который он описывает, — чтобы закэшированная копия этого сайта никогда не разошлась с живым API:

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

Он покрывает ровно то же, что и эта страница, и ничего сверх: базу знаний, линию связи, верификацию и журнал прозрачности, регистрацию агента и MCP-эндпоинт. Адреса, которых в нём нет, — внутренние и могут измениться без предупреждения. Эта граница проведена намеренно: описать эндпоинт в машиночитаемом контракте — значит взять обязательство его поддерживать, а брать его мы хотим только на ту поверхность, полагаться на которую уже просим вас.

Маршруты артефактов отдельных сайтов под /api/public/ исключены по другой причине: им нужен токен ?t=, принадлежащий клиенту, поэтому агент физически не может их вызвать, и называть их «публичными» было бы обманом.

MCP-эндпоинт представлен одним путём. Его инструменты, их аргументы и конверт ответа описываются вызовами initialize и tools/list во время работы, а не копируются в спецификацию: вторая копия — это второе место, которое может отстать.

В официальном реестре MCP сервер называется com.tunnelpowered/knowledge-base. Проверяйте идентификатор именно там, а не в файле-дескрипторе, который его декларирует.

12.Лимиты запросов и правила приличия

Публичные адреса ограничены по частоте на IP в фиксированном окне. В каждом ответе есть X-RateLimit-Limit и X-RateLimit-Remaining; в отказе приходит Retry-After в секундах. Читайте эти заголовки, а не угадывайте — лимит настраиваемый, и мы не станем менять поведение молча.

MCP-адрес считает чтения по трём ключам. Потолок по IP — жёсткий, он проверяется первым. Внутри него самозаявленная личностьclientInfo.name из MCP или содержательный User-Agent — получает собственную, более узкую долю, чтобы одна шумная интеграция не съела весь бюджет адреса. Зарегистрированный агент с bearer-токеном получает собственный, более высокий потолок.

Заявить, кто вы, никогда не поднимает лимит — поднимает только доказать. Имя, которое вы пишете о себе сами, непроверяемо, поэтому оно ничего не даёт и ничего не стоит; стимула нет ни в ту, ни в другую сторону. Присылайте его всё равно: так мы отличаем трафик агентов от шума, когда отчитываемся о том, кто этим пользуется.

Внутри tools/call отказ по лимиту приходит как обычный результат инструмента с isError и кодом rate_limited_*, а не как HTTP-ошибка: модель, управляющая инструментом, читает результат, а не строку статуса. Остальные методы получают JSON-RPC-ошибку и 429.

Три вещи, о которых мы просим любого агента на прямой линии: представляйтесь, не открывайте диалог, ответ на который не прочитаете, и не используйте её для массовых рассылок. Бизнес, получивший три бесполезных сообщения от агентов, не ответит на четвёртое, а канал имеет смысл только пока люди на нём остаются вовлечёнными.

13.Оспаривание

Если взаимодействие пошло не так — бизнес представил себя ложно или верификация выглядит неверной — аутентифицированный агент может это оспорить:

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

Оспаривание рассматривает человек. Это механизм, не дающий верификации превратиться в формальную печать, поэтому пользуйтесь им.

Вопросы или сценарий, который сюда не укладывается: contact@tunnelpowered.com. Дальше по теме: как рассчитывается оценка видимости.