AgentCore_
EN Início GitHub

$ cat docs/api.md

Documentação da API

Referência completa da API HTTP exposta pelo AgentCore: os endpoints próprios do adapter (configuração, sessões, eventos) e os controles exclusivos de cada runtime já implementado (Claude Code, Codex e OpenCode).

# base URL local, definida em src/server.ts

$ curl http://127.0.0.1:3000/health

# todas as rotas abaixo, exceto /health, vivem sob o prefixo /v1

$ curl http://127.0.0.1:3000/v1/sessions

$ cat convencoes.md

Não existe namespace de URL por provedor (nada de /providers/claude ou /:provider/...). Toda sessão, independente do runtime, é acessada pelos mesmos endpoints /v1/sessions/:sessionId/.... A distinção acontece dentro do handler, olhando o campo runtime da sessão. Rotas que não fazem sentido para um runtime respondem 400 com uma mensagem explicando a restrição.

Erros seguem sempre o mesmo formato, { "error": "mensagem" }, com o HTTP status comunicando a categoria:

Status Significado
400Body/params inválidos, ou a operação não se aplica ao runtime da sessão
404Sessão, permissão ou histórico não encontrado
409Conflito de estado (sessão ocupada, sem conversa pra ramificar/reverter ainda, etc.)
502Falha ao falar com o provedor (Claude SDK / Codex SDK / servidor OpenCode)

CORS fica habilitado só fora de produção (NODE_ENV !== "production"). Em produção a API é pensada pra ser consumida localmente, sem navegador cruzando origem.

$ cat modelos.md

AgentSession

{
  id: string,
  runtime: "claude" | "codex" | "opencode",
  projectPath: string,
  providerSessionId?: string,
  status: "ready" | "running" | "waiting_permission"
        | "completed" | "cancelled" | "error",
  createdAt: Date,
  title?: string,
  forkedFrom?: string,
  forkedFromMessageId?: string,
  tag?: string,
  permissionMode?: "default" | "acceptEdits" | "bypassPermissions"
                 | "plan" | "dontAsk" | "auto",
  model?: string,

  // exclusivos do Claude
  claudeDeniedTools?: string[],
  claudeEffortLevel?: "low" | "medium" | "high" | "xhigh",
  usage?: SessionUsage,

  // exclusivos do Codex
  codexSandboxMode?: "read-only" | "workspace-write" | "danger-full-access",
  codexReasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh",
  codexWebSearchMode?: "disabled" | "cached" | "live",
  codexWebSearchEnabled?: boolean,
  codexAdditionalDirectories?: string[],
  codexUsage?: CodexSessionUsage,
}

AgentEvent (formato de cada mensagem SSE)

{ type: "agent.started", sessionId }
{ type: "user.message", sessionId, text, messageId?, attachments? }
{ type: "assistant.delta", sessionId, text }
{ type: "assistant.message", sessionId, text, messageId? }
{ type: "tool.started", sessionId, tool, input }
{ type: "tool.completed", sessionId, tool, output? }
{ type: "permission.requested", sessionId, permissionId, tool, description }
{ type: "agent.completed", sessionId }
{ type: "agent.cancelled", sessionId }
{ type: "agent.error", sessionId, message }
{ type: "agent.todo_list", sessionId, items: [{ text, status }] }

Formatos de uso por runtime

// Claude (session.usage)
{ totalCostUsd, inputTokens, outputTokens,
  cacheReadInputTokens, cacheCreationInputTokens,
  modelUsage: { [model]: { inputTokens, outputTokens,
    cacheReadInputTokens, cacheCreationInputTokens, costUsd } } }

// Codex (session.codexUsage)
{ inputTokens, cachedInputTokens, cacheWriteInputTokens,
  outputTokens, reasoningOutputTokens }

// OpenCode (consultado ao vivo no servidor OpenCode)
{ costUsd, inputTokens, outputTokens, reasoningTokens,
  cacheReadTokens, cacheWriteTokens }

$ ls core/health

GET /health

Checagem de liveness. Única rota que não vive sob /v1.

Resposta 200

{ status: "ok", version: "0.1.0" }

$ ls core/config

GET /v1/config

Retorna a configuração atual do adapter: quais runtimes estão habilitados.

Resposta 200

{
  claude: { enabled: boolean },
  codex: { enabled: boolean },
  opencode: { enabled: boolean },
}
PATCH /v1/config

Habilita/desabilita um ou mais runtimes de uma vez. Persistido em data/config.json.

Body (pelo menos uma chave é obrigatória)

CampoTipo
claude{ enabled?: boolean }
codex{ enabled?: boolean }
opencode{ enabled?: boolean }

Resposta 200

A configuração completa já atualizada, mesmo formato do GET /v1/config.

$ ls core/agents

GET /v1/agents

