InvoiceXML

Conformidade global de faturamento eletrônico: Factur-X, Peppol UBL, CII e mais

Documentação

Servidor MCP InvoiceXML

Um servidor Model Context Protocol que expõe a API InvoiceXML para agentes de IA. Cobre Factur-X, ZUGFeRD, XRechnung, UBL / CII e Peppol BIS Billing 3.0.

O mesmo código-fonte roda em duas formas de implantação, selecionadas na inicialização por uma variável de ambiente:

ModoQuem executaAutenticação
Auto-hospedadoVocê, na sua própria máquina ou servidorUma única chave de API no ambiente ou appsettings.json
HospedadoInvoiceXML, na sua própria infraestruturaOAuth 2.1 + Registro Dinâmico de Cliente contra invoicexml.com

Ambos executam o mesmo binário; apenas a configuração difere. O repositório é independente de plataforma — ele não sabe nada sobre onde ou como você o hospeda.

Arquitetura

+----------------------+   ProjectReference   +----------------------+
|  InvoiceXml.Mcp.Core | -------------------> |  InvoiceXml.Mcp.Host |
|  (SDK: client+tools) |                      |  (the deployable)    |
+----------------------+                      +----------------------+

InvoiceXml.Mcp.Core é um SDK pequeno e agnóstico de transporte:

  • IInvoiceXmlClient — cliente tipado sobre a API REST pública
  • HttpInvoiceXmlClient — a única implementação; consome um HttpClient de IHttpClientFactory
  • InvoiceXmlClientOptions — URL base, tempo limite (sem autenticação)
  • AddInvoiceXmlMcpCore(IServiceCollection, IConfiguration) — ponto de entrada de injeção de dependência; retorna o IHttpClientBuilder para que o host anexe autenticação como um DelegatingHandler

O SDK nunca vê credenciais. O host as aplica através do pipeline HTTP. Essa costura é o que permite que um único código-fonte atenda a ambos os modos de implantação.

InvoiceXml.Mcp.Host é um aplicativo ASP.NET Core 10:

  • Lê Mcp:AuthMode (ApiKey ou OAuth) na inicialização
  • Conecta o DelegatingHandler correspondente ao cliente HTTP Core via AddHostAuth(...)
  • Serve o endpoint MCP em POST /, uma página de boas-vindas amigável em GET / e /health

Adicionar um novo modo de autenticação = um braço em AuthExtensions.cs mais uma pequena pasta em Auth/<Mode>/. Adicionar uma nova ferramenta = uma classe [McpServerTool]. Nada mais muda.

Estrutura do repositório

invoicexml-mcp/
├── src/
│   ├── InvoiceXml.Mcp.Core/              # the SDK: client, models, tools
│   │   ├── Enums/  Interfaces/  Models/  Options/  Services/  Tools/  Extensions/
│   └── InvoiceXml.Mcp.Host/              # the deployable host
│       ├── Auth/{ApiKey,OAuth}/          # the two auth modes
│       ├── Configuration/
│       ├── Program.cs
│       └── appsettings.json              # safe defaults, no secrets
├── tests/
│   ├── InvoiceXml.Mcp.Core.Tests/
│   └── InvoiceXml.Mcp.Host.Tests/
├── Directory.Build.props                 # repo-wide MSBuild defaults
├── Directory.Packages.props              # Central Package Management
├── global.json                           # pins the .NET SDK
└── InvoiceXml.Mcp.slnx

Executando localmente

Você precisa de um SDK .NET 10 e uma chave de API InvoiceXML.

# 1. Provide your API key (pick one):

# A. dotnet user-secrets (recommended — kept outside the repo)
dotnet user-secrets --project src/InvoiceXml.Mcp.Host set "Mcp:ApiKey:Value" "your-key"

# B. environment variable
$env:INVOICEXML_API_KEY = "your-key"

# 2. Run
dotnet run --project src/InvoiceXml.Mcp.Host

GET http://localhost:5004/ mostra uma página de boas-vindas no navegador; o endpoint MCP é POST http://localhost:5004/; GET /health retorna { "status": "ok" }.

Configuração

{
  // Required in OAuth mode. The public origin where this MCP server is reachable.
  // Used in the protected-resource metadata response.
  "McpUri": "https://mcp.example.com",

  "InvoiceXml": {
    "BaseUrl": "https://api.invoicexml.com",   // override for staging / local
    "Timeout": "00:01:40"
  },

  "Mcp": {
    "AuthMode": "ApiKey",                       // "ApiKey" | "OAuth"
    "ApiKey": {
      "Value": ""                               // ApiKey mode: NEVER commit a real key
    },
    "OAuth": {
      "AuthorizationServer": "https://invoicexml.com",
      "ScopesSupported": [ "api_token.read" ]
    },
    "FileInput": {                              // limits for the URL-fetch input mode
      "MaxFileSizeBytes": 5242880,
      "FetchTimeout": "00:00:30"
    }
  }
}

Equivalentes de variáveis de ambiente (sublinhado duplo = aninhamento):

VariávelMapeia para
INVOICEXML_API_KEYMcp:ApiKey:Value (alias amigável)
Mcp__ApiKey__ValueMcp:ApiKey:Value
Mcp__AuthModeMcp:AuthMode (ApiKey ou OAuth)
Mcp__OAuth__AuthorizationServerMcp:OAuth:AuthorizationServer
McpUriMcpUri (nível raiz)
InvoiceXml__BaseUrlInvoiceXml:BaseUrl

Modo OAuth

Quando Mcp:AuthMode=OAuth o host para de aceitar uma chave de API estática e em vez disso:

  1. Retorna 401 com WWW-Authenticate: Bearer resource_metadata="…" para qualquer POST / que não tenha um token Bearer.
  2. Serve GET /.well-known/oauth-protected-resource apontando clientes MCP para invoicexml.com como o servidor de autorização.
  3. Encaminha o token Bearer recebido literalmente em cada chamada de saída para a API InvoiceXML (a API é a fonte da verdade para validade do token; o servidor MCP não valida tokens localmente).

A dança que um cliente MCP executa:

client → MCP  POST /                           → 401 + resource_metadata
client → /.well-known/oauth-protected-resource → { authorization_servers: [invoicexml.com] }
client → invoicexml.com/.well-known/oauth-authorization-server
                                               → { authorize, token, register endpoints }
client → invoicexml.com/oauth/register         → client_id + client_secret  (DCR)
client → invoicexml.com/oauth/authorize        → user consents, gets code
client → invoicexml.com/oauth/token            → access_token  (= user's API key)
client → MCP  POST /  + Authorization: Bearer  → 200, tool call flows through

Implantação

O host é um aplicativo ASP.NET Core padrão — execute-o da maneira que você executa serviços .NET (systemd, um contêiner, um PaaS, etc.; o repositório não prescreve um):

dotnet publish src/InvoiceXml.Mcp.Host -c Release -o ./publish
# then run ./publish/InvoiceXml.Mcp.Host on your host

Defina a configuração via variáveis de ambiente no host (nunca confirme segredos):

  • ASPNETCORE_ENVIRONMENT=Production
  • Mcp__AuthMode=ApiKey (ou OAuth)
  • Mcp__ApiKey__Value=… / INVOICEXML_API_KEY=… (modo ApiKey)
  • McpUri=https://your-public-url e Mcp__OAuth__AuthorizationServer=https://invoicexml.com (modo OAuth)

Encerre o TLS no seu proxy reverso / balanceador de carga e encaminhe para a porta HTTP do host. O servidor não tem estado, então você pode executar várias instâncias atrás de um balanceador de carga.

Licença

MIT — veja LICENSE.