Дать ИИ-агенту SwapZilla можно двумя способами, и быстрый уже
опубликован. swapzilla-mcp — открытый (MIT, Node 18+) сервер
Model Context Protocol, который запускается одной строкой и не требует ключа;
он живёт на /ru/mcp/. Свой сервер нужен тогда, когда
обмены должны идти под вашим партнёрским ключом, с вашим белым
списком и вашими лимитами.
- Готовый: шесть инструментов, без аккаунта и без ключа, некастодиальный по конструкции.
- Свой: ордера помечены вашим
PartnerIDи вашимclient_order_id. - В обоих случаях создание ордера не двигает деньги — оно возвращает адрес.
- Ключ, если он есть, живёт в процессе сервера и никогда — в контексте модели.
Опубликованный сервер, одной строкой
npx -y https://swapzilla.io/mcp/swapzilla-mcp-1.0.0.tgz
Зарегистрируйте его в любом MCP-клиенте — Claude Desktop, Claude Code, Cursor, Windsurf — и у агента появятся шесть инструментов:
| Инструмент | Что агент им делает |
|---|---|
swapzilla_list_assets | Определяет точный код актива и сеть — до всего остального. |
swapzilla_list_providers | Смотрит, какие обменники агрегированы и включены. |
swapzilla_get_quote | Сравнивает живые предложения всех провайдеров; у каждого есть ID. |
swapzilla_validate_address | Сначала проверяет адрес получателя для нужной сети. |
swapzilla_create_exchange | Открывает обмен и возвращает DepositAddress. |
swapzilla_get_order | Опрашивает статус вплоть до хеша выплаты. |
Настраивается двумя переменными окружения: SWAPZILLA_API_BASE
(по умолчанию https://api.swapzilla.io) и необязательным
SWAPZILLA_API_KEY, который отправляется как
X-API-Key. Для публичных данных о курсах не нужен ни один из них.
Инструкции по установке, блок конфигурации клиента и сам пакет — на
/ru/mcp/.
Когда нужен свой сервер
Опубликованный сервер намеренно простой: это агрегатор, выставленный инструментами, для того, кто запускает агента. Партнёрской интеграции обычно нужно то, чего в нём нет, — и каждый такой пункт — повод обернуть partner API самостоятельно.
| Что нужно | Почему свой сервер |
|---|---|
| Чтобы обмены были вашими | Вызовы с партнёрским ключом помечаются вашим PartnerID, а GET /v1/partner/orders их перечисляет: атрибуции и сверки с чужой машины не получить. |
| Белый список адресов | Агент, который может назвать любой to_address, может заплатить кому угодно. Проверке место в инструменте, который вы контролируете, а не в промпте. |
| Лимиты расходов | На намерение и на день, проверяются в коде до создания ордера. |
| Человек в контуре | Ваш create_swap может ждать подтверждения, которое в продукте уже есть. |
| Собственные идентификаторы | client_order_id связывает обмен с намерением, тикетом или пользователем, который его вызвал. |
| Защита от повторов | Idempotency-Key на намерение превращает повторный вызов в тот же ордер, а не во второй обмен. |
Свой сервер примерно на пятьдесят строк
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const BASE = "https://api.swapzilla.io";
const KEY = process.env.SWAPZILLA_KEY!; // остаётся в этом процессе
const server = new McpServer({ name: "acme-swaps", version: "1.0.0" });
server.tool(
"quote_swap",
{
from_asset: z.string(), from_network: z.string(),
to_asset: z.string(), to_network: z.string(),
amount_from: z.string().optional(), amount_to: z.string().optional(),
rate_type: z.enum(["floating", "fixed"]).default("floating"),
},
async (args) => {
const r = await fetch(`${BASE}/v1/partner/quotes?${new URLSearchParams(args)}`, {
headers: { "X-API-Key": KEY },
});
const { offers } = await r.json();
// Возвращайте только то, о чём модель должна рассуждать, а не весь ответ.
return { content: [{ type: "text", text: JSON.stringify(offers.slice(0, 5).map((o) => ({
id: o.ID, provider: o.ProviderName, receive: o.ToAmount,
minutes: o.EstimatedMins, kyc: o.KycRating, worse_by_percent: o.DeviationPercent,
}))) }] };
},
);
await server.connect(new StdioServerTransport());
Пишущий инструмент устроен так же — с ограничениями вокруг него:
server.tool(
"create_swap",
{ offer_id: z.string(), to_address: z.string(), intent_id: z.string() },
async ({ offer_id, to_address, intent_id }) => {
assertAllowed(to_address); // ваш белый список
await requireApproval(intent_id); // ваш человек или ваша политика
const r = await fetch(`${BASE}/v1/partner/orders`, {
method: "POST",
headers: {
"X-API-Key": KEY, "Content-Type": "application/json",
"Idempotency-Key": intent_id, // одно намерение — один ордер
},
body: JSON.stringify({
offer_id, to_address,
refund_address: process.env.TREASURY_ADDRESS,
client_order_id: intent_id,
}),
});
const order = await r.json();
return { content: [{ type: "text", text:
`Отправьте ровно ${order.AmountFrom} ${order.FromAsset} в сети ${order.FromNetwork} ` +
`на ${order.DepositAddress}. Ордер ${order.ID}.` }] };
},
);
Читающие инструменты — активы, котировки, проверка адреса, статус — можно спокойно давать агенту. Ворота нужны только тому, который создаёт ордер.
Ограничения, которые стоит поставить
- Белый список адресов получения. Ограничьте
to_addressадресами, которые ваша система уже знает, и отклоняйте остальные внутри инструмента. - Лимиты сумм. На намерение и на день, проверяются в сервере. Здравый смысл модели — не лимит расходов.
- Одно намерение — один idempotency-ключ. Агенты повторяют вызовы; ключ и не даёт повтору стать вторым обменом.
- Котировка и подтверждение внутри пяти минут. Предложения истекают, поэтому план, одобренный через двадцать минут, нужно пересчитать — и инструмент должен об этом сказать, а не молча переоценить.
- Никогда не помещайте ключ в контекст модели. Он живёт в процессе сервера, не возвращается инструментами и не попадает в промпт.
- Логируйте
ProviderOrderID. Это та ссылка, которую понимает поддержка провайдера, если обмен приходится «догонять».
Самое сильное ограничение — структурное. API некастодиален: создание ордера выдаёт депозитный адрес и больше ничего. Пока тот же агент не умеет ещё и отправить депозит, худшее, что он может, — открыть ордер, который никто не оплатит и который истечёт сам.
Чего не может ни один из серверов
| Чего нет | Что это значит |
|---|---|
| Push-уведомлений | Вебхуков нет — статус это вызов инструмента опросом, и ждущий агент должен спрашивать раз в 5–10 секунд, не чаще. |
| Отмены | Ордер нельзя отменить через API. Неоплаченный истекает сам. |
| Перемещения средств | Так задумано. Любой обмен оплачивается кошельком, до которого агент не дотягивается. |
| Песочницы | В продакшене её нет; для детерминированных тестов можно включить на ваш ключ провайдер mock. |
| Скоринга рисков кошелька | Ни AML, ни анализа графов в API нет, поэтому агент не может спросить, рискованный ли адрес. |
Вопросы
Есть ли у SwapZilla официальный MCP-сервер?
Да — swapzilla-mcp с открытым исходным кодом под MIT, на Node 18+, устанавливается одной строкой: npx -y https://swapzilla.io/mcp/swapzilla-mcp-1.0.0.tgz. Он даёт шесть инструментов и не требует ни аккаунта, ни API-ключа для публичных данных о курсах. Всё про установку — на /ru/mcp/; эта страница о собственном сервере, когда в контуре нужны ваш ключ и ваши лимиты.
Когда опубликованного сервера недостаточно?
Когда обмены должны атрибутироваться на ваш партнёрский id, когда адреса получения обязаны приходить из белого списка, когда расходам нужен лимит или подтверждение человека, а также когда каждый обмен должен нести ваш client_order_id для сверки. Всё это живёт в процессе сервера — значит, сервер придётся поднять свой.
Может ли ИИ-агент потратить мои деньги через этот API?
Сам по себе — нет. Обмен некастодиальный: создание ордера возвращает депозитный адрес и ничего не перемещает. Средства двигаются только когда кошелёк отправит этот депозит, а это отдельное действие вне API. Держите возможность отправлять депозит подальше от агента — и худший случай это неоплаченный ордер, который истечёт.
Как не дать агенту повторами создать два обмена?
Дайте каждому намерению идентификатор и передавайте его как Idempotency-Key при создании ордера. Повторный вызов с тем же ключом вернёт исходный ордер, а не откроет второй.
Сколько живёт котировка, на которую опирается агент?
Пять минут. После этого создание ордера по идентификатору предложения падает с 400, и инструменту приходится пересчитать котировку. Показывайте этот срок модели, чтобы долго согласовывавшийся план переоценивался, а не ломался на исполнении.
Стоит ли отдавать агенту сырые ответы API?
Лучше нет. В предложениях больше полей, чем нужно модели; урезанная форма — провайдер, сумма к получению, минуты, KYC-рейтинг, насколько хуже лучшего — удешевляет рассуждение и не превращает случайные значения в выдуманные гарантии.
Что ещё собирают на этом же ключе
- Ссылки на оплату и инвойсы в криптовалютеОплата по ссылке и инвойсы для фрилансеров и подрядчиков: котировка по сумме счёта, зачисление напрямую на кошелёк получателя.
- Крипто-процессинг и эквайринг для бизнесаЧекаут для магазинов и SaaS: приём 100+ активов, зачисление в одном, сверка по вашему order id.
- API обмена криптовалют, SDK и виджетОбмен внутри кошелька, бота, агрегатора или сайта: стриминг котировок, один вызов на ордер, ваш интерфейс.
- Крипто-payroll для подрядчиков и распределённых командРегулярные выплаты реестру подрядчиков: свой актив и сеть у каждого, точная сумма на руки, сверка по периодам.
- Multi-send: массовые выплаты на множество адресовРазовая веерная рассылка выплат на сотни адресов: кросс-чейн, статус по каждому, безопасные повторы.
- Стриминг котировок, живые курсы и price alertsSSE-стрим котировок, всегда свежий фид курсов и отслеживание ордеров — основа для алертов.
Как получить ключ
Зарегистрируйтесь в партнёрском кабинете — партнёрский id и api_key для заголовка X-API-Key выпускаются сразу. Ключ становится рабочим после активации: напишите в @swapzilla_support_bot и коротко опишите интеграцию. Все эндпоинты, поля и статусы — в документации partner API.