dtwin Gateway
dtwin Gateway · MCP-шлюз

Туннель для AI-агентов.

Claude Code, Cursor или любой MCP-агент читает внутренние Jira, GitLab и SQL — только то, что разрешено. С маскированием, аудитом и kill-switch.

01 · Проблема

Не отдавайте агенту пароли.

Дать агенту токен Jira и пароль БД легко, но потом не узнать, кто и что прочитал. Шлюз выдаёт агенту один личный токен.

  • 1Секреты остаются в офисе
  • 2Каждый вызов попадает в журнал
Обычный путь · .env агента
JIRA_TOKEN=jira_••••••••
GITLAB_TOKEN=glpat-••••••
DB_USER=sa
DB_PASSWORD=••••••••••
  • ✕Пароли у агента
  • ✕Журнала нет
  • ✕Остановить нельзя
→
Через шлюз
Authorization:
Bearer ag_aziz_••••
  • Только разрешённые инструменты
  • Каждый вызов в аудите
  • Останавливается одной кнопкой
02 · Как это работает

Один шлюз — полный контроль.

Агент общается только со шлюзом. Шлюз проверяет, маскирует, записывает и передаёт запрос через туннель офисному коннектору.

  • 1MCP Streamable HTTP
  • 2Коннектор слушает только 127.0.0.1
Офисная сеть
tunnel
Claude Code
Cursor
MCP-клиент
gateway.dtwin.uz
токен
права
лимит
маска
аудит
коннектор
127.0.0.1
Jira
GitLab
SQL
03 · Подключение

Три шага — одна команда.

Админ создаёт агента, вы получаете токен и запускаете одну команду. Claude Code, Cursor или любой MCP-клиент.

  • 1Токен показывается один раз
  • 2Для Cursor есть JSON-конфиг
1Админ создаёт агентапанель → Агенты
2Вы получаете токенag_aziz_…
3Одна командаclaude mcp add
~/acme-pay — zsh
$ claude mcp add --transport http dtwin https://gateway.dtwin.uz/mcp --header "Authorization: Bearer ag_aziz_q7Lm2X…"
✓ Added HTTP MCP server dtwin with URL: https://gateway.dtwin.uz/mcp
$ claude
● dtwin · подключён · доступно 5 инструментов
Claude CodeCursorлюбой MCP-клиент
04 · Личный токен

Токен — один раз и лично.

У каждого агента свой токен ag_<имя>_…. На сервере хранится только sha256 — открытого токена нигде не остаётся.

  • 120 ошибок / 10 минут — IP блокируется
  • 2Перевыпуск в любой момент (rotate)

Новый агент

Имя
aziz
Владелец
Aziz (backend)
Инструменты
acme-jira_*, acme-gitlab_mr*, acme-sql_query
Лимит
30 / минуту
Создать
ag_aziz
ag_aziz_q7Lm2Xv9Tc4Rb8Np1Kd6Wf3Hs5Jy0GaE
⚠ Виден только сейчас — скопируйте
Копировать
Хранится на сервере sha256 · 4f9a1c0e…d27be20d
Тормоз брутфорса
20/ 20неверных попыток · один IP
IP заблокирован на 10 минут
05 · Живой пример

Один вопрос — три системы.

Разработчик спрашивает Claude. Агент сам читает Jira, GitLab и БД stage и отвечает с доказательствами.

  • 1Каждый шаг виден в админ-панели
  • 2Данные приходят уже замаскированными
claude · ~/acme-paydtwin · MCP
> Почему упал PAY-142?
● dtwin - acme-jira_issue (key: "PAY-142")
└ Reopened · 4 комментария · связан MR !318
● dtwin - acme-gitlab_mr (iid: 318)
└ +12 −3 · изменено округление InvoiceTotal
● dtwin - acme-sql_query (db: "stage", sql: "SELECT TOP 20 Id, Total …")
└ 3 строки · 41 мс · ROLLBACK
● Причина в !318: итог теперь округляется до 2 знаков, и на stage в 3 строках dbo.Invoice расхождение 0.01. Это и есть ошибка, которую нашла Dilnoza (QA).
◆3 инструмента · 0 отказов · замаскировано 4 поля
06 · Путь вызова

Каждый пакет — через шесть проверок.

