signer-mcp

Assinatura sem chave para CEX/DEX para agentes de IA — as chaves de API da exchange permanecem dentro de um AWS Nitro Enclave, para que um agente com injeção de prompt não possa vazá-las. Binance, OKX, Bybit, KuCoin, Hyperliquid, Asterdex.

Documentação

@usenami/signer-mcp

Assine ordens de CEX de qualquer agente de IA compatível com MCP — as chaves nunca saem de um AWS Nitro Enclave.

signer-mcp é a face pública do Usenami Signer. Ele dá ao Claude Desktop, Cursor, ElizaOS e qualquer outro cliente compatível com MCP uma superfície de seis ferramentas para negociar contas de perpétuos reais de CEX/DEX (Binance, OKX, Asterdex, KuCoin, Bybit, Hyperliquid) sem nunca carregar uma chave privada no processo do agente — nem no seu.

Status: v0 (alpha), piloto baseado em convite. Manifesto de venue, atestado, leitura de conta, ordem de colocação/cancelamento e um hedge de duas pernas. ⚠️ As ordens são reais: qual venue e rede suas ordens atingem é decidido pela política vinculada ao seu token, e na Binance a implantação hospedada assina ordens na mainnet com fundos reais (desde 2026-07-27). Não há rede de segurança implícita de testnet — leia place_order antes de enviar qualquer coisa.


Por que isso existe

Cada framework de agente que toca um CEX hoje carrega a chave de API para o processo do agente. Isso coloca o segredo em disco, em variáveis de ambiente, em pacotes npm, em chamadas de ferramentas engenheiradas por prompt e no seu histórico de shell. Uma injeção de prompt, um comprometimento da cadeia de suprimentos, uma linha de log acidental, um colega curioso — e a chave vaza.

O Signer adota a abordagem oposta. A chave de assinatura é gerada dentro de um AWS Nitro Enclave atestado pela própria AWS. A medição do enclave (PCR0) é publicada em https://usenami.io/signer/attestations. O servidor MCP que você instala aqui pode pedir ao enclave para assinar uma ordem específica — limitada por uma política explícita (teto por ativo, teto por período, venues permitidos) — mas ele não consegue ler a chave. Nem o agente, seu laptop, seu IaC ou nossos próprios engenheiros.

Se o agente for comprometido, o pior que pode fazer é colocar ordens dentro da sua janela de política. A chave em si permanece atestada.


Início rápido (Claude Desktop)

  1. Obtenha um token. O acesso é somente por convite durante o piloto — não há inscrição self-serve ainda; solicite acesso via usenami.io/signer (link de contato no rodapé) e seu token é provisionado no onboarding, vinculado a uma política com tetos por venue. Ainda não tem token? Os passos 2–4 funcionam mesmo assim: list_venues e get_attestation não precisam de token.

  2. Edite claude_desktop_config.json. O caminho é ~/Library/Application Support/Claude/claude_desktop_config.json no macOS.

    {
      "mcpServers": {
        "signer": {
          "command": "npx",
          "args": ["-y", "@usenami/signer-mcp"],
          "env": {
            "SIGNER_GATEWAY_URL": "https://signer-demo.usenami.io:8443",
            "SIGNER_API_TOKEN": "sk_live_..."
          }
        }
      }
    }
    
  3. Reinicie o Claude Desktop e procure pelo ícone de plugue 🔌. Você deve ver seis ferramentas listadas sob signer.

  4. Experimente primeiro as ferramentas somente leitura. Peça ao Claude:

    "Liste os venues disponíveis através do Signer e depois retorne o documento de atestado atual."

    Sem risco de fundos — elas não assinam nada e nenhuma precisa de token.

  5. Depois de ter um token e confiar no atestado, você pode colocar uma primeira ordem — conscientemente. ⚠️ Isso assina uma ordem real no venue que a política do seu token permite. Para Binance na implantação hospedada, isso significa mainnet, dinheiro real — 0.001 BTC é uma posição real, não um exercício de testnet. Verifique list_venues status/notes para o venue primeiro, comece com o menor tamanho que sua política permitir e só então:

    "Obtenha minha conta Binance e, se eu tiver pelo menos $20 de margem livre, coloque uma compra a mercado de 0.001 BTC."

Se algo parecer errado, o agente pode chamar cancel_order imediatamente.