Lista os runtimes habilitados e os modelos que cada um relata como disponível (consulta ao vivo via listModels() de cada runtime).

Resposta 200

{
  agents: [
    { runtime: "claude" | "codex" | "opencode",
      models: [{ id: string, displayName: string, description?: string }] }
  ]
}

Um runtime cuja consulta de modelos falhar é simplesmente omitido da lista (o erro é apenas logado).

$ ls sessions/ciclo-de-vida

Válidos para os três runtimes, salvo indicação contrária em cada rota.

POST /v1/sessions

Cria um registro de sessão. Não inicia o agente, isso só acontece ao enviar a primeira mensagem.

Body

CampoTipoObrigatório
runtime"claude" | "codex" | "opencode"sim
projectPathstringsim

Resposta 201

Objeto AgentSession.

GET /v1/sessions

Lista sessões conhecidas, com filtro por status e paginação.

Query params

CampoTipoPadrão
statusready | running | waiting_permission | completed | cancelled | error(sem filtro)
limitinteiro positivo20
offsetinteiro >= 00

Resposta 200

{ sessions: AgentSession[], total: number, limit: number, offset: number }
GET /v1/sessions/:sessionId

Consulta o estado atual de uma sessão (status, providerSessionId, configurações, uso, etc).

Resposta 200

Objeto AgentSession. 404 se não existir.

PATCH /v1/sessions/:sessionId

Renomeia a sessão, alterando apenas o título exibido.

Body

CampoTipoObrigatório
titlestringsim

Resposta 200

Objeto AgentSession atualizado.

DELETE /v1/sessions/:sessionId

Remove o registro local da sessão e, quando o runtime suporta, também a conversa do lado do provedor (Claude e OpenCode; Codex não tem equivalente na SDK).

Resposta 200

{ deleted: true }

409 se a sessão estiver running ou waiting_permission.

GET /v1/sessions/:sessionId/history

Histórico de mensagens da conversa, normalizado para o formato AgentEvent. A fonte varia por runtime: log local do Codex, API nativa do OpenCode, ou getSessionMessages da Claude Agent SDK.

Query params

CampoTipo
limitinteiro positivo
offsetinteiro >= 0

Resposta 200

{ events: AgentEvent[] }

404 se a sessão nunca chegou a trocar mensagens com o agente.

GET /v1/sessions/:sessionId/usage

Uso acumulado de tokens/custo da sessão. Formato depende do runtime, veja Modelos de dados.

Resposta 200

session.usage (Claude), session.codexUsage (Codex) ou consulta ao vivo no servidor OpenCode.

POST /v1/sessions/:sessionId/fork

Ramifica a conversa em uma nova sessão independente, sem afetar a original.

Body

CampoTipoObrigatório
upToMessageIdstringnão (corta a ramificação nessa mensagem)

Resposta 201

Nova AgentSession, com forkedFrom apontando pra sessão original.

somente claude / opencode Codex não tem operação de fork na SDK. 409 se a sessão ainda não tem conversa (sem providerSessionId).

POST /v1/sessions/:sessionId/tag

Define ou limpa uma tag livre na sessão.

Body

CampoTipoObrigatório
tagstring | nullsim (null limpa a tag)

Resposta 200

Objeto AgentSession atualizado.

Para sessões Claude com conversa já iniciada, a tag também é espelhada do lado do provedor.

$ ls sessions/execucao

POST /v1/sessions/:sessionId/messages assíncrono

Envia uma mensagem ao agente. A execução roda em background; a resposta HTTP volta imediatamente e o progresso é acompanhado via SSE. Limite de corpo de 32 MB (por causa dos anexos em base64).

Body

CampoTipoObrigatório
contentstringsim
attachments{ kind: "image"|"document", mediaType, data (base64), filename? }[]não

Resposta 202

{ accepted: true }

Tipos de mídia aceitos: imagem jpeg, png, gif, webp; documento pdf, text/plain. Codex só aceita anexos de imagem; OpenCode ainda não suporta anexos. 409 se a sessão já estiver running ou waiting_permission.

GET /v1/sessions/:sessionId/events SSE

Conexão Server-Sent Events com os eventos ao vivo da execução da sessão. Cada evento chega como event: <type> seguido de data: <AgentEvent em JSON>. A conexão fica aberta até o cliente desconectar.

Eventos possíveis

Ver union AgentEvent em Modelos de dados.

POST /v1/sessions/:sessionId/cancel

Cancela a execução em andamento. Apenas sinaliza o cancelamento; o evento agent.cancelled confirma quando de fato parar.

Resposta 200

{ cancelled: true }

409 se a sessão não estiver running.

$ ls sessions/controles

Mesmo endpoint pros três runtimes, com regras de aplicabilidade próprias em cada um.

POST /v1/sessions/:sessionId/permission-mode

Define o modo de permissão da sessão, usado como padrão nas próximas execuções.