После tools/call проверяются токен, права и лимит, а ответ коннектора возвращается замаскированным и записанным в журнал.

  • 1Отклонённый вызов тоже пишется
  • 2В результате видно, сколько полей скрыто
{ "jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": { "name": "acme-sql_query", "arguments": { "db": "stage", "sql": "SELECT TOP 20 Id, Total FROM dbo.Invoice WHERE …" } } }
tools/call
Токенsha256 ✓
Праваallowlist
Лимит12 / 30
Коннектор41 мс
Маска4 поля
АудитJSONL + SSE
результат агенту3 строки4 маски63 мс
07 · Права

Нет права — не виден и инструмент.

Админ задаёт агенту список с glob: *, acme-jira_*, acme-sql_query. Инструмента вне списка нет в tools/list, а вызов отклоняется.

  • 1Лимит в минуту, по умолчанию 30
  • 2Можно поставить на паузу одного агента
AZ
aziz
Aziz (backend)
on
Права · glob
acme-jira_*acme-gitlab_mr*acme-sql_query
Лимит · в минуту
12 / 30
tools/call → acme-sql_schema ✕ отказ · нет права
tools/list · видит агент
acme-jira_search✓
acme-jira_issue✓
acme-gitlab_mrs✓
acme-gitlab_mr✓
acme-gitlab_fileскрыт
acme-gitlab_searchскрыт
acme-gitlab_commitsскрыт
acme-sql_schemaскрыт
acme-sql_query✓
08 · Маскирование

Персональные данные — не доходят до агента.

Каждый результат проверяется до отправки агенту: ПИНФЛ, паспорт, телефон, email, карта, токены скрываются. Число скрытых полей видно в каждом вызове.

  • 1ИНН — по желанию
  • 2Типы включаются в панели
acme-sql_query · результат
phone+998 ** *** ** 67
phone+998 ** *** ** 34
phone+998 ** *** ** 40
pinfl31**********56
inn301234567
4
Скрыто в этом вызове
телефон ×3ПИНФЛ ×1
Типы маски
ПИНФЛ30**********56
ПаспортAB*****67
Телефон+998 ** *** ** 67
Emaila***@mail.uz
Карта**** **** **** 1234
JWT / токенPassword=***
ИННопция
09 · SQL guard

DELETE? Нет.

Guard пропускает только один SELECT или WITH. INTO, EXEC, sp_/xp_, OPENROWSET, WAITFOR, «;» — запрос останавливается, не дойдя до базы.

  • 1Отклонённый запрос остаётся в аудите
  • 2Проверка на стороне коннектора
acme-sql_query · stage
DELETE FROM dbo.Invoice WHERE Status = 3
✕ ОТКЛОНЕНОразрешён только один SELECT / WITH
ЗапрещеноDELETEUPDATEINSERTINTOEXECsp_ / xp_OPENROWSETWAITFOR;
acme-sql_query · stage
SELECT TOP 20 Id, Total FROM dbo.Invoice WHERE Total % 0.01 <> 0
✓ прошёл · 3 строки · 41 мсROLLBACK
10 · Только чтение

Записать нельзя — по устройству.

Даже пропущенный guard'ом запрос идёт в транзакции READ UNCOMMITTED и всегда откатывается. На prod — read-only логин на уровне БД.

  • 1Таймаут 30 секунд
  • 2Не больше 200 строк
SQL guardодин SELECT / WITH
ТранзакцияREAD UNCOMMITTED
Времятаймаут 30 с
Объём≤ 200 строк
Итогвсегда ROLLBACK
Prodread-only логин БД
connector · sql
BEGIN TRAN
SET ISOLATION LEVEL
READ UNCOMMITTED
SELECT TOP 20 Id, Total
FROM dbo.Invoice …
-- 3 rows · 41 ms
ROLLBACK
ROLLBACK ✓
0изменений
11 · Аудит

Кто, что, когда — всё записано.

Агент, инструмент, замаскированные аргументы, статус, мс, байты и число масок. JSONL хранится 30 дней и в реальном времени идёт в панель через SSE.

  • 1Фильтр по агенту и дню
  • 2Аргументы тоже маскируются
времяагентинструментстатусмсмаска
14:03:02azizacme-jira_searchok1880jql: "project = PAY AND status = Reopened"
14:02:40dilnozaacme-sql_queryотказ20sql: "DELETE FROM dbo.Invoice …"
14:02:15azizacme-sql_queryok414db: "stage", sql: "SELECT TOP 20 Id, Total …"
14:02:13azizacme-gitlab_mrok3880iid: 318
14:02:11azizacme-jira_issueok2120key: "PAY-142"
14:01:57ci-botacme-gitlab_commitsok1640ref: "main", limit: 20
SSEdata/log/2026-11-02.jsonl · хранится 30 дней
12 · Живая панель