Início rápido (ElizaOS)

O ElizaOS tem um plugin nativo: @usenami/plugin-signer (mesmo contrato de gateway — um token emitido para um funciona com o outro). Prefira-o: as ações caem diretamente no agente, mais um provedor de atestado que mantém o PCR0 atual no contexto.

Alternativamente, o ElizaOS pode alcançar este servidor MCP através da ponte genérica @elizaos/plugin-mcp sobre stdio:

npm install @elizaos/plugin-mcp

Depois, na configuração do seu character/agente:

{
  "plugins": ["@elizaos/plugin-mcp"],
  "settings": {
    "mcp": {
      "servers": {
        "signer": {
          "type": "stdio",
          "command": "npx",
          "args": ["-y", "@usenami/signer-mcp"],
          "env": {
            "SIGNER_GATEWAY_URL": "https://signer-demo.usenami.io:8443",
            "SIGNER_API_TOKEN": "sk_live_..."
          }
        }
      }
    }
  }
}

O agente agora expõe as mesmas seis ferramentas (list_venues, get_attestation, get_account, place_order, place_hedge, cancel_order). Mesmo modelo de confiança: a chave de assinatura nunca entra no processo do Eliza — inicie o agente nas ferramentas somente leitura (list_venues / get_attestation) e verifique o atestado antes de permitir que ele coloque ordens.


Configuração

Variáveis de ambiente passadas via bloco env de claude_desktop_config.json (ou equivalente do seu cliente):

VariávelObrigatóriaPadrãoNotas
SIGNER_GATEWAY_URLnãohttps://signer-demo.usenami.io:8443O enclave atestado de demonstração hospedado. Substitua para implantações auto-hospedadas.
SIGNER_API_TOKENsim (para ferramentas de conta/ordem)Token portador provisionado no onboarding (piloto por convite). list_venues e get_attestation funcionam sem ele; get_account, place_order, place_hedge, cancel_order exigem.
SIGNER_FETCH_TIMEOUT_MSnão30000Timeout de fetch por requisição em ms. Reduza para CI/testes de fumaça; aumente em links lentos. Deve ser inteiro positivo.

O servidor MCP em si não armazena nada em disco. Tokens são lidos do ambiente na inicialização e mantidos em memória durante a vida do processo — mate o agente, o token vai junto.


Referência de ferramentas

list_venues

Retorna o manifesto estático de venues para os quais este Signer pode assinar. Somente leitura, não contata o gateway, funciona sem token. Chame isso primeiro para descobrir o que é suportado.

{
  "venues": [
    {
      "venue": "binance",
      "asset_class": "perp",
      "auth_scheme": "hmac_sha256",
      "status": "live",
      "notes": "..."
    }
  ],
  "count": 7
}

Cada entrada carrega um status: live (o enclave assinará para ele) ou denied (o enclave se recusa por política — fornecer credenciais não mudará isso). Algumas entradas adicionam um campo network (bsc, hyperliquid-testnet, …). Leia status e notes antes de escolher um venue.

Venues suportados

id venuestatusclasse de ativoesquema de authexemplo de símbolonotas
binanceliveperphmac_sha256BTCUSDTFuturos USD-M da Binance. ⚠️ Mainnet, fundos reais na implantação hospedada (desde 2026-07-27)
okxliveperphmac_sha256BTC-USDT-SWAPSwap perpétuo da OKX. Assina apenas onde uma chave OKX está provisionada — a implantação hospedada não tem nenhuma hoje, então lá não assina em lugar nenhum
asterdexliveperpeip712 (bsc)BTC-USDPerp on-chain da Asterdex (BSC)
kucoinliveperphmac_sha256XBTUSDTMKuCoin Futures (HMAC + passphrase criptografada); quantidade em contratos
bybitliveperphmac_sha256BTCUSDTBybit V5 linear (category=linear)
hyperliquid_testnetliveperpeip712 (hyperliquid)BTCO caminho Hyperliquid que realmente assina. Mesmo código de enclave que a mainnet, fonte de agente fantasma da testnet
hyperliquid_mainnegadoperpeip712 (hyperliquid)BTCNegado dentro do enclave — uma negação de política, não uma configuração ausente; fornecer credenciais não mudará isso. Leitura de conta é o clearinghouseState público

