EVC Mesh
Tarefas, comentários, memória compartilhada e transferências para equipes de pessoas e agentes de IA, via MCP.
Documentação
Servidor MCP EVC Mesh
Servidor Model Context Protocol (MCP) para EVC Mesh — uma plataforma de gerenciamento de tarefas para coordenar humanos e agentes de IA.
Conecta agentes de IA (Claude Code, Cursor, Cline, OpenClaw, etc.) ao EVC Mesh por meio de ferramentas MCP para gerenciamento de tarefas, memória persistente, publicação de eventos e coordenação multiagente.
Esta é a cópia em desenvolvimento ativo. evc-mesh também inclui um servidor MCP (./cmd/mcp, mesmo conjunto de ferramentas internal/mcp) que ele mesmo compila e implanta — os dois existem porque as regras de visibilidade de internal/ do Go significam que um repositório não pode importar o pacote do outro, não porque devem divergir. Novas ferramentas e correções chegam aqui primeiro.
Pré-requisitos
- Go 1.22+
- Instância EVC Mesh em execução
- Agente registrado no Mesh com uma chave de API (
agk_...)
Instalação
go install github.com/entire-vc/evc-mesh-mcp@latest
Ou compile a partir do código-fonte:
git clone https://github.com/entire-vc/evc-mesh-mcp.git
cd evc-mesh-mcp
go build -o evc-mesh-mcp .
Docker
docker run -i --rm \
-e MESH_API_URL \
-e MESH_AGENT_KEY \
ghcr.io/entire-vc/evc-mesh-mcp
-i é obrigatório — o servidor fala MCP via stdio, e o Docker só conecta a
entrada padrão quando o contêiner é executado interativamente. Adicione -e MESH_MCP_PROFILE=core
para alternar perfis (veja Perfis de Ferramentas abaixo). A imagem é
publicada para linux/amd64 e linux/arm64 a partir de Dockerfile neste repositório
a cada lançamento com tag (docs/RELEASING.md).
Perfis de Ferramentas
O servidor MCP suporta dois perfis para otimizar o uso da janela de contexto:
| Perfil | Ferramentas | Sobrecarga de contexto | Melhor para |
|---|---|---|---|
| core | 25 | ~8K tokens (4% de 200K) | Claude Code, Cursor, modelos de contexto pequeno |
| full | 63 | ~18K tokens (9% de 200K) | Usuários avançados, agentes de automação, operações administrativas |
Definido pela variável de ambiente MESH_MCP_PROFILE. Padrão: full.
Configuração
| Variável | Obrigatória | Padrão | Descrição |
|---|---|---|---|
MESH_API_URL | Sim | http://localhost:8005 | URL base da API Mesh |
MESH_AGENT_KEY | Sim (stdio) | — | Chave de API do agente (agk_...) |
MESH_MCP_PROFILE | Não | full | Perfil de ferramentas para stdio: core ou full (SSE atende ambos) |
MESH_MCP_TRANSPORT | Não | stdio | Modo de transporte: stdio ou sse |
MESH_MCP_HOST | Não | 0.0.0.0 | Host de vinculação do servidor SSE |
MESH_MCP_PORT | Não | 8081 | Porta de vinculação do servidor SSE |
MESH_MCP_AUTH_FAIL_RPM | Não | 20 | Modo SSE: orçamento por IP para tentativas de autenticação contra uma chave de agente ainda não armazenada em cache em /sse, /core/sse, /mcp, /mcp/core. Acima do orçamento → 429 sem chamar a API Mesh. 0 desativa. |
MESH_MCP_SESSION_CACHE_TTL_MIN | Não | 15 | Modo SSE: por quanto tempo uma autenticação bem-sucedida é confiável antes que a chave seja verificada novamente — limita por quanto tempo uma chave revogada continua funcionando sem reinicialização. |
MESH_MCP_AUTH_FAIL_CACHE_SEC | Não | 30 | Modo SSE: por quanto tempo uma autenticação falha (chave inválida/desconhecida) é lembrada, para que repetir a mesma chave inválida não chame a API Mesh a cada requisição. |
MESH_MCP_PUBLIC_URL | Não | — | Modo SSE: a URL pela qual a raiz MCP é acessível externamente, ex.: https://mesh.example.com/mcp. Usada para o endpoint SSE absoluto e como URL de recurso OAuth (veja OAuth). Não definida: derivada do host de cada requisição, o que só é correto quando os clientes acessam este servidor diretamente — atrás de um proxy, defina-a, ou a URL principal derivada (/core) não corresponderá à pública (/mcp/core). |
MESH_MCP_OAUTH_ISSUER | Não | origem de MESH_MCP_PUBLIC_URL | Modo SSE: o servidor de autorização OAuth nomeado nos metadados do recurso protegido — a origem pública da sua instância Mesh. Defina apenas se o servidor MCP for servido de uma origem diferente da API Mesh. |
MESH_MCP_OAUTH_CACHE_TTL_SEC | Não | 60 | Modo SSE: por quanto tempo um token de acesso OAuth verificado é confiável antes que a API Mesh seja consultada novamente. Deliberadamente muito mais curto que o TTL da chave de agente para que uma concessão revogada pare de funcionar em cerca de um minuto. |
MESH_MCP_DECIDER_USERNAME | Não | — | Nome de usuário registrado como decided_by quando record_owner_decision responde a uma tarefa bloqueada. Não definido: o proprietário do workspace. |
MESH_MCP_LEGACY_TOOL_ALIASES | Não | desativado | 1 também registra os nomes anteriores das ferramentas, para implantações cujos chamadores ainda os usam. Deixe desativado para novas instalações. |
Execução sem credenciais
No modo stdio, o servidor também inicia quando MESH_AGENT_KEY não está definido. Ele então
responde initialize e tools/list normalmente, e cada chamada de ferramenta retorna
instruções para definir MESH_API_URL e MESH_AGENT_KEY. Isso permite que clientes
e catálogos MCP inspecionem a lista de ferramentas antes de você ter uma chave. Se uma chave
estiver definida mas a autenticação falhar na inicialização (API inacessível, chave rejeitada), o
servidor continua em execução: as ferramentas são listadas, e cada chamada tenta a autenticação
novamente e retorna o motivo até que tenha sucesso.
Anotações de ferramentas
Cada ferramenta declara as dicas MCP readOnlyHint, destructiveHint,
idempotentHint e openWorldHint, para que os clientes possam distinguir ferramentas somente leitura
(get_*, list_*, recall, search_docs, …) daquelas que alteram ou
removem dados (update_*, move_task, forget, …).
Métricas do cliente
Cada initialize é registrada com o clientInfo.name e a versão do cliente,
e contabilizada na métrica Prometheus mesh_mcp_initialize_total{client,profile}
(exposta em /metrics no modo SSE; os nomes dos clientes são normalizados e limitados).
Claude Code (modo stdio)
Adicione ao .mcp.json do seu projeto:
{
"mcpServers": {
"evc-mesh": {
"command": "evc-mesh-mcp",
"env": {
"MESH_API_URL": "https://your-mesh-instance.example.com",
"MESH_AGENT_KEY": "agk_your-workspace_your-key",
"MESH_MCP_PROFILE": "core"
}
}
}
}
Cursor
Adicione às configurações MCP do Cursor (Settings → MCP Servers):
{
"evc-mesh": {
"command": "evc-mesh-mcp",
"env": {
"MESH_API_URL": "https://your-mesh-instance.example.com",
"MESH_AGENT_KEY": "agk_your-workspace_your-key",
"MESH_MCP_PROFILE": "core"
}
}
}
Modo SSE (multiagente, servidor compartilhado)
Para conectar vários agentes por meio de um endpoint MCP compartilhado:
MESH_API_URL=https://your-mesh-instance.example.com \
MESH_MCP_PORT=8081 \
evc-mesh-mcp --transport sse
O modo SSE atende dois perfis simultaneamente em caminhos diferentes:
| Caminho | Perfil | Descrição |
|---|---|---|
/sse + /message | full | Todas as 63 ferramentas (compatível com versões anteriores) |
/core/sse + /core/message | core | 25 ferramentas essenciais |
O mesmo processo também atende o transporte Streamable HTTP (sem estado, uma
chave de agente por requisição, enviada no cabeçalho Authorization: Bearer ou X-Agent-Key
— o parâmetro de consulta é recusado lá):
| Caminho | Perfil |
|---|---|
/mcp | full |
/core | core |
Autenticação por conexão via:
- Cabeçalho
Authorization: Bearer agk_... - Cabeçalho
X-Agent-Key: agk_... - Parâmetro de consulta
?agent_key=agk_...(somente conexão SSE) Authorization: Bearer mot_...— um token de acesso OAuth emitido pela sua instância Mesh (veja abaixo); somente o cabeçalho, nunca a string de consulta, e somente nos endpoints Streamable HTTP (conexões SSE precisam de uma chave de agente)
OAuth (conectores remotos)
Clientes que autenticam usuários com OAuth — diretórios de conectores remotos, MCP Inspector, editores que seguem a especificação de autorização MCP — conectam-se aos endpoints Streamable HTTP sem uma chave pré-compartilhada. Sua instância Mesh é o servidor de autorização (registro dinâmico de clientes, PKCE, consentimento do usuário); este servidor é o servidor de recursos e faz duas coisas:
-
Desafios. Uma requisição sem credencial, ou com um token de acesso OAuth que a API Mesh rejeita (expirado, revogado, nunca emitido), recebe
401eWWW-Authenticate: Bearer resource_metadata="https://mesh.example.com/.well-known/oauth-protected-resource/mcp", scope="mesh"que é onde um cliente inicia o fluxo de autorização. Uma chave de agente rejeitada continua respondendo
403. Somente um veredito da API Mesh (um4xxdiferente de408/429) torna um token inválido: se a API Mesh não puder ser alcançada ou responder com um erro que não diga nada sobre o token (5xx,429), a resposta é503comRetry-After, para que um token válido não seja descartado por causa de uma interrupção. -
Serve os metadados (RFC 9728) no caminho bem conhecido derivado da URL de cada endpoint:
Endpoint Metadados https://mesh.example.com/mcp(full)/.well-known/oauth-protected-resource/mcphttps://mesh.example.com/mcp/core(core)/.well-known/oauth-protected-resource/mcp/core{ "resource": "https://mesh.example.com/mcp", "authorization_servers": ["https://mesh.example.com"], "scopes_supported": ["mesh"], "bearer_methods_supported": ["header"] }resourceéMESH_MCP_PUBLIC_URL(barra final, consulta e fragmento removidos;/coreanexado para o perfil core), então defina-o para a URL que seus usuários colam no cliente. O servidor de autorização assume como padrão a origem dessa URL; substitua-o comMESH_MCP_OAUTH_ISSUER.
Um token OAuth atua como um agente conector no workspace que o usuário escolheu quando
concedeu acesso, com as permissões desse agente — as mesmas ferramentas, o mesmo
modelo de permissão que uma chave de agente. Tokens verificados são armazenados em cache por um minuto (MESH_MCP_OAUTH_CACHE_TTL_SEC). O
orçamento por IP (MESH_MCP_AUTH_FAIL_RPM) é gasto por tokens rejeitados, não por
verificações, então muitos usuários atrás de um mesmo endereço não são limitados pelos seus próprios
refreshes de token. O token não é vinculado a público: qualquer token de acesso válido da
sua instância Mesh é aceito, o que é a intenção enquanto o servidor de
autorização e este servidor pertencem à mesma implantação. Chaves de agente (agk_...) em Authorization ou
X-Agent-Key funcionam exatamente como antes, e o modo stdio não é afetado.
Seu proxy reverso deve enviar /.well-known/oauth-protected-resource* para este
servidor em vez do catch-all do aplicativo web: um aplicativo de página única responde a todo
caminho desconhecido com 200 text/html, o que um cliente não consegue distinguir de metadados
ausentes.
Protocolo de Contexto do Agente (ACP)
No início da sessão, siga estes 5 passos em ordem:
1. heartbeat(status="online") → register as alive
2. get_project_knowledge(project_id) → load accumulated decisions & conventions
3. get_my_rules(project_id) → understand constraints
4. get_context(project_id) → see recent activity + project knowledge
5. get_my_tasks() → check assigned work
No final da sessão:
publish_event(type="summary", memory={persist: true}) → broadcast + persist
session_report(model, tokens_in, tokens_out) → report metrics
Ferramentas MCP — Perfil Core (25)
ACP e Identidade
| Ferramenta | Descrição |
|---|---|
heartbeat | Enviar heartbeat. Chame no início da sessão com status=online. A resposta inclui mesh_version (o git-SHA da compilação do binário em execução, ou "dev" para uma compilação local sem fixação) — uma forma barata de verificar se uma correção realmente chegou ao binário instalado sem acessar o shell do host. |
get_project_knowledge | Obter TODO o conhecimento permanente (decisões, convenções). Passo 2 do ACP |
get_my_rules | Obter TODAS as regras de governança (fluxo de trabalho + atribuição). Passo 3 do ACP |
get_context | Obter atividade recente + conhecimento do projeto. Passo 4 do ACP |
get_my_tasks | Obter tarefas atribuídas. Passo 5 do ACP |
Gerenciamento de Tarefas
| Ferramenta | Descrição |
|---|---|
list_projects | Listar projetos do workspace |
list_tasks | Listar tarefas com filtros (status, prioridade, responsável, busca) |
get_task | Obter detalhes da tarefa com comentários/artefatos/dependências opcionais |
create_task | Criar uma nova tarefa |
update_task | Atualizar campos da tarefa |
move_task | Alterar o status da tarefa usando slugs |
assign_task | Atribuir/desatribuir uma tarefa |
get_task_context | Obter tudo sobre uma tarefa em uma única chamada |
add_vcs_link | Vincular uma tarefa a um pull request, commit ou branch |
Comunicação
| Ferramenta | Descrição |
|---|---|
add_comment | Adicionar comentário a uma tarefa (markdown). A resposta inclui um array delivery por menção @ informando se ela realmente alcançou o destinatário (fila de tarefas/notificação) ou foi ignorada/falhou e por quê |
publish_event | Publicar evento + dica de memória opcional para persistência |
Memória
| Ferramenta | Descrição |
|---|---|
recall | Buscar memória por palavras-chave |
remember | Salvar conhecimento (UPSERT por chave) |
forget | Excluir uma entrada de memória |
recall_with_graph | Buscar memória, expandindo resultados pelo grafo de conhecimento |
set_project_knowledge | Escrever um fato estruturado do projeto (upsert por chave) |
get_canonical_updates | Buscar decisões canônicas registradas desde um determinado momento |
record_owner_decision | Registrar uma decisão do proprietário do workspace como conhecimento canônico do projeto |
O que recall garante sobre seu resultado
limit é um limite rígido. A resposta nunca contém mais de limit itens,
e total sempre é igual ao número de itens realmente retornados. Nada é adicionado
à página depois que ela foi dimensionada — nem linhas fixadas, nem vizinhos expandidos
do grafo.
Linhas que falham em scope/tags/tags_any são descartadas, nunca retornadas sem marcação.
Isso vale independentemente de como uma linha chegou ao resultado: recuperação comum,
fixação ou expansão do grafo. Uma linha fixada está isenta de ranqueamento, não de elegibilidade —
"fixada" significa "não deixe o ranqueamento enterrar isto", não "mostre isto a um chamador que pediu
um escopo diferente".
Vizinhos do grafo são marcados e limitados. Com RECALL_GRAPH_ENABLED=true,
recall também executa uma expansão do grafo de conhecimento e incorpora hop > 0 vizinhos,
cada um carregando graph_boost: true e provenance: via:graph. Eles ocupam no máximo
limit/4 da página (pelo menos 1 quando limit >= 2, nenhum quando limit < 2) e ocupam
suas posições finais, deslocando os resultados de recuperação mais fracos em vez de serem anexados
por cima. Quando a expansão não retorna nada utilizável, a página é exatamente o resultado base —
a reserva é um teto, não uma cota. graph_boost_count informa quantas posições
foram realmente gastas.
A reserva existe porque os resultados base carregam score (RRF entre os braços de recuperação)
e os vizinhos carregam composite_score de uma travessia separada — campos diferentes
em escalas diferentes. Ordenar a união por uma chave comum não os equilibra; na
prática, todo vizinho observado fica abaixo de todo resultado base, então uma ordenação por
intercalação ingênua desativaria silenciosamente o reforço do grafo. A reserva torna essa troca explícita e
ajustável.
Predefinições nunca sobrepõem você. recall classifica a consulta e pode aplicar um
perfil (por exemplo, multi-sessão amplia a página). Um perfil apenas preenche parâmetros que você
não forneceu; um limit explícito sempre vence.
Utilidade
| Ferramenta | Descrição |
|---|---|
report_error | Relatar um erro em uma tarefa |
session_report | Relatar métricas de sessão (modelo, tokens, custo) |
Ferramentas MCP — Perfil Completo (adiciona mais 38, total 63)
Ferramentas Adicionais de Tarefas
| Ferramenta | Descrição |
|---|---|
get_project | Obter detalhes do projeto com status e campos personalizados |
create_subtask | Criar subtarefa sob um pai (status_slug opcional; usa o status padrão do projeto, não o do pai) |
add_dependency | Adicionar dependência entre tarefas |
checkout_task | Bloqueio atômico de tarefa para coordenação multi-agente |
release_task | Liberar bloqueio atômico de tarefa |
extend_checkout | Estender um bloqueio de tarefa existente para trabalhos de longa duração |
set_human_gate | Congelar uma tarefa até que uma pessoa nomeada responda a uma pergunta registrada |
clear_human_gate | Liberar uma aprovação humana |
Comentários e Artefatos
| Ferramenta | Descrição |
|---|---|
list_comments | Listar comentários de tarefas |
upload_artifact | Enviar arquivo/código/log para uma tarefa |
list_artifacts | Listar artefatos de tarefas |
get_artifact | Obter detalhes do artefato (download_path; bytes via download em duas etapas abaixo) |
Baixando um artefato
Baixar um artefato envolve dois GETs. Etapa 1: GET /api/v1/artifacts//download com o cabeçalho X-Agent-Key: -> 200 JSON {"url": ""}. Etapa 2: GET nessa url SEM cabeçalhos -> 200, os bytes do arquivo. Armadilhas: na etapa 1, apenas X-Agent-Key é aceito (X-API-Key e Authorization: Bearer retornam 401); na etapa 2, qualquer cabeçalho extra, especialmente Authorization, quebra a assinatura pré-assinada (400). O download_path do artefato é o caminho da etapa 1. Nunca busque browser_only_url com uma chave de agente: é uma página humana e responde 401 por design.
Barramento de Eventos
| Ferramenta | Descrição |
|---|---|
publish_summary | Publicar resumo de trabalho (wrapper de conveniência) |
subscribe_events | Configurar entrega de webhook para eventos |
poll_tasks | Long-poll para novas atribuições de tarefas |
Agente e Equipe
| Ferramenta | Descrição |
|---|---|
register_sub_agent | Registrar um sub-agente |
list_sub_agents | Listar sub-agentes (opcionalmente recursivo) |
get_team_directory | Obter diretório da equipe do workspace |
update_agent_profile | Atualizar função, capacidades e perfil do agente |
Governança e Configuração
| Ferramenta | Descrição |
|---|---|
get_project_rules | Obter todas as regras do projeto |
get_assignment_rules | Obter regras de atribuição |
get_workflow_rules | Obter regras de fluxo de trabalho com permissões do chamador |
import_workspace_config | Importar configuração do workspace de YAML |
export_workspace_config | Exportar configuração do workspace como YAML |
Tarefas Recorrentes
| Ferramenta | Descrição |
|---|---|
create_recurring_task | Criar agendamento de tarefa recorrente |
list_recurring_schedules | Listar agendamentos recorrentes |
get_recurring_history | Obter histórico de instâncias para um agendamento |
trigger_recurring_now | Acionar a próxima instância imediatamente |
update_recurring_schedule | Alterar ou desativar um agendamento recorrente |
delete_recurring_schedule | Excluir um agendamento recorrente (instâncias existentes permanecem) |
Documentos e Conhecimento
| Ferramenta | Descrição |
|---|---|
list_docs | Listar documentos de um projeto (apenas metadados) |
get_doc | Ler um documento (esboço por padrão, corpo sob solicitação) |
search_docs | Pesquisa de texto completo nos documentos de um projeto |
create_doc | Criar um documento |
update_doc | Editar um documento (concorrência otimista via base_version) |
comment_doc | Comentar em um documento ou em uma passagem citada |
list_doc_comments | Ler os tópicos de comentários de um documento |
get_canonical | Consultar fatos e decisões selecionados para um tópico |
Arquitetura
AI Agent (Claude Code / Cursor / Cline / OpenClaw)
↕ MCP (stdio or SSE)
EVC Mesh MCP Server (core or full profile)
↕ REST API (HTTP)
EVC Mesh API Server
↕
PostgreSQL / Redis / NATS / S3
O servidor MCP é um proxy leve — ele traduz chamadas de ferramentas MCP em solicitações de API REST. Nenhum acesso direto ao banco de dados é necessário.
Executando o servidor HTTP compartilhado
Para atender vários agentes a partir de um único processo, execute o servidor em modo SSE ao lado
da sua API Mesh (a mesma imagem funciona: docker run -e MESH_MCP_TRANSPORT=sse -e MESH_API_URL=... -p 8081:8081 ghcr.io/entire-vc/evc-mesh-mcp) e coloque-o
atrás do seu proxy reverso. Ele expõe tanto SSE (/sse, /core/sse) quanto
Streamable HTTP (/mcp, /core); cada conexão ou solicitação autentica
com sua própria chave de agente. O servidor não tem banco de dados próprio: ele chama a
API REST Mesh, então atualize-o após a API Mesh com a qual ele se comunica.
A ferramenta heartbeat retorna mesh_version, o commit a partir do qual o binário em execução foi
compilado, e --version também o imprime.
Relacionados
- evc-mesh — Plataforma principal (API + Interface Web)
- evc-mesh-openclaw-skill — Skill do OpenClaw (scripts bash)