Каждый вызов — перед глазами.

Поток от агентов к ядру и от ядра к коннекторам. Красная вспышка — отказ, фиолетовая — замаскированные данные.

  • 13D-поток + лента + статистика
  • 2Одна страница, ничего не нужно вводить
gateway.dtwin.uz/adminLIVE
gateway ядро azizdilnozaci-bot acmeacme-qa
1 284вызовы
17отказы
3ошибки
342маски
84p50 · ms
410p95 · ms
13 · Kill-switch

Одна кнопка — всё остановлено.

При подозрении админ нажимает kill-switch: ни один вызов агента не проходит. Можно также поставить на паузу одного агента или отключить один коннектор.

  • 1Включить обратно — тоже одна кнопка
  • 2Причина пишется в журнал
gateway.dtwin.uz/admin · kill-switch
Kill-switch включён · вызовы отклоняются
ОСТАНОВИТЬ ВСЁ
Агенты
AZ
azizAziz (backend)
активенПауза
DI
dilnozaDilnoza (QA)
активенПауза
CI
ci-botCI
активенПауза
Коннекторы
acmetunnel · 9 tools
активенВыключить
14 · Секреты в офисе

Пароли — не покидают офис.

Пароли БД, токены Jira и GitLab лежат только в маленьком офисном коннекторе. Он слушает 127.0.0.1 и публикуется для шлюза через tunnel.dtwin.uz.

  • 1Шлюз обращается к коннектору с bearer secret
  • 2tunnel.dtwin.uz — родственный продукт
Облако
gateway.dtwin.uz
0секретов
sha256auditpolicy
Офисная сеть
коннектор
127.0.0.1:8095 · Bearer
БД stage · read-only логин
Токен Jira
Токен GitLab
tunnel.dtwin.uzbearer secret
15 · Инструменты

Девять инструментов — все только для чтения.

Jira, GitLab и SQL — то, что разработчик спрашивает каждый день. Без npm-зависимостей, один маленький контейнер.

  • 1Имя инструмента с именем коннектора: acme-…
  • 2Новый коннектор — новые инструменты
jira_searchпоиск по JQL
jira_issueописание + комментарии + связи
gitlab_mrsсписок MR
gitlab_mrописание + diff
gitlab_fileфайл с диапазоном строк
gitlab_searchпоиск по коду
gitlab_commitsистория коммитов
sql_schemaтаблицы и столбцы
sql_querySELECT · ≤ 200 строк
read-only0 npm-зависимостейодин контейнерNode 20+
16 · Подтверждение человеком Скоро

Рискованный шаг — с подтверждением.

Если агент хочет написать комментарий в Jira, запрос приходит в панель или Telegram. Пока админ не подтвердит, ничего не записывается.

  • 1Пишущие инструменты — только с подтверждением
  • 2Кто подтвердил — в аудите
Запрос на подтверждениеСкоро
aziz → acme-jira_comment
PAY-142: исправлено в !318, проверено на stage.
ПодтвердитьОтклонить
✓ Подтверждено · admin · 14:05
claude
● acme-jira_comment
└ ждём подтверждения админа…
└ ✓ комментарий добавлен
17 · Дорожная карта

Следующие шаги — план готов.

Шлюз растёт: пишущие инструменты, тонкие политики и новые коннекторы. Отмечены значком.

Подтверждение человекомв панели или TelegramСкоро
Пишущие инструментынапример, комментарий Jira — с подтверждениемСкоро
Политики prod БДна уровне строк и столбцовСкоро
Коннектор логовSeq / GrafanaСкоро
Токены и затратыучёт по каждому агентуСкоро
Алерты об аномалияхсразу в TelegramСкоро
OAuth-входMCP auth вместо статичных токеновСкоро
Повтор вызоваreplay для разбораСкоро
Multi-tenantдля других компанийСкоро
Начать

Подключите агента сегодня.

Получите токен у админа и запустите одну команду — а потом спросите агента о любой задаче.

← → или нажмите · P пауза · O все · F полный экран
пауза · продолжить: P или ▶

dtwin Gateway · все разделы