mcp-obras
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-obrasresuma a obra Aurora e mostre os pedidos pendentes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-obras
Servidor MCP pequeno (Node.js, stdio) em que a permissão de cada agente é aplicada em código, não no prompt.
Problema
Quando um agente de IA tem ferramentas (consultar obras, criar pedido de compra, aprovar pagamento), a regra "o agente de campo não mexe na obra dos outros" costuma morar no prompt. Prompt é pedido, não trava: o modelo pode errar, ser enganado por um texto malicioso que veio num dado, ou simplesmente ignorar a instrução. Quando a ferramenta mexe em dinheiro, a trava precisa ficar onde o modelo não alcança.
Related MCP server: ProcureFlow MCP Server
Solução
Um servidor MCP com 6 ferramentas sobre dados fictícios de obras, pedidos de compra, cotações e fornecedores. Quem é o agente vem de uma variável de ambiente (AGENTE) que quem configura o cliente define, e uma única função, authorize(), decide antes de qualquer ferramenta rodar:
nega por padrão: agente desconhecido, ferramenta fora da lista, tudo é "não";
cada agente tem uma lista de ferramentas, uma lista de obras e a flag de escrita (
agentes.json);aprovar_pedidoexige o papelgestor, mesmo que alguém liste a ferramenta para outro papel por engano;criar_pedidonunca vale na hora: o pedido nasceaguardando_aprovacaoe não entra no orçamento até um gestor aprovar;toda chamada de ferramenta que chega ao handler vira uma linha em um log JSONL só de acréscimo (
permitido,negado,invalidoouerro, este último quando o arquivo de estado está ilegível); se o log não grava, a chamada é recusada;argumentos são validados com zod e as respostas têm tamanho máximo.
Esta é uma versão pequena, inspirada em um sistema real de uma construtora. O código foi escrito de novo e nenhum dado de lá foi copiado; a ideia de devolver o resultado das ferramentas como dado, e não como instrução, dentro de um envelope com rótulo aleatório, vem desse sistema.
Diagrama
flowchart LR
C["Claude Desktop ou Claude Code<br/>env AGENTE=compras"] -- "JSON-RPC por stdio" --> S["src/server.js"]
S --> A{"authorize()"}
AG[["agentes.json"]] -.-> A
A -- "negado" --> L[("logs/auditoria.jsonl")]
A -- "permitido" --> V["validação zod"]
V -- "inválido" --> L
V -- "ok" --> W["grava a decisão no log"]
W --> L
W -- "gravou" --> T["corpo da ferramenta"]
T --> E[("estado: pedidos")]Detalhes, sequência de aprovação e códigos de negação em docs/arquitetura.md.
Stack
Node.js 22+ (declarado em engines; testado só em 24.19.0) · @modelcontextprotocol/sdk 1.32.2 (stdio) · zod 4.6.7 · node:test (sem biblioteca de teste).
Agentes
Agente | Papel | Escrita | Obras | Ferramentas |
| operador | sim | Aurora, Horizonte | listar_obras, resumo_obra, listar_pedidos, buscar_fornecedor, criar_pedido |
| gestor | sim | Aurora, Horizonte | listar_obras, resumo_obra, listar_pedidos, aprovar_pedido |
| operador | sim | só Aurora | listar_obras, resumo_obra, listar_pedidos, buscar_fornecedor, criar_pedido |
| leitor | não | Aurora, Horizonte | listar_obras, resumo_obra, listar_pedidos, buscar_fornecedor |
Resultado
Números medidos em 28/10/2026 (Windows 10, Node 24.19.0, npm 11.17.0):
6 ferramentas, 4 agentes e 5 códigos de negação (tabela em
docs/arquitetura.md).npm test: 18 testes, 18 passando (entre 30 e 50 s num PC com Windows 10; é lento porque 17 dos 18 testes sobem o servidor de verdade como processo filho e falam com ele pelo cliente do SDK; em Linux ou Mac não foi medido).Para ver se os testes pegam falha de verdade, desliguei de propósito, numa cópia, a checagem de papel (1 teste falhou) e a de allowlist de obras (2 falharam).
366 linhas em
src/(wc -l src/*.js), 327 emtest/.npm auditlogo após onpm install: 0 vulnerabilidades. O SDK está em 1.32.2 porque, nas versões até 1.31.0,npm auditaponta 4 avisos (2 de severidade alta e 2 moderada; o resumo do comando conta 1 vulnerabilidade alta), todos de transporte HTTP, OAuth ou tarefas experimentais, que este projeto nem usa; não vale começar com versão que já vem com aviso.
Saída real de npm run demo:
leitura listar_obras {} -> ok
leitura criar_pedido {"obra":"obra-aurora",... -> NEGADO [FERRAMENTA_NAO_PERMITIDA]
campo resumo_obra {"obra":"obra-horizonte"} -> NEGADO [OBRA_FORA_DO_ESCOPO]
compras criar_pedido {"obra":"obra-aurora",... -> ok
compras aprovar_pedido {"pedido_id":"ped-005"} -> NEGADO [FERRAMENTA_NAO_PERMITIDA]
financeiro aprovar_pedido {"pedido_id":"ped-005"} -> ok
fantasma listar_obras {} -> NEGADO [AGENTE_DESCONHECIDO](O script imprime a mensagem de negação completa e depois o log de auditoria; aqui encurtei as colunas.)
Não publico aqui números do sistema real (quantidade de agentes ou ferramentas); este repositório mede só o que está nele.
Como rodar
Precisa de Node 22 ou mais novo (engines do package.json; só foi testado no 24.19.0).
# depois de clonar o repositório
cd mcp-obras
npm install
npm test # 18 testes (30 a 50 s num PC com Windows 10: 17 deles sobem o servidor)
npm run demo # passeio de 7 chamadas + o log de auditoriaPara usar no Claude Desktop ou no Claude Code (um servidor por agente, cada um com seu AGENTE), veja docs/conectar.md. O servidor não lê .env; as variáveis vão no bloco env da configuração do cliente:
Variável | Para quê | Padrão |
| quem está chamando; precisa existir em | (vazio: tudo negado) |
| caminho do arquivo de agentes |
|
| onde guardar os pedidos criados |
|
| onde gravar o log |
|
Os padrões valem a partir da raiz do projeto, de qualquer pasta de onde o cliente suba o servidor. Se você definir uma dessas três variáveis, use caminho absoluto: um caminho relativo passa a valer a partir da pasta em que o cliente rodou o comando.
Estrutura de pastas
mcp-obras/
├── README.md
├── LICENSE # MIT
├── .gitignore
├── package.json # e package-lock.json (versões fixas)
├── agentes.json # quem pode o quê (ferramentas, obras, escrita, papel)
├── data/dados.json # dados fictícios (obras, fornecedores, pedidos, cotações)
├── src/
│ ├── server.js # liga tudo: authorize -> validação -> auditoria -> ferramenta
│ ├── authorize.js # a função que decide, e a validação do agentes.json
│ ├── ferramentas.js # as 6 ferramentas (schema zod + regra de negócio)
│ ├── auditoria.js # log JSONL de acréscimo
│ └── estado.js # leitura e gravação do "banco" (um JSON)
├── test/mcp-obras.test.js
├── scripts/demo.js
└── docs/
├── arquitetura.md # diagramas, decisões, o que falta
└── conectar.md # Claude Desktop e Claude CodeDecisões de projeto
Nega por padrão. A função
authorize()só devolve "pode" se todas as regras passarem. Ferramenta que não existe e ferramenta não liberada recebem a mesma resposta (FERRAMENTA_NAO_PERMITIDA); agente desconhecido recebeAGENTE_DESCONHECIDO. Nos três casos o resultado é negar.Trava em código, não no prompt. O prompt (a
descriptiondas ferramentas) ajuda o modelo a se comportar, mas quem impede é oauthorize(). O teste "mesmo listada por engano, o papel operador continua negado" existe para provar isso.stdio. É o transporte mais simples, sem porta aberta na rede, e o Claude Desktop e o Claude Code falam com ele. O custo: a identidade é só uma variável de ambiente, sem login.
Aprovação em duas camadas. O pedido só vale depois de
aprovar_pedido, que é de outro agente com papelgestor; além disso, os clientes MCP normalmente pedem confirmação da pessoa antes de rodar uma ferramenta (comportamento do cliente, que não testei aqui; o servidor só marca as de escrita comreadOnlyHint: false). O servidor não consegue provar que uma pessoa clicou; veja Limitações.Serverde baixo nível do SDK, nãoMcpServer. Assim nenhuma validação de argumentos nem corpo de ferramenta roda antes doauthorize()(só a leitura do estado, ver docs/arquitetura.md), e até chamada com argumentos inválidos cai no log (requisição semnameem texto, ou comargumentsque não é objeto, o SDK recusa antes do handler, e ela fica fora do log). O JSDoc do SDK 1.32.2 marcaServercomo@deprecated(recomendaMcpServer;Serversó para uso avançado), então o editor pode mostrá-lo riscado. É uma escolha consciente: oMcpServervalida o schema antes de chamar o callback, e oauthorize()precisa vir antes.
Mais detalhes e o raciocínio em docs/arquitetura.md.
Limitações / o que ficou de fora
A identidade não é autenticada. Quem edita a configuração do cliente escolhe o
AGENTE. Serve para uma máquina de confiança, não para vários usuários.A aprovação humana não é verificável pelo servidor. Se o
financeirofor um agente de IA que chamaaprovar_pedidosozinho, o servidor aprova. Quem garante que há uma pessoa no meio é o pedido de confirmação do cliente MCP, ou, melhor, não exporaprovar_pedidoa um agente autônomo."Banco" é um arquivo JSON, sem trava entre processos: dois agentes gravando ao mesmo tempo, vale o último.
O log registra a decisão, não o resultado da execução, e é de acréscimo por construção do código, não por garantia do sistema de arquivos.
Nem toda requisição chega ao log. Um
tools/callsemnameem texto, ou comargumentsque não é objeto, é recusado pelo SDK (erro JSON-RPC -32603) antes do handler: não passa peloauthorize(), nenhuma ferramenta roda e não sai linha emlogs/auditoria.jsonl. Conferido mandando essas requisições na mão, como em docs/conectar.md.Sem OAuth, sem limite de taxa, sem banco de dados de verdade: o que cada um seria numa versão de produção está em "O que falta" de docs/arquitetura.md.
Não foi testado dentro do Claude Desktop nem do Claude Code; o
npm testusa o mesmo comando e as mesmas variáveis de ambiente, pelo cliente do SDK.
Como foi feito
Rodei npm test e npm run demo para conferir o resultado.
Licença
MIT. Veja LICENSE. Rafael M. da Silva Santos.
Maintenance
Related MCP Connectors
Secure agent purchasing with human-approved virtual cards, receipts, and audit trails.
Structured B2B supply search, quoting, sandbox orders and fulfillment status for agents.
Agent-native supply network for components, fabrication, industrial RFQs, offers, and fulfillment.
Hosted approval queue for agents: tiered human approvals, park-don't-block queue, budgets, digests.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables customer support operations such as order lookup, store credit, refunds, and audit log review through an agent using safe, typed MCP tools.-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to query and manage ERP procurement data, including suppliers, parts, inventory, and purchase orders, with human approval for write operations.-
- FlicenseNot gradedqualityBmaintenanceEnables AI agents to browse product catalogs and make purchases through a policy engine that enforces spending limits, requires human approval for certain amounts, and logs all actions to an audit trail.-
- AlicenseNot gradedqualityBmaintenanceEnables an AI agent to browse inventory and make purchases under strict human approval, with hard spending caps and auditable on-chain payment records.MIT