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

Install via Spark

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:

PerfilFerramentasSobrecarga de contextoMelhor para
core25~8K tokens (4% de 200K)Claude Code, Cursor, modelos de contexto pequeno
full63~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ávelObrigatóriaPadrãoDescrição
MESH_API_URLSimhttp://localhost:8005URL base da API Mesh
MESH_AGENT_KEYSim (stdio)—Chave de API do agente (agk_...)
MESH_MCP_PROFILENãofullPerfil de ferramentas para stdio: core ou full (SSE atende ambos)
MESH_MCP_TRANSPORTNãostdioModo de transporte: stdio ou sse
MESH_MCP_HOSTNão0.0.0.0Host de vinculação do servidor SSE
MESH_MCP_PORTNão8081Porta de vinculação do servidor SSE
MESH_MCP_AUTH_FAIL_RPMNão20Modo 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_MINNão15Modo 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_SECNão30Modo 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_URLNã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_ISSUERNãoorigem de MESH_MCP_PUBLIC_URLModo 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_SECNão60Modo 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_USERNAMENã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_ALIASESNãodesativado1 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:

CaminhoPerfilDescrição
/sse + /messagefullTodas as 63 ferramentas (compatível com versões anteriores)
/core/sse + /core/messagecore25 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á):

CaminhoPerfil
/mcpfull
/corecore

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 401 e

    WWW-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 (um 4xx diferente de 408/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 é 503 com Retry-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:

    EndpointMetadados
    https://mesh.example.com/mcp (full)/.well-known/oauth-protected-resource/mcp
    https://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; /core anexado 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 com MESH_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

FerramentaDescrição
heartbeatEnviar 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_knowledgeObter TODO o conhecimento permanente (decisões, convenções). Passo 2 do ACP
get_my_rulesObter TODAS as regras de governança (fluxo de trabalho + atribuição). Passo 3 do ACP
get_contextObter atividade recente + conhecimento do projeto. Passo 4 do ACP
get_my_tasksObter tarefas atribuídas. Passo 5 do ACP

Gerenciamento de Tarefas

FerramentaDescrição
list_projectsListar projetos do workspace
list_tasksListar tarefas com filtros (status, prioridade, responsável, busca)
get_taskObter detalhes da tarefa com comentários/artefatos/dependências opcionais
create_taskCriar uma nova tarefa
update_taskAtualizar campos da tarefa
move_taskAlterar o status da tarefa usando slugs
assign_taskAtribuir/desatribuir uma tarefa
get_task_contextObter tudo sobre uma tarefa em uma única chamada
add_vcs_linkVincular uma tarefa a um pull request, commit ou branch

Comunicação

FerramentaDescrição
add_commentAdicionar 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_eventPublicar evento + dica de memória opcional para persistência

Memória

FerramentaDescrição
recallBuscar memória por palavras-chave
rememberSalvar conhecimento (UPSERT por chave)
forgetExcluir uma entrada de memória
recall_with_graphBuscar memória, expandindo resultados pelo grafo de conhecimento
set_project_knowledgeEscrever um fato estruturado do projeto (upsert por chave)
get_canonical_updatesBuscar decisões canônicas registradas desde um determinado momento
record_owner_decisionRegistrar 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

FerramentaDescrição
report_errorRelatar um erro em uma tarefa
session_reportRelatar métricas de sessão (modelo, tokens, custo)

Ferramentas MCP — Perfil Completo (adiciona mais 38, total 63)

Ferramentas Adicionais de Tarefas

FerramentaDescrição
get_projectObter detalhes do projeto com status e campos personalizados
create_subtaskCriar subtarefa sob um pai (status_slug opcional; usa o status padrão do projeto, não o do pai)
add_dependencyAdicionar dependência entre tarefas
checkout_taskBloqueio atômico de tarefa para coordenação multi-agente
release_taskLiberar bloqueio atômico de tarefa
extend_checkoutEstender um bloqueio de tarefa existente para trabalhos de longa duração
set_human_gateCongelar uma tarefa até que uma pessoa nomeada responda a uma pergunta registrada
clear_human_gateLiberar uma aprovação humana

Comentários e Artefatos

FerramentaDescrição
list_commentsListar comentários de tarefas
upload_artifactEnviar arquivo/código/log para uma tarefa
list_artifactsListar artefatos de tarefas
get_artifactObter 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

FerramentaDescrição
publish_summaryPublicar resumo de trabalho (wrapper de conveniência)
subscribe_eventsConfigurar entrega de webhook para eventos
poll_tasksLong-poll para novas atribuições de tarefas

Agente e Equipe

FerramentaDescrição
register_sub_agentRegistrar um sub-agente
list_sub_agentsListar sub-agentes (opcionalmente recursivo)
get_team_directoryObter diretório da equipe do workspace
update_agent_profileAtualizar função, capacidades e perfil do agente

Governança e Configuração

FerramentaDescrição
get_project_rulesObter todas as regras do projeto
get_assignment_rulesObter regras de atribuição
get_workflow_rulesObter regras de fluxo de trabalho com permissões do chamador
import_workspace_configImportar configuração do workspace de YAML
export_workspace_configExportar configuração do workspace como YAML

Tarefas Recorrentes

FerramentaDescrição
create_recurring_taskCriar agendamento de tarefa recorrente
list_recurring_schedulesListar agendamentos recorrentes
get_recurring_historyObter histórico de instâncias para um agendamento
trigger_recurring_nowAcionar a próxima instância imediatamente
update_recurring_scheduleAlterar ou desativar um agendamento recorrente
delete_recurring_scheduleExcluir um agendamento recorrente (instâncias existentes permanecem)

Documentos e Conhecimento

FerramentaDescrição
list_docsListar documentos de um projeto (apenas metadados)
get_docLer um documento (esboço por padrão, corpo sob solicitação)
search_docsPesquisa de texto completo nos documentos de um projeto
create_docCriar um documento
update_docEditar um documento (concorrência otimista via base_version)
comment_docComentar em um documento ou em uma passagem citada
list_doc_commentsLer os tópicos de comentários de um documento
get_canonicalConsultar 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

Licença

MIT