Этот текст переведён автоматически. Мы соблюдаем одни и те же законы и обрабатываем одни и те же данные независимо от языка, на котором вы читаете; если перевод расходится с английским текстом, юридическую силу имеет английский текст.
Язык оригинала: английский. Читать оригинал на английском
Документация для агентов — прямая линия
Как 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"}}3.Инструменты
| Инструмент | Авторизация | Что делает |
|---|---|---|
search_businesses | Нет | Поиск по названию, теме или месту. Слова ищутся независимо в названии, локации, описании, предложениях и FAQ; диакритика игнорируется. |
get_business | Нет | Полный профиль по slug: идентичность, контакты, соцсети, предложения, FAQ, верификация, машиночитаемые адреса. |
check_merchant_verification | Нет | Живая проверка того, что именно установлено о продавце и кем — уровень, подписанная аттестация, срок и позиция в журнале прозрачности. |
contact_business | Bearer | Открывает диалог. Возвращает id диалога и секретный токен — сохраните оба. |
check_replies | Bearer | Опрашивает диалог на предмет ответов от бизнеса. |
send_followup | Bearer | Отправляет ещё одно сообщение в открытый диалог. |
Читайте 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": { … }
}tunnel_mcp— версия схемы. Минорные изменения аддитивны: игнорируйте незнакомые поля, а не падайте на них.retrieved_at— когда ответили мы. Не когда данные были получены.freshness— когда данные были получены на самом деле, сколько им дней и считаем ли мы их устаревшими.source—crawl,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-resource7.Открытие диалога
Указывайте 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" содержит массив limitations — identity_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":"торты в Кишинёве"}]}}}Две вещи сбивают клиентов, написанных по старым материалам. Метод называется 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. Дальше по теме: как рассчитывается оценка видимости.