mcp-local-erp

mcp-local-erp

Enables local file reading and writing for your project via Claude Desktop, with tools to read, write, and list files in a specified root path.

Category
访问服务器

README

mcp-local-erp

Servidor MCP local de leitura e escrita de arquivos de um projeto, para uso com o Claude Desktop. Cada projeto (ex: erp-distribuidora, erp-consultorio, erp-confeccao...) recebe sua própria cópia desta pasta, com um config.yaml próprio. Isso permite que vários projetos rodem em paralelo, cada um aparecendo com um nome distinto dentro do Claude Desktop.

Toda escrita de arquivo passa por um harness de controle de mudanças: nenhuma alteração acontece sem um plano prévio (feature + arquivos envolvidos) aprovado explicitamente. Veja a seção Harness de controle de mudanças abaixo.

Estrutura

mcp-local-erp/
├── config.yaml         # nome do projeto e raiz de arquivos que o servidor enxerga
├── server.py            # define as ferramentas (read_file, write_file, list_dir, harness)
├── change_control.py    # implementação do harness: planos, aprovação, log de auditoria
├── start.py             # registra este servidor no Claude Desktop
├── pyproject.toml       # dependências (fastmcp, pyyaml, psutil)
├── mcp_audit.jsonl       # log append-only de todo evento do harness (versionado no Git)
├── mcp_state.json        # planos pendentes/aprovados (transitório — não versionado)
└── README.md

mcp_state.json e mcp_audit.jsonl ficam sempre dentro desta pasta (mcp-local-erp/), nunca dentro do projeto que o servidor gerencia — mesmo quando root_path aponta para fora dela. Veja o porquê em Arquivos gerados pelo harness.


Instalação (primeira vez na máquina)

1. Python

Verifique se já está instalado:

python --version

Se não retornar nada, instale a versão 3.11 ou superior:

Sistema Comando
Windows winget install Python.Python.3.12
macOS brew install python@3.12
Linux sudo apt install python3 python3-venv

2. uv (gerenciador de dependências)

Sistema Comando
Windows (PowerShell) powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh

Feche e reabra o terminal depois de instalar, para o uv entrar no PATH.

3. Dependências do projeto

Dentro da pasta mcp-local-erp:

cd C:\project-claude\mcp-local
uv sync

Isso cria um .venv local e instala tudo conforme o pyproject.toml.


Configuração

Edite o config.yaml antes de registrar:

project_name: mcp-local-erp    # nome único — é o que aparece no Claude Desktop
environment: dev                # dev | prod — identifica o ambiente na auditoria
root_path: ../                  # pasta raiz do projeto que este servidor pode ler/escrever
allowed_extensions:              # extensões que write_file tem permissão de gravar
  - .py
  - .tsx
  - .ts
  - .json
  - .yaml
  - .md
blocked_dirs:                     # diretórios nunca acessíveis, nem para leitura
  - node_modules
  - .git
  - .venv

mcp-local-erp é o nome padrão de fábrica do pacote. Ao colocar esta pasta dentro de um projeto específico (erp-distribuidora, erp-consultorio, erp-confeccao...), troque project_name para um nome único por projeto — é o que diferencia os servidores quando mais de um estiver rodando ao mesmo tempo no Claude Desktop.

root_path define o escopo de read_file / list_dir / write_file — ou seja, o projeto que este servidor enxerga e pode alterar. Isso é propositalmente diferente de onde o harness guarda seu próprio estado (ver seção seguinte).


Registro no Claude Desktop

Passo 1 — Feche o Claude Desktop por completo

Isso é obrigatório, não opcional. O Claude Desktop mantém o claude_desktop_config.json em memória enquanto está aberto; se ele continuar rodando durante o registro, pode sobrescrever o arquivo com o estado antigo ao ser fechado depois — apagando a entrada nova sem aviso.

No Windows:

  1. Clique com o botão direito no ícone do Claude na bandeja do sistema → Sair / Quit.
  2. Confirme que não sobrou processo algum:
    Get-Process Claude -ErrorAction SilentlyContinue
    
    Se não retornar nada, está encerrado.

Passo 2 — Rode o script de registro

uv run start.py

