Programadores · MCP
Ligue o Foral ao seu assistente de IA (MCP)
O Model Context Protocol (MCP) permite que assistentes de IA — Claude, Cursor, ChatGPT e outros — chamem o Foral diretamente como ferramentas. O Foral tem dois tipos de servidor MCP: o MCP de Dados Foral, para contas Premium, e um servidor MCP por cada agente de empresa publicado.
1. MCP de Dados Foral
O servidor MCP de Dados Foral expõe a API de Dados como ferramentas MCP: contratação pública (Portal BASE), sinais municipais, concelhos, os seus alertas e o catálogo de indicadores. URL: https://data.foral.ai/mcp.
É para contas Premium. Use a mesma chave sk_live_… da API REST — crie-a na página Chaves de API. Os âmbitos da chave e o seu plano decidem que ferramentas o tools/list mostra; uma ferramenta que a chave não pode chamar simplesmente não aparece.
Os limites são os da API REST: cada pedido HTTP conta para o limite por minuto, e cada tools/call conta como um pedido na quota mensal. O arranque (initialize, tools/list, ping) não gasta quota. Comece pela ferramenta me — devolve o plano, os domínios, os âmbitos e os limites.
| Ferramenta | Domínio de dados |
|---|---|
me | — |
municipalities_search | indicators |
municipalities_get | indicators |
indicators_list | indicators |
indicators_series | indicators |
indicators_snapshot | indicators |
signals_list | signals |
signals_get | signals |
signal_cases_list | signals |
procurement_contracts | procurement |
procurement_aggregate | procurement |
procurement_entities | procurement |
procurement_entity_profile | procurement |
procurement_lookup_municipalities | procurement |
procurement_lookup_entities | procurement |
procurement_announcements | procurement |
procurement_amendments | procurement |
alert_rules | alerts |
alert_matches | alerts |
structuredContent (o mesmo JSON que o endpoint REST devolve) e uma cópia em texto. Uma chamada falhada (por exemplo, quota mensal esgotada) volta como resultado com isError: true e o documento de erro da API REST.2. MCP de um agente de empresa
Cada agente de empresa publicado no canal MCP tem o seu servidor: https://agents.foral.ai/<slug>/mcp. <slug> é o identificador da publicação, visível no estúdio da empresa.
Autentique-se com uma credencial do agente, criada por um administrador da empresa no estúdio (passo Publicar, canal MCP). As ferramentas são as que o agente ativa — o seu conhecimento, a área de serviço e, quando ativas, as consultas de contratação pública. A publicação tem de estar em produção.
Para publicar o agente da sua empresa, veja Agentes Foral.
3. Instalar no seu cliente
Os exemplos usam o MCP de Dados. Para um agente de empresa, use https://agents.foral.ai/<slug>/mcp e a credencial do agente. Substitua sk_live_... pela sua chave e guarde-a em segredo.
Claude Code
Depois corra claude mcp list — o servidor aparece como ligado.
Terminal
claude mcp add --transport http foral https://data.foral.ai/mcp \
--header "Authorization: Bearer sk_live_..."Claude Desktop (através do mcp-remote)
Junte este bloco ao claude_desktop_config.json (Settings → Developer → Edit config) e reinicie o Claude Desktop. Precisa do Node.js. A chave fica em env para o cabeçalho não ser partido nos argumentos em Windows.
claude_desktop_config.json
{
"mcpServers": {
"foral": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://data.foral.ai/mcp",
"--header", "Authorization:${AUTH_HEADER}",
"--transport", "http-only"
],
"env": { "AUTH_HEADER": "Bearer sk_live_..." }
}
}
}Conectores do claude.ai e do Claude Desktop, e ChatGPT
Estes clientes ligam-se com OAuth: entra na sua conta Foral e aprova o acesso — sem chave para colar.
- claude.ai e Claude Desktop: Customize → Connectors → Add → Add custom connector. Indique um nome e o URL do servidor, clique em Add (o Claude deteta o OAuth e regista-se sozinho) e depois em Connect. Abre o Foral: entre na conta e clique em Permitir acesso.
- ChatGPT: Plugins → Add → Add custom MCP server. Indique um nome e o URL do servidor, mantenha a autenticação em OAuth (o ChatGPT regista-se sozinho), aceite o aviso de risco e clique em Create as a plugin e depois em Continue. Abre o Foral: entre na conta e clique em Permitir acesso.
- Pode ver e desligar as aplicações ligadas a qualquer momento em Aplicações ligadas.
Cursor e Windsurf
Cursor: junte o bloco a ~/.cursor/mcp.json (ou .cursor/mcp.json num projeto). Windsurf: o mesmo bloco em ~/.codeium/windsurf/mcp_config.json, com serverUrl em vez de url.
mcp.json
{
"mcpServers": {
"foral": {
"url": "https://data.foral.ai/mcp",
"headers": { "Authorization": "Bearer sk_live_..." }
}
}
}Python (SDK MCP 1.x)
Exemplo mínimo com o SDK oficial MCP para Python, versão 1.x (testado com a 1.30). O SDK 2.x mudou esta API de cliente.
client.py
# pip install "mcp>=1.30,<2" httpx
import asyncio
import httpx
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
URL = "https://data.foral.ai/mcp"
KEY = "sk_live_..."
async def main() -> None:
headers = {"Authorization": f"Bearer {KEY}"}
async with httpx.AsyncClient(headers=headers, timeout=30) as http:
async with streamable_http_client(URL, http_client=http) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
print([t.name for t in tools.tools])
result = await session.call_tool("municipalities_search", {"q": "Faro", "limit": 5})
print(result.structuredContent)
asyncio.run(main())JSON-RPC direto (curl)
Os servidores falam Streamable HTTP com respostas JSON: uma mensagem JSON-RPC por POST. Não há sessão a abrir — liste as ferramentas e chame uma.
Listar as ferramentas
curl -s https://data.foral.ai/mcp \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Chamar uma ferramenta
curl -s https://data.foral.ai/mcp \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Protocol-Version: 2025-06-18" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"municipalities_search","arguments":{"q":"Faro","limit":5}}}'4. Limites
Uma resposta 429 traz Retry-After (segundos). Espere esse tempo antes de repetir.
| Servidor | Limite |
|---|---|
| MCP de Dados Foral | O limite por minuto do seu plano (cada pedido HTTP) e a quota mensal (um pedido por tools/call), partilhados com a API REST. |
| MCP de um agente de empresa | 60 pedidos/minuto por credencial, 200/minuto por publicação (valores por omissão). Ligar gasta cerca de 3 pedidos. |
5. Resolução de problemas
| Resposta | O que significa |
|---|---|
401 | Chave em falta, errada, expirada ou revogada. Envie Authorization: Bearer sk_live_…. |
403 | O pedido veio de uma página de browser noutro site (cabeçalho Origin). Chame o servidor a partir de um cliente de desktop, de um IDE ou do seu backend. No MCP de Dados, um 403 também pode significar que o seu plano não inclui acesso à API de Dados (api-access-required, mude para Premium) ou que a chave está limitada a um grupo beta (beta-access-required). |
404 (agente de empresa) | <slug> errado, publicação fora de produção, ou credencial de outra publicação ou sem o canal MCP. |
405 | GET não é servido: estes servidores são só POST. Os clientes MCP tratam disto sozinhos. |
400 | Mcp-Protocol-Version não suportada. Use 2025-06-18 ou 2025-11-25. |
429 | Limite de pedidos. Espere Retry-After segundos. |
quota-exceeded / 402 | Quota mensal esgotada. Espere pela renovação ou mude de plano. |
| Falta uma ferramenta | A chave não tem o âmbito ou o plano não inclui o domínio. Chame me para ver ambos. |
503 | Temporário. Repita com intervalos crescentes. |