Sanka

Sanka é a empresa de extensão. Conecte IA ao seu ciclo de vendas — negócios, cotações, faturamento e mais de 100 integrações de CRM/comércio — diretamente do Claude ou Codex.

Documentação

Servidor MCP Sanka

Este repositório contém o serviço MCP Sanka hospedado e o cliente TypeScript que ele usa para chamar a superfície de API externamente chamável da Sanka. Agora é mantido como um workspace TypeScript normal, não como um repositório gerenciado pela Stainless.

O serviço de produção é um endpoint MCP HTTP Streamable remoto:

  • POST /mcp como endpoint principal
  • POST /sse como alias de compatibilidade para clientes que ainda esperam um caminho no estilo SSE
  • POST / como alias de compatibilidade
  • GET /health para verificações de saúde

O endpoint /mcp expõe tanto as ferramentas gerais do SDK quanto as ferramentas de CRM somente leitura a partir de uma única superfície MCP.

Endpoints de produção:

  • https://mcp.sanka.com/mcp
  • https://mcp.sanka.com/sse

Endpoint de staging:

  • https://sanka-mcp-staging.fly.dev/mcp

Estrutura do repositório

  • src/: cliente TypeScript para a superfície de API externamente chamável da Sanka, usado pelo serviço MCP
  • src/internal/: auxiliares de runtime do SDK privados do pacote, não código de backend privado da Sanka
  • packages/mcp-server/: aplicação do servidor MCP e entrypoint do Docker
  • .github/workflows/: CI além de workflows de deploy do Fly para staging e produção
  • fly.toml: configuração do app Fly de produção
  • fly.staging.toml: configuração do app Fly de staging
  • docs/openapi-maintenance.md: orientações para manter a cobertura da API atualizada sem Stainless

Autenticação

Clientes HTTP hospedados autenticam-se por meio do Connect Sanka. O servidor MCP emite um ID de sessão vinculado a recursos, retorna uma URL https://app.sanka.com/oauth/mcp/connect assinada de connect_sanka ou um resultado de ferramenta protegido, e troca a sessão aprovada internamente por um token de acesso Sanka de curta duração por meio de POST /oauth/internal/mcp-session-token.

O OAuth MCP nativo está intencionalmente desabilitado até que a Sanka V2 implemente o servidor completo de código de autorização. O serviço MCP não publica metadados de servidor de autorização OAuth ou de recurso protegido, e rejeita cabeçalhos Authorization e X-Sanka-API-Key fornecidos pelo cliente. O segredo de troca de token é usado apenas entre sanka-mcp e sanka-api; ele nunca deve ser enviado a clientes MCP.

Leituras do workspace e chamadas switch_workspace bem-sucedidas atualizam a identidade de workspace resolvida mantida para a sessão MCP. O enriquecimento de URL de registro usa, portanto, o código de workspace selecionado imediatamente após uma troca, em vez de reter o código capturado durante a conexão inicial. Chamadas de pré-visualização/início de workflow também releem a sessão MCP atual imediatamente antes do envio, vinculam a solicitação a esse workspace e falham de forma segura se a API resolver um workspace diferente. Isso mantém simulações contábeis e gravações de workflow no mesmo tenant exibido por current_workspace.

Todos os clientes hospedados, incluindo Codex e Claude, usam o mesmo fluxo de URL Connect Sanka. Solicitações não autenticadas de initialize e listagem de ferramentas permanecem disponíveis para que o cliente possa carregar connect_sanka e o fallback de ferramenta protegida.

Tokens de API para desenvolvedores são intencionalmente não suportados para acesso MCP. Eles permanecem válidos para uso direto da API e SDK da Sanka fora do MCP.

Desenvolvimento local

pnpm install
pnpm build
export MCP_SERVER_AUTHORIZATION_SERVER_URL="http://app.localhost:8000"
export MCP_SERVER_INTERNAL_AUTHORIZATION_SERVER_URL="http://api.localhost:8000"
export MCP_SERVER_TOKEN_EXCHANGE_SHARED_SECRET="local-shared-secret"
export SANKA_BASE_URL="http://api.localhost:8000"
node packages/mcp-server/dist/index.js --transport=http --port=8080