O script:

  • detecta automaticamente onde este Windows guarda o claude_desktop_config.json — cobre tanto instalação via Microsoft Store (MSIX) (%LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\) quanto a instalação tradicional (%APPDATA%\Claude\). Isso importa: editar o arquivo errado é a causa mais comum de "registrei mas não apareceu";
  • limpa processos órfãos de server.py deste projeto — instâncias presas de sessões anteriores cujo processo pai (o Claude Desktop) já fechou. Só encerra processo com pai morto; nunca mexe em processo com o Claude Desktop ainda rodando;
  • lê o project_name do config.yaml e, se a entrada ainda não existir, adiciona automaticamente (com backup do arquivo original antes de qualquer alteração); se já existir, apenas avisa e não altera nada;
  • em qualquer um dos dois casos, relê o arquivo no final e mostra a lista de servidores registrados, como conferência.

Se mcp-local-erp (ou o nome que você definiu) não aparecer nessa lista final, não abra o Claude Desktop ainda — confirme antes se o processo estava mesmo encerrado no Passo 1.

Passo 3 — Abra o Claude Desktop

O novo servidor MCP aparece na lista de ferramentas conectadas com o nome definido em project_name.


Harness de controle de mudanças

Nenhuma escrita acontece "direto". Toda alteração de arquivo passa obrigatoriamente por um plano prévio, revisado por você, antes de o conteúdo ser gravado. Isso dá rastreabilidade clara do propósito de cada mudança e impede que várias alterações aconteçam sem revisão.

O processo, passo a passo

 ┌──────────────────────────┐
 │ 1. propose_change         │  Claude declara: feature, descrição do
 │    (Claude chama)         │  propósito, e a lista exata de paths que
 │                           │  serão criados/alterados.
 └────────────┬──────────────┘
              │  grava plano com status "pending"
              │  em mcp_state.json (dentro de mcp-local-erp/)
              ▼
 ┌──────────────────────────┐
 │ 2. revisão humana          │  Você lê o plano exibido na conversa:
 │    (você decide)          │  feature, arquivos, propósito.
 └────────────┬──────────────┘
              │
      ┌───────┴────────┐
      │                │
   aprovado          rejeitado
      │                │
      ▼                ▼
 ┌───────────────┐  ┌───────────────────┐
 │ 3. approve_    │  │ reject_change      │
 │    change      │  │ (Claude chama)      │
 │ (Claude chama) │  │ plano vira          │
 │ plano vira     │  │ "rejected" — fim    │
 │ "approved"     │  └───────────────────┘
 └───────┬────────┘
         ▼
 ┌────────────────────────────────────┐
 │ 4. write_file(rel_path, content,    │
 │    plan_id, feature, description)   │
 │                                     │
 │  Antes de gravar, verifica:         │
 │    - rel_path é um arquivo interno  │
 │      reservado do harness? recusa   │
 │    - plan_id existe?                │
 │    - status == "approved"?          │
 │    - rel_path está na lista de      │
 │      files do plano?                │
 │                                     │
 │  Se qualquer checagem falhar        │
 │  → recusa com erro, nada é gravado. │
 │                                     │
 │  Se tudo OK:                        │
 │    - injeta comentário de           │
 │      rastreabilidade no topo do     │
 │      arquivo (feature, plano, data) │
 │    - grava o arquivo (dentro de     │
 │      ROOT, o projeto gerenciado)    │
 │    - registra o evento em           │
 │      mcp_audit.jsonl (dentro de     │
 │      mcp-local-erp/)                │
 └────────────────────────────────────┘

Ferramentas do harness

Ferramenta MCP Quando usar Efeito
propose_change(feature, description, files) Antes de qualquer alteração Cria plano pending, devolve plan_id
approve_change(plan_id) Depois que você aprovar na conversa Plano vira approved
reject_change(plan_id) Se você recusar o plano proposto Plano vira rejected
list_pending_changes(status) Para conferir o que está pendente/aprovado/rejeitado Lista os planos filtrados por status
write_file(rel_path, content, plan_id, feature, description) Só depois do plano aprovado Grava o arquivo com comentário de rastreabilidade; recusa se o plano não cobrir rel_path
read_file(rel_path) A qualquer momento Leitura livre, sem exigir plano (não altera nada)
list_dir(rel_path) A qualquer momento Leitura livre da árvore de arquivos

