npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jamesmccomish/mp-mcp

v0.2.0

Published

Model Context Protocol server for agents to use UK Parliament data.

Downloads

80

Readme

mp-mcp

npm version CI Node License: MIT

A Model Context Protocol (MCP) server that makes UK Parliament data agent-friendly — intent-led tools, citation-first responses.

mp-mcp lets an agent answer real questions about Westminster — "how has my MP voted on climate?", "what is Parliament doing about NHS waiting lists?" — by composing a small set of purpose-built tools over UK Parliament's official public APIs. Every response carries source URLs so the agent can cite its claims back to parliament.uk and hansard.parliament.uk.

Install

Add to Claude Code:

claude mcp add mp-mcp -- npx -y @jamesmccomish/mp-mcp

Or configure any MCP client that speaks stdio:

{
  "mcpServers": {
    "mp-mcp": {
      "command": "npx",
      "args": ["-y", "@jamesmccomish/mp-mcp"]
    }
  }
}

The server communicates over stdio (JSON-RPC on stdin/stdout) and runs as a subprocess — there is no HTTP/SSE transport in the package itself. (For a hosted HTTP endpoint usable with the Anthropic MCP connector, see apps/mcp-host.)

What you can ask it

The tools are designed around questions a person actually asks. Once the server is connected, prompts like these route to the right tools automatically:

  • "Who's my MP? My postcode is BS3 4QH."
  • "How has the MP for Holborn and St Pancras voted on climate?"
  • "What is Parliament doing about NHS waiting lists?"
  • "Explain the last Commons vote on the Renters' Rights Bill."
  • "What's in Diane Abbott's register of interests?"

Tools

Fifteen tools, grouped by the job they do. Names are stable and namespaced parliament_*.

Identity — who and where

| Tool | Purpose | | --- | --- | | parliament_find_member | Find a sitting (or former) member by name, constituency, or postcode. | | parliament_find_constituency | Find a constituency by name or postcode; returns the record plus the current MP. |

Synthesis — the real work

| Tool | Purpose | | --- | --- | | parliament_member_overview | One-call overview of an MP: synopsis, policy focus, contact, committees, recent votes, recent contributions, and interests. | | parliament_member_voting_history | One member's voting record over time, optionally filtered by topic keyword and date range (Commons and Lords). | | parliament_search_hansard | Full-text search across Hansard (debates, written answers, statements); returns cited excerpts and the IDs needed to drill in. | | parliament_get_debate | Full text of a single Hansard debate by ID or URL; caps at ~15K tokens and steers narrower follow-ups when longer. | | parliament_topic_tracker | A cross-Parliament round-up on one topic — bills, debates, divisions, written questions, and petitions, fanned out in parallel. |

Divisions — recorded votes

| Tool | Purpose | | --- | --- | | parliament_search_divisions | Find Commons divisions on a topic with their IDs, titles, dates, and aggregate aye/no counts — the entry point for "what was voted on". | | parliament_get_division | Full detail of one division: ayes and noes by party, totals, and (in detailed mode) every named voter. Commons and Lords. |

Drill-ins — targeted detail

| Tool | Purpose | | --- | --- | | parliament_member_interests | An MP's Register of Members' Financial Interests: earnings, gifts, donations, shareholdings, employment, visits. | | parliament_get_committee | Full committee detail: membership, chair, category, and optionally recent reports and evidence sessions. | | parliament_get_bill | Full detail of a bill: short title, house and stage, whether it became an Act or was defeated, sponsors, and stage history. | | parliament_get_state_of_parties | Seat counts by party for a house on a given date — the current or historical party balance. | | parliament_get_ministerial_roles | Government ministers or opposition shadow post-holders, with the current holder and department for each. | | parliament_get_election_results | Election results for a constituency: winner, party, majority, turnout, electorate, and the full candidate breakdown. |

Prompts

Four MCP prompts package common multi-tool workflows into one invocation:

| Prompt | Purpose | | --- | --- | | mp-report-card | A one-page report card for an MP, given a postcode or name. Orchestrates find_membermember_overview. | | topic-tracker | A narrative briefing on what Parliament is doing about a topic — bills, debates, votes, written questions, petitions. | | draft-constituent-letter | Draft a letter to an MP, grounded in their actual voting record and Hansard contributions on the issue. | | vote-explainer | Explain a Commons division: the motion, the result, the party breakdown, and the surrounding debate. |

The citation contract

Every tool response is a typed envelope:

type ToolResponse<T> = {
  data: T;
  sources: Array<{ title: string; url: string }>; // parliament.uk / hansard.parliament.uk
  meta?: {
    upstream_calls?: number;
    truncated?: boolean;
    truncation_hint?: string; // present when a response was capped — steers a narrower follow-up
  };
};

sources is always present and populated for factual results. The server's instructions field (sent to the model on connection) asks the agent to cite those URLs inline for any claim it makes. This is the project's central credibility lever: a grounded answer over a guessed one.

Architecture

A clean layering, top to bottom:

tools/        intent-led tool definitions (Zod schema + response_format toggle + handler)
   │
domain/       hand-written, agent-friendly domain types + mappers (API shapes → clean output)
   │
clients/      one client per upstream API (members, hansard, votes, bills, committees, …)
   │
clients/http  shared fetch wrapper: retry + timeout, User-Agent, Open Parliament Licence headers

Cross-cutting concerns live in lib/: citations (URL builders), errors (structured tool errors), responseFormat (the concise/detailed toggle), logger (pino), and registerTool (the wrapper every tool registers through, so the envelope and contract can't drift).

TypeScript API types in src/generated/ are produced from Parliament's OpenAPI specs and committed so the package installs with no network access. Locked decisions are recorded in docs/adrs/ — ESM-only Node 22 target (0001), committed generated types (0002), citation-contract enforcement (0003), the eval suite as contract (0004).

Local development

pnpm install
pnpm --filter @jamesmccomish/mp-mcp build      # one-off compile to dist/
pnpm --filter @jamesmccomish/mp-mcp dev        # incremental tsc --watch into dist/
pnpm --filter @jamesmccomish/mp-mcp test       # vitest

Once built, the repo's .claude/settings.json registers the local artifact in Claude Code under the mp-mcp-local name. With dev running, edits recompile on save; restart the MCP client to pick up the new dist/.

Inspect tool calls

Drive the server directly, without a full client session:

pnpm --filter @jamesmccomish/mp-mcp build
npx @modelcontextprotocol/inspector node packages/mp-mcp/dist/stdio.js

Generated types

src/generated/ is committed (so installs need no network) and generated from Parliament's OpenAPI specs. Regenerate with pnpm --filter @jamesmccomish/mp-mcp gen:types; never hand-edit those files.

Configuration

All configuration is via environment variables (all optional):

| Variable | Default | Purpose | | --- | --- | --- | | MP_MCP_LOG_LEVEL | info | pino level: fatal, error, warn, info, debug, trace, silent. | | MP_MCP_USER_AGENT_SUFFIX | (empty) | Appended to the outbound User-Agent on upstream calls. | | MP_MCP_UPSTREAM_TIMEOUT_MS | 4000 | Per-request upstream timeout (1000–30000). | | MP_MCP_UPSTREAM_MAX_ATTEMPTS | 2 | Upstream retry attempts (1–5). | | MP_MCP_UPSTREAM_BASE_BACKOFF_MS | 200 | Base backoff between retries (0–5000). | | MP_MCP_FIXTURE_DIR | ./fixtures | Fixture directory used by replay-based integration tests. |

Contributing

The tool surface is intentionally small — prefer extending an existing tool over adding one (see "Consolidate over multiply" in CLAUDE.md). When a new tool is genuinely warranted, scaffold it with the /new-tool command (.claude/commands/new-tool.md); it encodes the full contract — Zod schema, response_format toggle, citation envelope, registration, and snapshot test — so the pattern can't drift. Don't hand-roll one.

Data and licence

Data is provided under the Open Parliament Licence v3.0. When this MCP's output is surfaced to end users, attribute as:

Contains Parliamentary information licensed under the Open Parliament Licence v3.0.

The code is MIT licensed — see the repo root LICENSE.