MCP server for Brazilian Senate open data running on Cloudflare Workers (37 tools, Streamable HTTP transport)
git clone https://github.com/SidneyBissoli/senado-br-mcp-cloudflare{
"mcpServers": {
"senado-br-mcp-cloudflare": {
"command": "node",
"args": ["/path/to/senado-br-mcp-cloudflare/dist/index.js"]
}
}
}MCP Servers overview
# senado-br-mcp (Cloudflare Workers)
MCP server for **Brazilian Senate open data** running on Cloudflare Workers with Streamable HTTP transport.
Provides **90 tools** organized into 19 groups covering the **legislative** domain (senators, bills, votes, committees, plenary sessions and results, presidential vetoes, party-bloc voting orientation, legislative processes, reference data, citizen participation via e-Cidadania, speeches and stenographic transcripts, blocs and leadership, federal legislation, committee voting) and the **administrative** domain (CEAPS parliamentary quota expenses, housing allowance, civil servants and payroll, overtime, interns, procurement contracts, biddings, outsourced staff, petty-cash funds, budget execution and own revenues). Connects to three sources: the [legislative open data API](https://legis.senado.leg.br/dadosabertos/), the [administrative open data API](https://adm.senado.gov.br/adm-dadosabertos/swagger-ui/index.html) and the e-Cidadania portal.
> **v2.1.0:** all tools that consumed endpoints marked *deprecated* upstream (the legacy `/materia/*` family and `/senador/{codigo}/votacoes`) were migrated to the v3 `/processo` and `/votacao` APIs, keeping tool names and output keys stable.
>
> **v2.2.0:** adds the administrative domain (groups O, P, Q, R — 16 tools) consuming `adm.senado.gov.br`. Large datasets (CEAPS ≈ 10 MB/year, payroll ≈ 5.5 MB/month) are fetched once, cached, and filtered/aggregated inside the Worker — tools never return raw dumps.
## Architecture
- **Runtime:** Cloudflare Workers (ESM)
- **Transport:** Streamable HTTP (MCP spec 2025-03-26) via `createMcpHandler` from `agents/mcp`
- **Protocol:** MCP over JSON-RPC — single `/mcp` endpoint handles POST, GET, DELETE
- **SDK:** `@modelcontextprotocol/sdk` 1.26.0+ (per-request McpServer instances)
- **Validation:** Zod schemas for all tool inputs
- **Caching:** 2-layer (L0 memory + L1 Cache API) with SHA-256 keying
- **Rate limiting:** Token bucket — global (8 req/s) + per-client (2 req/s)
- **Upstream throttle:** Max 6 concurrent requests, 10s timeout, retry with exponential backoff
- **Auth:** Optional Bearer token (set the `API_KEY` secret; open access when unset). Constant-time comparison.
- **Observability:** Structured JSON logging + in-memory counters exposed at `/metrics`
- **Tests:** Vitest unit tests for parsers, helpers, cache, throttle, and auth
## Prerequisites
- Node.js 18+
- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/) v4+
- Cloudflare account
## Setup
### 1. Install dependencies
```bash
npm install
```
### 2. Create KV namespace
```bash
# Create the KV namespace
wrangler kv namespace create CACHE_KV
# Note the ID from the output, e.g.:
# { binding = "CACHE_KV", id = "abc123..." }
```
### 3. Configure wrangler.toml
Replace the placeholder KV namespace ID:
```toml
[[kv_namespaces]]
binding = "CACHE_KV"
id = "YOUR_KV_NAMESPACE_ID_HERE"
```
Optionally set `ALLOWED_ORIGIN` to restrict CORS:
```toml
[vars]
ALLOWED_ORIGIN = "https://your-app.example.com"
```
### 4. (Optional) Enable authentication
```bash
wrangler secret put API_KEY
# Clients must then send: Authorization: Bearer <key>
# When API_KEY is not set, the server is open access.
```
### 5. Local development
```bash
npm run dev
# Server runs at http://localhost:8787
```
### 6. Tests and typecheck
```bash
npm test # run all tests once
npm run test:watch # watch mode
npm run typecheck # tsc --noEmit
```
### 7. Deploy
```bash
npm run deploy
# Deploys to https://senado-br-mcp.sidneybissoli.workers.dev
```
## Endpoints
| Path | Methods | Description |
|------|---------|-------------|
| `/mcp` | POST, GET, DELETE, OPTIONS | MCP Streamable HTTP endpoint (managed by `createMcpHandler`) |
| `/health` | GET | Health check — returns `ok` (always public) |
| `/metrics` | GET | JSON counters: requests, tool calls, cache hits/misses, upstream calls/retries/errors, auth failures (always public) |
## MCP Request Examples
All requests go to `POST /mcp` with JSON-RPC 2.0 format.
### List available tools
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
```
### Call a tool — List senators from SP
```json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "senado_listar_senadores",
"arguments": {
"uf": "SP",
"emExercicio": true
}
}
}
```
### Call a tool — Search bills by keyword
```json
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "senado_buscar_materias",
"arguments": {
"palavraChave": "inteligência artificial",
"tramitando": true
}
}
}
```
### Call a tool — Get recent plenary votes
```json
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "senado_votacoes_recentes",
"arguments": {
"dias": 30
}
}
}
```
### Call a tool — Most popular citizen ideas
```json
{
"jsonrpc": "2.0",
"id": 5,
"method": "tools/call",
"params": {
"name": "senado_ecidadania_ideias_populares",
"arguments": {
"limite": 5
}
}
}
```
## Upstream API Endpoints
The server consumes two classes of upstream endpoints from the Senado API:
### Legacy endpoints (`.json` suffix, PascalCase responses)
Used by Groups A, E, F, H, I, J, K, L, M, N. The `.json` suffix is appended automatically by `upstream.ts`. None of these is marked deprecated upstream.
| Upstream path | Used by |
|---------------|---------|
| `/senador/lista/atual` | `senado_listar_senadores` |
| `/senador/lista/legislatura/{legislatura}` | `senado_listar_senadores` (param `legislatura`) |
| `/senador/{codigo}` | `senado_obter_senador`, `senado_senador_detail` |
| `/senador/{codigo}/licencas`, `/comissoes`, `/cargos`, `/historicoAcademico` | `senado_senador_historico` |
| `/senador/afastados` | `senado_senadores_afastados` |
| `/senador/{codigo}/apartes` | `senado_apartes_senador` |
| `/comissao/lista/colegiados` | `senado_listar_comissoes` (+ sigla-to-code resolution) |
| `/comissao/{codigo}` | `senado_obter_comissao` (numeric code, not sigla) |
| `/composicao/comissao/{codigo}` | `senado_membros_comissao` |
| `/comissao/agenda/{data}` | `senado_agenda_comissoes` |
| `/comissao/agenda/{dataInicio}/{dataFim}` | `senado_reunioes_comissao` |
| `/comissao/reuniao/{codigoReuniao}` | `senado_reuniao_comissao` |
| `/comissao/cpi/{sigla}/requerimentos` | `senado_requerimentos_cpi` (empty body = no requests) |
| `/materia/distribuicao/autoria`, `/distribuicao/relatoria/{sigla}` | `senado_distribuicao_materias` |
| `/plenario/agenda/dia/{data}`, `/agenda/mes/{data}`, `/agenda/cn/...` | `senado_agenda_plenario` |
| `/plenario/resultado/{data}`, `/resultado/cn/{data}`, `/resultado/mes/{data}` | `senado_resultado_plenario` |
| `/plenario/resultado/veto/{codigo}` (+ `/materia/`, `/dispositivo/`) | `senado_resultado_veto` |
| `/plenario/votacao/orientacaoBancada/{data}` (+ período) | `senado_orientacao_bancada` |
| `/plenario/encontro/{codigo}` (+ `/pauta`, `/resultado`, `/resumo`) | `senado_encontro_plenario` |
| `/plenario/tiposSessao`, `/lista/tiposComparecimento`, `/lista/legislaturas` | `senado_tabelas_plenario` |
| `/materia/vetos/{ano}`, `/vetos/aposrcn`, `/vetos/antesrcn`, `/vetos/encerrados` | `senado_vetos` |
| `/taquigrafia/notas/{sessao\|reuniao}/{id}` | `senado_notas_taquigraficas` |
| `/taquigrafia/videos/{sessao\|reuniao}/{id}` | `senado_videos_taquigrafia` |
| `/senador/{codigo}/discursos` | `senado_discursos_senador` |
| `/plenario/lista/discursos/{dataInicio}/{dataFim}` | `senado_discursos_plenario` |
| `/discurso/texto-integral/{codigo}` | `senado_discurso_texto` (plain text, fetched directly) |
| `/senador/lista/tiposUsoPalavra` | `senado_tipos_uso_palavra` |
| `/composicao/lista/blocos` | `senado_listar_blocos` |
| `/composicao/bloco/{codigo}` | `senado_obter_bloco` |
| `/composicao/lideranca` | `senado_liderancas` |
| `/composicao/mesaSF` | `senado_mesa_senado` |
| `/composicao/mesaCN` | `senado_mesa_congresso` |
| `/orcamento/lista` | `senado_orcamento_emendas` |
| `/orcamento/oficios` | `senado_orcamento_oficios` |
| `/legislacao/lista` | `senado_buscar_legislacao` |
| `/legislacao/{codigo}` | `senado_obter_legislacao` |
| `/legislacao/tiposNorma` | `senado_tipos_norma` |
| `/votacaoComissao/comissao/{sigla}` | `senado_votacao_comissao` |
| `/votacaoComissao/parlamentar/{codigo}` | `senado_votacao_comissao_senador` |
| `/votacaoComissao/materia/{sigla}/{numero}/{ano}` | `senado_votacao_comissao_materia` |
| `/autor/lista/atual` | `senado_autores_atuais` |
### v3 endpoints (flat JSON arrays/objects, camelCase)
Used by Groups B, C, D. Dates must be in **ISO format** (`YYYY-MM-DD`) — tools accept `YYYYMMDD` and convert. The `codigoMateria` query param bridges legacy matéria codes to v3 processes.
| Upstream path | Used by |
|---------------|---------|
| `/votacao` | `senado_listar_votacoes`, `senado_votacoes_recentes`, `senado_obter_votacao`, `senado_search_votacoes`, `senado_votos_materia`, `senado_votacoes_senador` |
| `/processo` | `senado_search_processos`, `senado_buscar_materias` |
| `/processo/{id}` | `senado_obter_processo`, `senado_obter_materia`, `senado_tramitacao_materia` |
| `/processo/documento` | `senado_textos_materia` |
| `/processo/emenda` | `senado_emendas_processo` |
| `/processo/relatoria` | `senado_relatorias_processo`, `senado_obter_materia` (rapporteur) |
| `/processo/prazo` | `senado_prazos_processo` |
| `/processo/{siglas,assuntos,classes,destinos,entes,tipos-*}` | `senado_tabelas_processo` (12 reference tables) |
### Administrative API (adm.senado.gov.br/adm-dadosabertos, flat snake_case JSON)
Used by Groups O, P, Q, R via `admFetch` (no `.json` suffix; HTTP 404 treated as empty collection). Base URL configurable via `SENADO_ADM_BASE_URL`.
| Upstream path | Used by |
|---------------|---------|
| `/api/v1/senadores/despesas_ceaps/{ano}` | `senado_ceaps` (~10 MB/year, cached + aggregated in-Worker) |
| `/aWhat people ask about senado-br-mcp-cloudflare
What is SidneyBissoli/senado-br-mcp-cloudflare?
+
SidneyBissoli/senado-br-mcp-cloudflare is mcp servers for the Claude AI ecosystem. MCP server for Brazilian Senate open data running on Cloudflare Workers (37 tools, Streamable HTTP transport) It has 0 GitHub stars and was last updated today.
How do I install senado-br-mcp-cloudflare?
+
You can install senado-br-mcp-cloudflare by cloning the repository (https://github.com/SidneyBissoli/senado-br-mcp-cloudflare) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is SidneyBissoli/senado-br-mcp-cloudflare safe to use?
+
SidneyBissoli/senado-br-mcp-cloudflare has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains SidneyBissoli/senado-br-mcp-cloudflare?
+
SidneyBissoli/senado-br-mcp-cloudflare is maintained by SidneyBissoli. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to senado-br-mcp-cloudflare?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy senado-br-mcp-cloudflare to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/sidneybissoli-senado-br-mcp-cloudflare)<a href="https://claudewave.com/repo/sidneybissoli-senado-br-mcp-cloudflare"><img src="https://claudewave.com/api/badge/sidneybissoli-senado-br-mcp-cloudflare" alt="Featured on ClaudeWave: SidneyBissoli/senado-br-mcp-cloudflare" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!
⭐AI-driven public opinion & trend monitor with multi-platform aggregation, RSS, and smart alerts.🎯 告别信息过载,你的 AI 舆情监控助手与热点筛选工具!聚合多平台热点 + RSS 订阅,支持关键词精准筛选。AI 智能筛选新闻 + AI 翻译 + AI 分析简报直推手机,也支持接入 MCP 架构,赋能 AI 自然语言对话分析、情感洞察与趋势预测等。支持 Docker ,数据本地/云端自持。集成微信/飞书/钉钉/Telegram/邮件/ntfy/bark/slack 等渠道智能推送。