Arquivos gerados pelo harness

  • mcp_state.json — os planos e seus status (pending / approved / rejected) e quais escritas cada plano já cobriu. Não é versionado (está no .gitignore): é estado de trabalho, não histórico.
  • mcp_audit.jsonl — log append-only, uma linha JSON por evento (propose, approve, reject, write), com timestamp. Este arquivo é versionado — é o seu histórico auditável de quem pediu e aprovou o quê, mesmo depois de o plano ter saído do mcp_state.json.

Os dois arquivos vivem sempre em HARNESS_ROOT (Path(__file__).parent em server.py, ou seja, a própria pasta mcp-local-erp/) — não em ROOT (root_path do config.yaml, que é o projeto gerenciado, ex: erp-distribuidora/). Essa separação é intencional: ROOT muda de projeto para projeto e pode até apontar para fora desta pasta, mas o bookkeeping do harness precisa ficar contido e previsível, sempre no mesmo lugar, independente de onde root_path aponte. Por isso também write_file recusa qualquer tentativa de gravar em um arquivo chamado mcp_state.json ou mcp_audit.jsonl — mesmo com plano aprovado — para que o próprio fluxo de aprovação não possa corromper seu próprio estado.

Exemplo de recusa (proteção funcionando)

Se o Claude tentar escrever em um arquivo fora do escopo aprovado:

ValueError: Arquivo 'app/models/pagamento.py' não está no escopo
declarado do plano 'a1b2c3d4' (['server.py', 'change_control.py']).
Proponha um novo plano cobrindo este arquivo.

Isso é o comportamento esperado: qualquer expansão de escopo exige um novo plano — e uma nova aprovação sua.


Reaproveitando em projetos futuros

Esta pasta é autocontida — nada nela depende de algo externo. Para usar em um novo projeto:

  1. Copie a pasta mcp-local-erp inteira para dentro do repositório.
  2. Ajuste project_name e root_path no config.yaml.
  3. Repita os passos de Registro no Claude Desktop acima.

Não é um pacote instalável (não vai pro PyPI, não é importado por outro código) — é um servidor autônomo, então não precisa de nenhum ajuste de packaging além do que já está pronto aqui.


Troubleshooting

Erro Failed to build mcp-local mencionando hatchling ou only-include: o pyproject.toml já vem corrigido com [tool.uv] package = false, que avisa o uv para instalar dependências e rodar os scripts sem tentar empacotar nada. Se aparecer de novo, confirme que seu pyproject.toml tem esse bloco e não tem uma seção [build-system].

A entrada some do claude_desktop_config.json depois de reiniciar o Claude Desktop: o app estava aberto durante o registro. Siga o Passo 1 da seção de Registro à risca antes de rodar start.py de novo.

A entrada nunca aparece na tela "Servidores MCP locais", mesmo o terminal confirmando o registro: o script pode ter escrito no arquivo tradicional (%APPDATA%\Claude\) enquanto sua instalação do Claude Desktop é via Microsoft Store (MSIX), que lê de %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\. A versão atual do start.py já detecta isso automaticamente e imprime qual caminho encontrou — confira a linha "Config detectado" no início da saída para confirmar qual arquivo está sendo usado.

spawn uv ENOENT nos logs do Claude Desktop: o app não achou o executável do uv no seu próprio PATH (que pode ser mais restrito que o do terminal). O start.py já resolve o caminho absoluto do uv automaticamente; se o aviso aparecer na tela, rode where uv e confirme o caminho manualmente no claude_desktop_config.json.

write_file recusa com "Plano não encontrado" ou "não aprovado": o harness está funcionando como esperado — chame propose_change (e, depois da sua aprovação, approve_change) antes de tentar escrever.

write_file recusa dizendo que o arquivo é "interno do harness": também esperado — mcp_state.json e mcp_audit.jsonl nunca podem ser alvo de write_file, mesmo com plano aprovado; são gerenciados só pelas funções internas de change_control.py.


Observação importante

Rodar python server.py diretamente no terminal não faz nada visível — o servidor fica esperando mensagens no stdin. Quem inicia o processo de fato é o Claude Desktop, usando o comando registrado pelo start.py. Use o start.py apenas para garantir o registro; o "start" do servidor em si acontece automaticamente quando o Claude Desktop abre.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选