O bloco de configuração do agente é idêntico para cada venue — aponte SIGNER_GATEWAY_URL para o seu Signer e defina SIGNER_API_TOKEN. Quais venues um determinado token pode negociar é vinculado no servidor à política desse token; list_venues relata o conjunto completo que o gateway pode assinar, não sua lista de permitidos por token.

get_attestation

Retorna o documento de atestado Nitro para o enclave atualmente em execução. A medição PCR0 aqui é o que a AWS assinou quando inicializou o enclave; você pode verificar se corresponde à build publicada fazendo hash do EIF correspondente e comparando.

{
  "pcr0_sha384": "...sha384 hex...",
  "attestation_doc_b64": "...base64 COSE_Sign1, signed by AWS Nitro...",
  "registered_onchain": true,
  "timestamp_ms": 1785847208571
}

pcr0_sha384 é uma cópia de conveniência; a evidência é attestation_doc_b64 — o documento COSE assinado pela AWS contendo todos os PCRs. Confie no documento, não no campo impresso ao lado dele.

Somente leitura, funciona sem token.

get_account

Retorna patrimônio, margem livre e posições abertas para um venue.

{
  "venue": "binance",
  "equity_usd": 145.32,
  "free_margin_usd": 92.10,
  "positions": [
    { "symbol": "BTCUSDT", "qty": 0.002, "entry_price": 67120.5 }
  ],
  "updated_at": "2026-05-31T18:01:11Z"
}

Somente leitura. Exige SIGNER_API_TOKEN.

place_order

Coloca uma única ordem a mercado ou limitada. O enclave assina o payload após verificar os tetos da política.

Args:

  • venue — um de binance | okx | asterdex | kucoin | bybit | hyperliquid_testnet | hyperliquid_main. ⚠️ v0 tem rotas de ordem estruturadas apenas para binance | okx — outros venues retornam um erro claro (eles expõem acesso somente leitura à conta); e verifique list_venues status primeiro — hyperliquid_main é negado dentro do enclave
  • symbol — canônico (BTC, BTCUSDT, BTC/USDT) ou nativo do venue (BTC-USDT-SWAP, XBTUSDTM, …). O cliente traduz para o formato nativo do venue e ecoa de volta.
  • sidebuy | sell
  • qtysempre quantidade do ativo base (ex.: 0.001 para 0.001 BTC). Não é nocional em USD, não são contratos do venue. Venues denominados por contrato (okx: 1 contrato = 0.01 BTC em BTC-USDT-SWAP) são convertidos automaticamente; tamanhos fora da grade de contratos do venue são rejeitados, nunca arredondados silenciosamente.
  • typemarket | limit
  • price — obrigatório se type=limit, ignorado se type=market
  • policy_id — override opcional; padrão é a política vinculada ao seu token

O resultado inclui um eco de translation — verifique translation.sent para ver o símbolo + tamanho exatos nativos do venue que atingiram a exchange:

{
  "requested": { "symbol": "BTC", "qty": 0.01, "unit": "base_asset" },
  "sent": { "symbol": "BTC-USDT-SWAP", "qty": "1", "unit": "contracts", "ctVal": "0.01" }
}
{
  "venue": "binance",
  "order_id": "...",
  "status": "FILLED",
  "filled_qty": 0.001,
  "avg_fill_price": 67128.9,
  "policy_id": "default",
  "attested_at": "..."
}

Destrutiva. Exige SIGNER_API_TOKEN. ⚠️ As ordens vão para onde a política do seu token as envia — não há roteamento implícito para testnet. Na Binance, a implantação hospedada assina ordens na mainnet com fundos reais (desde 2026-07-27); OKX assina apenas onde uma chave OKX está provisionada (a implantação hospedada não tem nenhuma hoje); Hyperliquid assina em hyperliquid_testnet e é negado em hyperliquid_main. Uma revisão anterior desta seção dizia "v0 roteia Binance/OKX para testnet" — isso estava errado, veja CHANGELOG 0.6.0.

place_hedge

Coloca um hedge de 2 pernas com assinatura atômica: ambas as pernas são assinadas dentro do enclave tudo-ou-nada (uma negação de política em qualquer perna significa que nada é sequer enviado), então o gateway dispara ambas as chamadas de venue em paralelo no lado do servidor — a lacuna entre pernas colapsa para a própria latência dos venues e os cabeçalhos de autenticação assinados nunca transitam pelo seu cliente. ⚠️ A execução do venue não é atômica: os status partial e unknown abaixo existem precisamente porque uma exchange pode aceitar uma perna e perder ou rejeitar a outra.

