# Senado Br Mcp Cloudflare

> Hosted MCP server for the Brazilian Federal Senate on Cloudflare Workers — 66 tools, 4 prompts, 5 resources. Legislative + administrative + e-Cidadania. Also on npm (npx senado-br-mcp).

- **Type:** MCP server
- **Install:** `agentstack add mcp-sidneybissoli-senado-br-mcp-cloudflare`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [SidneyBissoli](https://agentstack.voostack.com/s/sidneybissoli)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 2.2.0
- **License:** MIT
- **Upstream author:** [SidneyBissoli](https://github.com/SidneyBissoli)
- **Source:** https://github.com/SidneyBissoli/senado-br-mcp-cloudflare
- **Website:** https://senado.sidneybissoli.com/mcp

## Install

```sh
agentstack add mcp-sidneybissoli-senado-br-mcp-cloudflare
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Senado Brasil MCP Server

[](https://github.com/SidneyBissoli/senado-br-mcp-cloudflare/actions/workflows/ci.yml)
[](https://registry.modelcontextprotocol.io)
[](https://lobehub.com/mcp/sidneybissoli-senado-br-mcp-cloudflare)
[](https://smithery.ai/servers/sidneybissoli/senado-br-mcp-cloudflare)
[](https://glama.ai/mcp/servers/SidneyBissoli/senado-br-mcp-cloudflare)
[](https://github.com/SidneyBissoli/senado-br-mcp-cloudflare)
[](https://github.com/sponsors/SidneyBissoli)
[](LICENSE)
[](https://senado.sidneybissoli.com/status)

🇧🇷 [Leia em Português](README.pt-BR.md)

A **public, hosted** MCP server that gives AI assistants live, structured access to **Brazilian Senate open data** — **no installation, no account, no API key**. Point your MCP client at the hosted endpoint and start asking about senators, bills, votes, expenses, and more. It runs on Cloudflare Workers over Streamable HTTP.

It exposes **67 tools**, **4 prompts**, and **5 resources** across two domains:

- **Legislative** — senators; bills and their tramitation; votes; committees; plenary sessions, results and presidential vetoes; party-bloc voting orientation; speeches and stenographic transcripts; blocs and leadership; federal legislation; and citizen participation via the e-Cidadania portal.
- **Administrative** — CEAPS parliamentary-quota expenses; housing allowance; civil servants and payroll; overtime; interns; procurement contracts and biddings; outsourced staff; petty-cash funds; and budget execution.

Data comes from three official 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. All tool responses are in Portuguese (pt-BR). See [CHANGELOG.md](CHANGELOG.md) for release history.

## See it in action

Point a client at the endpoint and ask in plain language — English or Portuguese:

- *"How did São Paulo's senators vote in the most recent floor votes?"* → `senado_search_votacoes`
- *"Show the legislative progress of PEC 45/2019 (a constitutional amendment proposal)."* → `senado_buscar_materias` + `senado_obter_materia`
- *"How much was spent on the CEAPS parliamentary allowance in 2024, broken down by expense type?"* → `senado_ceaps`

The answers come live from the Senate's official open-data APIs — exact figures with provenance, not numbers guessed from training data.

## Use it (hosted — no setup)

This is a **remote, hosted, open-access** server. To use it, point any MCP client at the Streamable
HTTP endpoint — **no install, no account, no API key, no configuration**:

```
https://senado.sidneybissoli.com/mcp
```

### OpenAI / ChatGPT app surface

For OpenAI Apps SDK submission and review, the Worker also exposes a curated MCP surface:

```
https://senado.sidneybissoli.com/mcp/openai-app-v2
```

This endpoint intentionally keeps the full public MCP server intact at `/mcp`, but limits tool discovery
to 27 high-signal, intent-oriented tools for ChatGPT app use. `/mcp/openai-app` remains available as a
legacy alias, but new ChatGPT app configurations should use `/mcp/openai-app-v2` so clients fetch the
current tool schema. The tools still call the same handlers and return the same provenance envelope; only
the advertised surface is narrower. Any ChatGPT app listing should present this as an independent open-data
research app, not as an official Senate, OpenAI or ChatGPT connector.

For ChatGPT Apps, those 27 tools also advertise a shared MCP Apps UI template at
`ui://senado-br-mcp/openai-app-dashboard-v2.html`. The self-contained widget renders the returned
`structuredContent` as a compact dashboard with metrics, main records, and source/provenance, without
adding another model-visible data tool.

Public legal URLs for app review:

- Privacy policy: `https://senado.sidneybissoli.com/privacy`
- Terms of use: `https://senado.sidneybissoli.com/terms`

### Install (any client)

For clients that launch MCP servers as a command — and for one-command setup — use the
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge. **No build, no config, no key:**

```bash
npx -y mcp-remote https://senado.sidneybissoli.com/mcp
```

- **One-click (LobeHub):** open the [server page](https://lobehub.com/mcp/sidneybissoli-senado-br-mcp-cloudflare) and click **Install**.
- **Native remote URL** (Claude Desktop/Code and other Streamable-HTTP clients): see [Connecting MCP Clients](#connecting-mcp-clients).

Everything below *Architecture* (Prerequisites, Setup, Deploy) is **only for optionally self-hosting your
own instance** — it is **not** required to use this public server.

## Run locally (npx · stdio)

Prefer not to route queries through a third-party host (e.g. a newsroom policy)? The **same server**
also runs as a **local stdio process** that talks **directly to the official government APIs** — same
67 tools, same provenance envelope, no Cloudflare in the loop. This is the npm/stdio channel, published
as [`senado-br-mcp`](https://www.npmjs.com/package/senado-br-mcp).

Point a command-based client (Claude Desktop/Code, etc.) at the package — npm fetches and runs it,
no clone or build:

```json
{
  "mcpServers": {
    "senado-br": {
      "command": "npx",
      "args": ["-y", "senado-br-mcp"]
    }
  }
}
```

To run it directly or hack on it, use the source checkout instead:

```bash
git clone https://github.com/SidneyBissoli/senado-br-mcp-cloudflare
cd senado-br-mcp-cloudflare
npm install
npm run build
node dist/cli.js   # serves MCP over stdio (Ctrl+C to stop)
```

**Parity with the hosted server:** the legislative and administrative tools are **identical** (same
upstream APIs, same throttle/cache/provenance) — locally the L1 Cloudflare cache is a no-op, but the L0
in-memory cache still works, so results are the same. The **only** difference is the e-Cidadania
list/corpus tools: without D1 they fall back to a live scrape of the ~5 REST highlights, flagged via
`meta.fonte` / `possivelDesatualizacao`; the detail tools (`obter_*`) are identical. Logs go to
**stderr** — stdout carries only the JSON-RPC protocol stream.

## Agent Skill (optional)

This repo bundles a Claude [Agent Skill](https://platform.claude.com/docs/en/docs/agents-and-tools/agent-skills/overview)
at [`.claude/skills/senado-br/`](.claude/skills/senado-br/SKILL.md) that teaches Claude **when** to reach for
this server and **how** to use its 67 tools well — a themed tool map, common question→tool playbooks, the
provenance contract, and gotchas (dates, the `codigoMateria` bridge, e-Cidadania's open-set listing, pagination).
It points back to the server's own `senado://catalogo` / `senado://guia` resources rather than duplicating them.

Claude Code auto-discovers it when you work in this repo. To use it elsewhere, copy
`.claude/skills/senado-br/` into your `~/.claude/skills/`, or zip the folder and upload it in claude.ai
(Settings → Features). The skill assumes the `senado-br` MCP server is connected (hosted or via npx).

## Architecture

- **Runtime:** Cloudflare Workers (ESM)
- **Transport:** Streamable HTTP (MCP spec 2025-03-26) via `createMcpHandler` from `agents/mcp`
- **Protocol:** MCP over JSON-RPC — `/mcp` handles the full public server; `/mcp/openai-app-v2` exposes a curated 27-tool profile plus a shared MCP Apps widget for OpenAI app review/submission (`/mcp/openai-app` remains as a legacy alias)
- **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
- **e-Cidadania store:** D1 database refreshed by a Cron Trigger (every 2h) — list tools read from D1 with a live-scrape fallback and a staleness flag; detail tools stay live with write-through (see [e-Cidadania](#e-cidadania-d1-backed-cron-refreshed))
- **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 at `/metrics`; per-tool call telemetry (selection, error rate, cache-vs-live) in Cloudflare Analytics Engine, PII-free
- **Liveness:** Runs on Cloudflare's own global network behind a custom domain — no third-party host that can go dark. Public `/health` and `/status` (version + last-deploy id/timestamp) make uptime and the current build verifiable; the **status** badge above pings the live endpoint
- **Tests:** Vitest unit tests for parsers, helpers, cache, throttle, and auth

## Self-hosting (optional)

> **Not needed to use the server** — it is already hosted at `https://senado.sidneybissoli.com/mcp`
> (open access). Follow this section only if you want to run your **own** private instance.

### Prerequisites

- Node.js 20+
- [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"
```

The e-Cidadania pipeline needs a **D1 database** and a **Cron Trigger** (both already declared in `wrangler.toml` — replace the database ID):

```toml
[[d1_databases]]
binding = "ECIDADANIA_DB"
database_name = "senado-ecidadania"
database_id = "YOUR_D1_DATABASE_ID_HERE"

[triggers]
crons = ["0 */2 * * *"]
```

Create the database (paste the returned ID above) and apply the schema:

```bash
npx wrangler d1 create senado-ecidadania
npx wrangler d1 migrations apply senado-ecidadania --remote
```

The list tools fall back to live scraping when D1 is empty, so the server works before the first Cron run.

#### 4. (Optional) Enable authentication

```bash
wrangler secret put API_KEY
# Clients must then send: Authorization: Bearer 
# When API_KEY is not set, the server is open access.
```

#### 5. Local development

```bash
npm run dev
# Dev server runs locally on port 8787 (local only).
# The public MCP endpoint is https://senado.sidneybissoli.com/mcp
```

#### 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
# Serves at https://senado.sidneybissoli.com (custom domain) and
# https://senado-br-mcp.sidneybissoli.workers.dev (workers.dev fallback)
```

## Endpoints

| Path | Methods | Description |
|------|---------|-------------|
| `/` | GET | Landing page (pt-BR) — identifies the client behind the outgoing User-Agent: what the service is, load posture, contact (always public) |
| `/mcp` | POST, GET, DELETE, OPTIONS | MCP Streamable HTTP endpoint (managed by `createMcpHandler`) |
| `/health` | GET | Health check — returns `ok` (always public) |
| `/status` | GET | JSON: `status`, `version`, and last-deploy metadata (`deploy.id`/`tag`/`timestamp`) — liveness + current build, no MCP handshake needed (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_search_votacoes",
    "arguments": {
      "dias": 7
    }
  }
}
```

### Call a tool — Most popular citizen ideas

```json
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "senado_ecidadania_listar_ideias",
    "arguments": {
      "ordenarPor": "apoios",
      "ordem": "desc",
      "status": "aberta"
    }
  }
}
```

## 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}` (+ `/mandatos`) | `senado_obter_senador` (biografia + mandatos via chamada extra) |
| `/senador/{codigo}/licencas`, `/comissoes`, `/cargos`, `/historicoAcademico`, `/filiacoes`, `/profissao` | `senado_senador_historico` (`tipo` enum) |
| `/senador/afastados` | `senado_senadores_afastados` |
| `/senador/{codigo}/apartes` | `senado_discursos_senador` (`tipo=apartes`) |
| `/comissao/lista/colegiados` | `senado_listar_comissoes` (+ sigla-to-code resolution) |
| `/comissao/{codigo}` | `senado_obter_comissao` (`secao=resumo`; numeric code, not sigla) |
| `/composicao/comissao/{codigo}` (+ `?ativas=S`) | `senado_obter_comissao` (`secao=membros`) |
| `/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` (upstream often empty even for active CPIs — empty result carries an `aviso`) |
| `/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_tabelas_referencia` (`tabela=tipos-uso-palavra`) |
| `/composicao/lista/blocos` | `senado_listar_blocos` |
| `/composicao/bloco/{codigo}` | `senado_obter_bloco` |
| `/composicao/lideranca` | `senado_liderancas` |
| `/composicao/mesaSF` | `senado_mesa` (`casa=senado`) |
| `/composicao/mesaCN` | `senado_mesa` (`casa=congresso`) |
| `/orcamento/lista` | `senado_or

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SidneyBissoli](https://github.com/SidneyBissoli)
- **Source:** [SidneyBissoli/senado-br-mcp-cloudflare](https://github.com/SidneyBissoli/senado-br-mcp-cloudflare)
- **License:** MIT
- **Homepage:** https://senado.sidneybissoli.com/mcp

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v2.2.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **2.2.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-sidneybissoli-senado-br-mcp-cloudflare
- Seller: https://agentstack.voostack.com/s/sidneybissoli
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