Pré-requisitos locais da Sanka:

  • app.localhost:8000 serve /oauth/mcp/connect
  • api.localhost:8000 serve /api/v2/public/*
  • api.localhost:8000 serve /oauth/internal/mcp-session-token
  • o servidor MCP e a API usam o mesmo segredo local de troca de token

Stdio permanece como transporte de desenvolvimento local. SANKA_API_KEY ali é configuração de processo, não um modo bearer fornecido pelo cliente; clientes hospedados devem usar Connect Sanka.

Em seguida, verifique:

curl http://127.0.0.1:8080/health
curl -sS -D - http://127.0.0.1:8080/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0.1"}}}'

Aponte clientes MCP HTTP para http://127.0.0.1:8080/mcp sem cabeçalhos de autenticação estáticos. Chame connect_sanka ou uma ferramenta protegida, abra a URL Connect Sanka retornada e tente novamente com o ID de sessão MCP emitido pelo servidor.

Worker do Browser Use

A ferramenta MCP browser_use despacha workflows de navegador na lista de permissões para um worker separado. O servidor MCP mantém autenticação de sessão, metadados de auditoria, roteamento de workflow e portões de confirmação; o worker é dono do estado do navegador e da interação com UI de terceiros. O primeiro workflow registrado é:

  • demo.hubspot.company_avatar: atualizar avatares de empresas demo do HubSpot por meio da UI do HubSpot quando as APIs de CRM não conseguem definir o avatar visível.

Execute um worker local com agent-browser:

npm install -g agent-browser
agent-browser install

export SANKA_BROWSER_USE_WORKER_TOKEN="local-worker-token"
export SANKA_BROWSER_USE_PROFILE_ROOT=".browser-use-profiles"
export SANKA_BROWSER_USE_ARTIFACT_DIR=".browser-use-artifacts"
pnpm --dir packages/mcp-server browser-use-worker

Aponte o servidor MCP para ele:

export SANKA_BROWSER_USE_WORKER_URL="http://127.0.0.1:8787/run"
export SANKA_BROWSER_USE_WORKER_TOKEN="local-worker-token"

Para produção, implante o worker como um serviço separado, por exemplo no Fly, com um volume persistente montado em SANKA_BROWSER_USE_PROFILE_ROOT para que os cookies de login do HubSpot sobrevivam a reinicializações. Mantenha o worker privado ou protegido por token e exponha apenas /run ao serviço MCP.

Consulte docs/browser-use-worker-fly.md para o app worker do Fly, volume persistente, configuração de segredos e runbook de provisionamento de perfil.

Implantação

Este repositório faz deploy para o Fly a partir de packages/mcp-server/Dockerfile.

  • Deploy manual de produção: fly deploy -c fly.toml
  • Deploy manual de staging: fly deploy -c fly.staging.toml
  • Deploy automático de staging: push para staging
  • Deploy automático de produção: publicar um release do GitHub que tenha como alvo main

Fluxo de release

Use o mesmo formato de promoção do app principal da Sanka:

  1. Abra PRs de funcionalidade em staging.
  2. Faça merge de staging após o CI passar para implantar sanka-mcp-staging.
  3. Valide o endpoint MCP de staging.
  4. Abra staging -> main.
  5. Após main estar pronto, execute Create new Sanka MCP Tag and Release.
  6. O release publicado implanta produção.

Apps e segredos Fly necessários:

  • App de produção: sanka-mcp
  • App de staging: sanka-mcp-staging
  • Defina os mesmos segredos MCP_SERVER_* em ambos os apps, a menos que o staging use intencionalmente uma stack de autenticação diferente.

Política de nova tentativa

O cliente TypeScript tenta novamente 408, 409, 429, erros 5xx e erros de conexão duas vezes por padrão. Apenas ferramentas com metadata.operation: 'read' mantêm essas novas tentativas automáticas. Cada ferramenta de gravação chama a API uma vez e retorna qualquer erro ao agente: uma gravação pode falhar após seu efeito colateral ter ocorrido, como um e-mail que o Gmail aceitou antes de a Sanka registrá-lo, e uma nova tentativa o repetiria. A API também marca erros de rotas de entrega com x-should-retry: false. Ferramentas de resposta relatam DELIVERY_UNKNOWN como um erro de não reenvio.

Direção de manutenção

Este repositório não depende mais do acesso ao projeto Stainless em runtime ou para desenvolvimento contínuo. A cobertura da API deve ser mantida diretamente neste repositório.

O próximo passo recomendado é adotar ferramentas OpenAPI de código aberto para atualizações do cliente TypeScript, em vez de reintroduzir uma dependência de gerador hospedado. Consulte openapi-maintenance.md.

O repositório agora inclui um comando inicial de geração de tipos:

pnpm generate:openapi-types

Por padrão, ele lê a spec irmã da Sanka em ../sanka-sdks/openapi.json.

Developer Cloud (candidato a release)

As ferramentas hospedadas expõem os mesmos contratos V2 de source, run, receipt, certificate e Fleet que a CLI e os SDKs. Esta mudança de fonte não habilita execução em produção. Leia get_developer_cloud_availability primeiro e obedeça ao flag de disponibilidade de cada capacidade. Migração local gratuita e registro de evidências do cliente permanecem inalterados.

Cada chamada usa um workspace_id fixado. Criações pagas e novas tentativas seletivas exigem uma solicitação explícita, cap aprovado, confirm: true e idempotency_key estável. Autorização de usuário existente é suficiente. Uma resposta perdida não deve criar uma nova intenção: leia de volta ou repita a chave e a solicitação idênticas. Nenhuma ferramenta compra créditos, cria PRs de repositório, faz merge ou implanta.

  • Source/run: upload_developer_cloud_source, create_developer_cloud_run, list_developer_cloud_runs, get_developer_cloud_run, cancel_developer_cloud_run.
  • Evidências: list_developer_cloud_events, get_developer_cloud_receipt, list_developer_cloud_artifacts, download_developer_cloud_artifact.
  • Certificados: list_developer_cloud_certificate_keys, get_developer_cloud_certificate, revoke_developer_cloud_certificate.
  • Fleet: create_developer_cloud_fleet, list_developer_cloud_fleets, get_developer_cloud_fleet, cancel_developer_cloud_fleet, retry_developer_cloud_fleet.

Reparo e emissão de certificados usam create_developer_cloud_run.request.repair e .certification, respectivamente. Computação é 100 créditos por minuto de worker, arredondado uma vez por execução. Repair bem-sucedido adiciona 1.000 créditos; emissão independente de certificado adiciona 2.000. Toda computação e prêmios permanecem dentro do cap aprovado. Portões com falha não têm prêmio. Fleet não adiciona sobretaxa: seu cap é a soma dos caps filhos explícitos, reservados atomicamente, com no máximo cinco workers ativos por workspace. Nova tentativa seleciona apenas filhos com falha após o Fleet original se estabelecer; ela cria um novo Fleet e preserva os receipts dos filhos concluídos.

Envie o digest ZIP exato e a revisão completa declarada; o serviço fixa os bytes enviados, mas não prova independentemente sua proveniência Git. Inspecione escopo do certificado, cenários, limitações e revogação. Baixar um certificado não verifica sua assinatura: use a verificação offline da CLI com a chave publicada. Downloads de artefatos verificam bytes contra metadados SHA-256 registrados. MCP suporta até 64 MiB; artefatos maiores usam a CLI/API. Downloads grandes usam a URL vinculada à sessão existente ou o fluxo read_binary_download_chunk.

A regeneração do schema de solicitação usa a entrada compartilhada do SDK V2:

python3 scripts/sync-developer-cloud-contract.py ../sanka-sdks/openapi.json
pnpm exec prettier --write packages/mcp-server/src/generated/developer-cloud-schemas.ts

Workspace incorporado

O app Sanka abre o workspace Flow completo conectado: sua barra lateral, dashboards, tabelas de registros, workflows e relatórios. O acesso completo ao workspace exige autorização explícita da Sanka. Conexões com acesso mais restrito mostram os controles de autorização; a tela anterior do piloto do assistente de Invoice não é mais oferecida.

As ferramentas MCP de invoice hospedadas permanecem disponíveis sob seus escopos existentes e requisitos de confirmação. Remover a tela do piloto não altera registros de invoice nem o contrato da API.