Args:

  • legs — exatamente 2, cada um {venue, symbol, side, qty, type}. Restrições de v1: type: "market" apenas (uma perna limitada em repouso permitiria que "executado" escondesse uma perna não preenchida — use place_order para limites) e venues limitados a binance | okx. Hedge típico: mesmo símbolo, lados opostos, quantidade igual de ativo base em dois venues.
  • Símbolos e qty usam a mesma tradução canônica/ativo base que place_order; translations por perna são ecoados de volta.

Leia o status do resultado antes de qualquer outra coisa:

  • executed — ambas as pernas vivas.
  • partial — 🔴 exatamente uma perna viva: a posição está NUA. Repare fechando a perna viva ou recolocando a perna rejected. Nunca recolocar uma perna cujo resultado é unknown.
  • unknown — 🔴 o recibo de uma perna foi perdido (timeout / 5xx do venue) — essa ordem pode estar viva. NÃO tente novamente place_hedge; reconcilie primeiro via get_account em ambos os venues.
  • failed — ambas as pernas definitivamente rejeitadas, nada vivo, seguro corrigir e tentar novamente.

Destrutiva (move posições reais em dois venues ao mesmo tempo). Exige SIGNER_API_TOKEN. Gateways mais antigos que o endpoint /hedge retornam um erro claro "use duas chamadas place_order".

cancel_order

Cancela uma ordem em aberto pelo id de ordem do venue. Idempotente — cancelar uma ordem já preenchida ou inexistente retorna ok: false com um motivo do venue em vez de erro. Disponível para binance | okx na v0 — outros venues ainda não têm rota de cancelamento estruturada e retornam um erro claro (mesma limitação do place_order).

Argumentos:

  • venuebinance | okx
  • order_id — o id do venue retornado por place_order
  • symbolobrigatório (BTC canônico ou nativo do venue; traduzido exatamente como place_order) — as rotas REST de cancelamento de ambos os venues precisam dele junto com order_id

Requer SIGNER_API_TOKEN.


Verificação da atestação

Um Signer confiável é aquele cuja medição do enclave corresponde a um build que você pode auditar. O fluxo de trabalho:

  1. Chame get_attestation e copie o pcr0_sha384 retornado (ou, mais rigoroso, leia o PCR0 do próprio attestation_doc_b64 assinado).
  2. Visite usenami.io/signer/attestations.
  3. Compare o PCR0 com o build publicado para a versão de produção atual.
  4. Opcionalmente, reconstrua o EIF a partir do código-fonte e verifique a medição você mesmo — instruções passo a passo: VERIFY-SIGNER-YOURSELF.

Se o PCR0 publicado não corresponder ao que get_attestation retorna, não negocie. Abra uma issue.


O que a v0 deliberadamente NÃO faz

A v0 mantém a superfície deliberadamente enxuta:

  • Sem multi-tenant: uma conta por venue por token.
  • Sem interface de edição de UPL: as políticas são definidas fora da banda em usenami.io/signer.
  • Sem ferramentas WebSocket / streaming — apenas REST.
  • Sem roteamento entre venues (place_order aceita um venue; a única ferramenta multi-venue é o place_hedge fixo de 2 pernas).
  • Sem configuração de alavancagem (set_leverage) — usa os padrões da conta.
  • Sem saques / transferências (o mais próximo é cancel_order).
  • Sem TWAP / iceberg — apenas ordens de disparo único.
  • Apenas transporte stdio — sem SSE ou HTTP remoto.

Se você precisar de qualquer um dos itens acima, abra uma issue descrevendo o caso de uso. A v0 mantém a superfície enxuta de propósito.


Desenvolvimento

# install deps
npm install

# typecheck + build
npm run build

# run from source against the hosted demo enclave
SIGNER_GATEWAY_URL=https://signer-demo.usenami.io:8443 \
SIGNER_API_TOKEN=sk_test_... \
npm run dev

O transporte é stdio; você precisará de um cliente compatível com MCP para realmente exercitar as ferramentas. O mcp-inspector da Anthropic é a maneira mais rápida de testá-lo localmente.


Licença

MIT. Veja LICENSE.