Body

CampoTipo
modedefault | acceptEdits | bypassPermissions | plan | dontAsk | auto

Resposta 200

{ mode, applied: "live" | "pending" }

applied: "live" quando a sessão já está em execução e o Claude consegue aplicar na hora. Para o OpenCode só default (agent "build") e plan (agent "plan") são aceitos. não aplicável ao Codex

POST /v1/sessions/:sessionId/model

Define o modelo da sessão. null reseta pro padrão da CLI.

Body

CampoTipo
modelstring | null

Resposta 200

{ model, applied: "live" | "pending" }

Aplicação ao vivo ("live") só existe hoje para sessões Claude em execução.

POST /v1/sessions/:sessionId/rewind

Reverte as edições de arquivo feitas a partir de uma mensagem de usuário específica.

Body

CampoTipoObrigatório
userMessageIdstringsim
dryRunbooleannão, só suportado no Claude

Resposta 200

{ canRewind: boolean, filesChanged?: number,
  insertions?: number, deletions?: number, error?: string }

somente claude / opencode Codex não tem sistema de rewind. 409 se a sessão ainda não tem conversa pra reverter.

POST /v1/sessions/:sessionId/permissions/:permissionId/approve

Aprova um pedido de permissão de ferramenta pendente (evento permission.requested).

Resposta 200

{ approved: true }

não aplicável ao Codex 404 se o pedido já tiver sido respondido ou nunca existiu.

POST /v1/sessions/:sessionId/permissions/:permissionId/reject

Rejeita um pedido de permissão pendente.

Body

CampoTipoObrigatório
reasonstringnão (padrão: "Rejected by user")

Resposta 200

{ rejected: true }

não aplicável ao Codex O OpenCode não aceita um motivo em texto livre; reason é aceito no corpo mas não é repassado ao servidor OpenCode.

$ ls sessions/claude

Rotas exclusivas de sessões com runtime: "claude". Respondem 400 para qualquer outro runtime.

GET /v1/sessions/:sessionId/claude-tools

Lista as tools que a Claude Code CLI reportou disponíveis para o projeto, a partir do cache por projectPath.

Resposta 200

{ tools: string[] | null, updatedAt: string | null }
POST /v1/sessions/:sessionId/claude-tool-permissions

Configura a lista de tools que o Claude não pode usar nesta sessão.

Body

CampoTipoObrigatório
denystring[]sim (nomes livres, sem catálogo fechado)

Resposta 200

{ deny: string[], applied: "pending" }
POST /v1/sessions/:sessionId/claude-effort-level

Configura o esforço de raciocínio do modelo Claude para esta sessão.

Body

CampoTipo
effortlow | medium | high | xhigh

Resposta 200

{ effort, applied: "pending" }

$ ls sessions/codex

Rotas exclusivas de sessões com runtime: "codex". Respondem 400 para qualquer outro runtime.

POST /v1/sessions/:sessionId/codex-sandbox-mode

Configura o modo de sandbox/permissão de sistema de arquivos do Codex para esta sessão.

Body

CampoTipo
moderead-only | workspace-write | danger-full-access

Resposta 200

{ mode, applied: "pending" }
POST /v1/sessions/:sessionId/codex-reasoning-effort

Configura o esforço de raciocínio do modelo Codex para esta sessão.

Body

CampoTipo
effortminimal | low | medium | high | xhigh

Resposta 200

{ effort, applied: "pending" }
POST /v1/sessions/:sessionId/codex-web-search

Habilita/configura a busca na web do Codex para esta sessão.

Body (pelo menos um dos dois é obrigatório)

CampoTipo
modedisabled | cached | live
enabledboolean

Resposta 200

{ mode, enabled, applied: "pending" }
POST /v1/sessions/:sessionId/codex-additional-directories

Concede ao Codex acesso a diretórios extras fora do projectPath da sessão.

Body

CampoTipoObrigatório
directoriesstring[] (caminhos absolutos, precisam existir)sim

Resposta 200

{ directories: string[], applied: "pending" }

400 se algum caminho não for absoluto ou não existir como diretório.

$ ls sessions/opencode

O OpenCode não tem endpoints exclusivos. Ele é tratado como um branch a mais dentro dos endpoints compartilhados listados em Ciclo de vida, Execução & eventos e Controles compartilhados, com as seguintes particularidades:

Endpoint Particularidade no OpenCode
history / usageConsultados ao vivo no servidor OpenCode, sem cache local
messagesNão aceita anexos ainda (400 se attachments vier preenchido)
permission-modeSó aceita default (agent "build") ou plan (agent "plan")
rewindSem modo dryRun, o revert do snapshot é sempre aplicado de verdade
permissions/approve & rejectAceita reason no corpo por consistência, mas o servidor OpenCode só recebe "aprovado" ou "rejeitado"