Pohoda MCP
Servidor MCP para o software de contabilidade Pohoda (tcheco) - ler e criar faturas, pedidos, inventário, contatos via API XML do mServer.
Documentação
Servidor Pohoda MCP
Servidor MCP para o software contábil Pohoda da Stormware. Ele se comunica com o Pohoda por meio da API XML do mServer.
Conecte seu assistente de IA diretamente à contabilidade. Pergunte sobre faturas, navegue pelo catálogo de endereços, verifique estoques, crie novos documentos ou imprima uma fatura em PDF. Basta escrever o que você precisa, e o servidor MCP cuidará da comunicação com o Pohoda.
Requisitos
- PHP 8.1+
- ext-curl, ext-dom, ext-simplexml
- Pohoda com mServer ativo (esquema versão 2)
Configuração do mServer no Pohoda
Antes de usar o servidor MCP, é necessário ativar e configurar o mServer no Pohoda.
1. Abrindo o gerenciamento do mServer
No programa Pohoda, abra a agenda Unidades contábeis e, no menu, selecione Banco de dados > POHODA mServer.
2. Gerenciamento de configurações
Uma caixa de diálogo será aberta com a lista de configurações do mServer. Para cada configuração, são exibidos nome, porta, status de execução, host e PID.
3. Criando uma nova instância
Clique em Novo e, na aba Básico, defina:
- Nome do mServer
- Unidade contábil com a qual o mServer se comunicará
- Porta para comunicação (padrão 444)
Na aba HTTPS, você pode ativar a comunicação segura:
Na aba Monitoramento, você pode ativar o registro de comunicação:
4. Inicialização
Selecione a configuração e clique em Iniciar (ou clique duas vezes no registro). O mServer começará a escutar na porta configurada.
Alternativamente, o mServer pode ser controlado pela linha de comando usando a opção /HTTP sobre pohoda.exe. Como último parâmetro, informe o nome da configuração (entre aspas, se contiver espaços):
& "C:\Program Files (x86)\STORMWARE\POHODA\Pohoda.exe" /HTTP start "eShop-1"
& "C:\Program Files (x86)\STORMWARE\POHODA\Pohoda.exe" /HTTP stop "eShop-1"
& "C:\Program Files (x86)\STORMWARE\POHODA\Pohoda.exe" /HTTP restart "eShop-1"
& "C:\Program Files (x86)\STORMWARE\POHODA\Pohoda.exe" /HTTP list
Outros comandos: stop /f (encerramento forçado), list:xml (lista de configurações em XML). Para inicialização automática na inicialização do sistema, a Stormware recomenda o Agendador de Tarefas do Windows (não o serviço do Windows).
Consulte a documentação da Stormware para obter detalhes.
Instalação do servidor MCP
git clone https://github.com/dg/pohoda-mcp.git
cd pohoda-mcp
composer install
Configuração
O servidor é configurado por meio de variáveis de ambiente:
| Variável | Descrição | Padrão |
|---|---|---|
POHODA_URL | URL do mServer | http://localhost:444 |
POHODA_ICO | CNPJ da unidade contábil | |
POHODA_USERNAME | Nome de usuário para o mServer | |
POHODA_PASSWORD | Senha | |
POHODA_EXE_PATH | Caminho para Pohoda.exe para inicialização automática do mServer (opcional) | |
POHODA_CONFIG_NAME | Nome da configuração do mServer para inicialização automática (opcional) |
Se POHODA_EXE_PATH e POHODA_CONFIG_NAME estiverem definidos, o servidor verificará antes da primeira chamada de ferramenta se o mServer está em execução — se não estiver, ele o iniciará automaticamente via pohoda.exe /HTTP start. Ao encerrar o servidor MCP, ele também o interromperá, mas somente se ele mesmo o tiver iniciado (se o mServer já estava em execução, ele permanecerá em execução). Somente Windows (o mServer faz parte do Pohoda).
Uso em agentes (ex.: Claude Code)
A configuração pronta está no arquivo .mcp.json.example. Copie-o e adicione o caminho absoluto para server.php e as credenciais de acesso. As duas últimas variáveis são opcionais e servem para iniciar automaticamente o mServer na primeira chamada de ferramenta (veja acima). Onde o arquivo deve ser colocado depende da ferramenta:
| Ferramenta | Localização |
|---|---|
| Claude Code | .mcp.json na raiz do projeto |
| Claude Desktop | insira o conteúdo em %APPDATA%\Claude\claude_desktop_config.json |
| Cursor | .cursor/mcp.json no projeto, ou ~/.cursor/mcp.json para todos os projetos |
| Gemini CLI | .gemini/settings.json no projeto, ou ~/.gemini/settings.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
O VS Code (Copilot) usa a chave servers e pode solicitar a senha na inicialização, portanto ela não precisa estar no arquivo. Em .vscode/mcp.json:
{
"inputs": [
{"type": "promptString", "id": "pohoda-password", "description": "Heslo k mServeru", "password": true}
],
"servers": {
"pohoda": {
"type": "stdio",
"command": "php",
"args": ["/cesta/k/pohoda-mcp/server.php"],
"env": {
"POHODA_URL": "http://localhost:444",
"POHODA_ICO": "12345678",
"POHODA_USERNAME": "Admin",
"POHODA_PASSWORD": "${input:pohoda-password}"
}
}
}
}
O OpenAI Codex CLI tem configuração em TOML, em ~/.codex/config.toml:
[mcp_servers.pohoda]
command = "php"
args = ["/cesta/k/pohoda-mcp/server.php"]
env = { POHODA_URL = "http://localhost:444", POHODA_ICO = "12345678", POHODA_USERNAME = "Admin", POHODA_PASSWORD = "" }
Nunca faça commit do arquivo com a senha. Se você salvar a configuração no projeto, adicione-a ao .gitignore.
Ferramentas disponíveis
status
Verifica se o mServer está em execução e respondendo. A chamada básica retorna apenas um texto curto de GET /status (o Pohoda responde com uma string simples, não XML). Com o parâmetro companyDetail=true, além da consulta autenticada, retorna o nome da unidade contábil, o nome do banco de dados e o ano contábil atual.
| Parâmetro | Descrição |
|---|---|
companyDetail | true / false — retornar também os dados da unidade contábil ativa (padrão false) |
list_documents, list_stock, list_contacts
Três ferramentas de leitura divididas por tipo de registro. Agendas de nicho/tabelas (centre, activity, store, bankAccount, cashRegister, numericalSeries) não estão disponíveis por meio de uma ferramenta dedicada; use raw_xml.
list_documents
Documentos. Parâmetro agenda — um dos seguintes:
| Agenda | Descrição | Agenda | Descrição | |
|---|---|---|---|---|
invoice | faturas* | prijemka | recibos de entrada | |
order | pedidos | vydejka | recibos de saída | |
voucher | documentos de caixa | prodejka | vendas | |
bank | banco | prevodka | transferências | |
contract | contratos | vyroba | produção | |
intDoc | documentos internos | accountancy | diário contábil | |
offer | propostas | |||
enquiry | cotações |
* A agenda invoice exige o parâmetro invoiceType: issuedInvoice ou receivedInvoice.
Filtros: id, dateFrom, dateTill, company, ico, number (correspondência exata do valor inteiro, não substring), lastChanges (registros alterados desde YYYY-MM-DDThh:mm:ss), limit (padrão 100, corte no cliente).
list_stock
Estoques. Filtros: id, code, name, ean, storage (caminho na estrutura do armazém, ex.: "ZBOZI/Elektro"), store (abreviação do armazém), internet (true/false), lastChanges, limit.
list_contacts
Catálogo de endereços. Filtros: id, company, ico, lastChanges, limit.
create_invoice
Criação de fatura emitida ou recebida. Suporta:
- endereço do parceiro diretamente ou vínculo com o catálogo de endereços (
partnerId) - símbolo variável, data de vencimento, data de incidência tributável
- pré-contabilização, forma de pagamento, conta bancária
- centro de custo, atividade, contrato
- moeda estrangeira com taxa de câmbio
- itens com vínculo à ficha de estoque (
stockCode)
create_address
Criação de registro no catálogo de endereços (empresa/contato).
create_stock
Criação de ficha de estoque. Além dos dados básicos (código, nome, preço), suporta:
- EAN, PLU para PDVs
- sinalizadores para venda e e-commerce
- descrição, complemento do nome, nome curto
- estoque mínimo e máximo, peso
- fornecedor, garantia
create_order
Criação de pedido recebido ou emitido com itens.
Impressão ou exportação em PDF de qualquer registro. Ele pode:
- imprimir na impressora (padrão ou específica)
- exportar para arquivo PDF no servidor (
pdfPathé obrigatório para o caminho do PDF) - retornar o PDF como Base64 diretamente na resposta (
pdfBase64=true, exigepdfPath)
A agenda é informada em tcheco: vydane_faktury, prijate_faktury, zasoby, adresar, pokladna, banka, interni_doklady, zakazky, vydejky, prijemky, prodejky, vydane_objednavky, prijate_objednavky, vydane_nabidky, prijate_nabidky, etc.
O ID do relatório de impressão (reportId) varia conforme a instalação e personalizações. No Pohoda, você pode descobri-lo no Editor de relatórios de impressão (menu Arquivo → Relatórios de impressão), onde você vê a coluna ID para cada relatório, ou clicando com o botão direito no relatório na caixa de diálogo de impressão → Propriedades. Os relatórios padrão fornecidos têm IDs na faixa de centenas a milhares (normalmente 200–3000+).
raw_xml
Envio de XML arbitrário. Cobre casos em que as outras ferramentas não são suficientes. O XML é inserido diretamente no envelope <dat:dataPackItem>, portanto deve conter suas próprias declarações de namespace.
Recursos de referência (recursos MCP)
As tabelas de valores permitidos são expostas como recursos MCP, para que o cliente possa obtê-las sem uma chamada de ferramenta:
| URI | Conteúdo |
|---|---|
pohoda://enums/agendas | lista de agendas dividida por qual ferramenta de lista as cobre |
pohoda://enums/vat-rates | valores permitidos de vatRate para itens (none, low, high) |
pohoda://enums/payment-types | valores de paymentType de faturas (draft, cash, card, compensation) |
pohoda://enums/print-agendas | nomes tchecos de agendas aceitos por print |
Uso a partir do código PHP (sem MCP)
A biblioteca também pode ser usada diretamente como um cliente PHP para o mServer, independentemente do MCP. É útil para scripts próprios, cron jobs ou integração em um aplicativo existente.
use DG\Pohoda\PohodaClient;
$client = new PohodaClient(
url: 'http://localhost:444',
ico: '12345678',
username: 'Admin',
password: '',
);
// Najdi fakturu podle čísla dokladu
$list = $client->listRecords('invoice', ['number' => '26010192'], 'issuedInvoice');
$faId = (int) $list->items[0]->data['invoice'][0]['invoiceHeader']['id'];
// Vytiskni ji do PDF
$client->printRecord([
'agenda' => 'vydane_faktury',
'recordId' => $faId,
'reportId' => 3000,
'pdfPath' => 'C:\\tmp\\faktura.pdf',
]);
Métodos públicos de PohodaClient: getStatus(), listRecords(), createInvoice(), createAddress(), createStock(), createOrder(), printRecord(), sendRawXml().
Iniciando e parando o mServer
Se o script não puder presumir que o mServer já está em execução, a classe MServerController é útil. É um wrapper fino sobre pohoda.exe /HTTP start|stop que inicia o Pohoda de forma não bloqueante e, após a inicialização, faz polling de PohodaClient::getStatus() até o mServer começar a responder. Somente Windows.
A maneira mais simples é passá-lo para PohodaClient — ele então iniciará o mServer de forma lazy antes da primeira solicitação HTTP e o interromperá na destruição (somente se ele mesmo o tiver iniciado; se já estava em execução, ele permanecerá em execução):
use DG\Pohoda\MServerController;
use DG\Pohoda\PohodaClient;
$client = new PohodaClient(url: 'http://127.0.0.1:555', ico: '12345678', username: 'Admin', password: '');
$client->setController(new MServerController(
exePath: 'C:\Program Files (x86)\STORMWARE\POHODA\Pohoda.exe',
configName: 'mServer1',
));
// ... práce s $client — autostart se postará o sebe ...
Se você quiser gerenciar o ciclo de vida manualmente, o controlador pode fazer as mesmas coisas diretamente:
$ctrl = new MServerController(exePath: '...', configName: 'mServer1');
$wasRunning = false;
try {
$client->getStatus();
$wasRunning = true;
} catch (\RuntimeException) {
$ctrl->start($client); // vrátí se až když mServer odpovídá (nebo vyhodí po timeoutu)
}
// ... práce s $client ...
if (!$wasRunning) {
$ctrl->stop();
}
Ao chamar endpoints HTTP, use http://127.0.0.1:555, não http://localhost:555 — o resolvedor PHP tenta primeiro IPv6 para localhost (::1), onde o mServer não escuta, e você espera desnecessariamente por um timeout.
Métodos públicos de MServerController:
start(PohodaClient $client, int $timeoutSeconds = 30)— inicia o Pohoda com/HTTP start, aguarda até a API de status HTTP responder. Em caso de timeout, lançaRuntimeException.stop()— envia/HTTP stopfire-and-forget, não aguarda o encerramento.
Solução de problemas
| Sintoma | Causa provável |
|---|---|
Curl Error: Connection refused | mServer não está em execução; inicie-o no Pohoda ou via pohoda.exe /HTTP start |
HTTP 401 | POHODA_USERNAME / POHODA_PASSWORD incorretos |
| A resposta é HTML com página de login | O usuário no Pohoda não tem permissões para o mServer ou a agenda está aberta por outra instância |
state="error" + note="Nepodařila se validace dokumentu podle schématu" | Estrutura XML incorreta — normalmente namespace trocado ou elemento obrigatório ausente; o texto do erro aponta para o elemento |
listRecords retorna lista vazia | O mServer está conectado a uma unidade contábil/ano diferente daquela onde o documento reside (verifique status com companyDetail=true) |
pdfPath é criado, mas não pode ser aberto (0 B) | O mServer não tem permissão para gravar no local — tente o D:\Data\ucto\Tisk\ padrão ou o diretório temporário do usuário sob o qual o Pohoda está em execução |
Print retorna OK, mas o PDF não é gerado | reportId não existe na instalação; verifique o ID no Editor de relatórios de impressão |
Estrutura do projeto
server.php vstupní bod MCP serveru (stdio transport)
.mcp.json.example vzorová konfigurace MCP klienta
src/
McpTools.php tenký MCP adaptér (#[McpTool] atributy)
PohodaClient.php HTTP klient a doménové metody pro mServer API
XmlBuilder.php stavba XML požadavků přes XMLWriter
Response.php parsovaná odpověď z mServeru
ResponseItem.php jeden záznam z odpovědi
MServerController.php spouštění a zastavování mServeru přes pohoda.exe




