uk-parliament-mcp 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uk_parliament_mcp-1.0.0/.github/workflows/ci.yml +38 -0
- uk_parliament_mcp-1.0.0/.github/workflows/publish.yml +47 -0
- uk_parliament_mcp-1.0.0/.gitignore +48 -0
- uk_parliament_mcp-1.0.0/.python-version +1 -0
- uk_parliament_mcp-1.0.0/AGENTS.md +73 -0
- uk_parliament_mcp-1.0.0/CLAUDE.md +160 -0
- uk_parliament_mcp-1.0.0/IMPLEMENTATION_PLAN.md +227 -0
- uk_parliament_mcp-1.0.0/PKG-INFO +379 -0
- uk_parliament_mcp-1.0.0/PROMPT_build.md +119 -0
- uk_parliament_mcp-1.0.0/PROMPT_plan.md +80 -0
- uk_parliament_mcp-1.0.0/README.md +355 -0
- uk_parliament_mcp-1.0.0/config/claude_desktop_config.json.example +9 -0
- uk_parliament_mcp-1.0.0/config/vscode_mcp_config.json.example +9 -0
- uk_parliament_mcp-1.0.0/context/bills-api.json +3355 -0
- uk_parliament_mcp-1.0.0/context/committees-api.json +6971 -0
- uk_parliament_mcp-1.0.0/context/commonsvotes-api.json +758 -0
- uk_parliament_mcp-1.0.0/context/erskinemay-api.json +1026 -0
- uk_parliament_mcp-1.0.0/context/hansard-api.json +4675 -0
- uk_parliament_mcp-1.0.0/context/interests-api.json +1000 -0
- uk_parliament_mcp-1.0.0/context/lordsvotes-api.json +833 -0
- uk_parliament_mcp-1.0.0/context/members-api.json +4896 -0
- uk_parliament_mcp-1.0.0/context/oralquestions-api.json +1585 -0
- uk_parliament_mcp-1.0.0/context/parliamentnow-api.json +432 -0
- uk_parliament_mcp-1.0.0/context/readme.md +67 -0
- uk_parliament_mcp-1.0.0/context/statutoryinstruments-api.json +2451 -0
- uk_parliament_mcp-1.0.0/context/treaties-api.json +801 -0
- uk_parliament_mcp-1.0.0/context/whatson-api.json +2077 -0
- uk_parliament_mcp-1.0.0/context/writtenquestions-api.json +1443 -0
- uk_parliament_mcp-1.0.0/loop.sh +53 -0
- uk_parliament_mcp-1.0.0/pyproject.toml +68 -0
- uk_parliament_mcp-1.0.0/specs/python-migration-spec.md +1059 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/__init__.py +3 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/__main__.py +22 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/http_client.py +159 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/server.py +42 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/__init__.py +1 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/bills.py +385 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/committees.py +385 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/commons_votes.py +138 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/core.py +28 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/erskine_may.py +25 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/hansard.py +39 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/interests.py +43 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/lords_votes.py +149 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/members.py +439 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/now.py +30 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/oral_questions.py +55 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/statutory_instruments.py +38 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/treaties.py +25 -0
- uk_parliament_mcp-1.0.0/src/uk_parliament_mcp/tools/whatson.py +72 -0
- uk_parliament_mcp-1.0.0/tests/__init__.py +1 -0
- uk_parliament_mcp-1.0.0/tests/conftest.py +21 -0
- uk_parliament_mcp-1.0.0/tests/test_http_client.py +224 -0
- uk_parliament_mcp-1.0.0/tests/test_tools/__init__.py +1 -0
- uk_parliament_mcp-1.0.0/tests/test_tools/test_core.py +87 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install -e ".[dev]"
|
|
28
|
+
|
|
29
|
+
- name: Lint with ruff
|
|
30
|
+
run: |
|
|
31
|
+
ruff check src/
|
|
32
|
+
ruff format --check src/
|
|
33
|
+
|
|
34
|
+
- name: Type check with mypy
|
|
35
|
+
run: mypy src/
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: pytest
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
|
|
13
|
+
- name: Set up Python
|
|
14
|
+
uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.11"
|
|
17
|
+
|
|
18
|
+
- name: Install build dependencies
|
|
19
|
+
run: |
|
|
20
|
+
python -m pip install --upgrade pip
|
|
21
|
+
pip install build
|
|
22
|
+
|
|
23
|
+
- name: Build package
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Upload build artifacts
|
|
27
|
+
uses: actions/upload-artifact@v4
|
|
28
|
+
with:
|
|
29
|
+
name: dist
|
|
30
|
+
path: dist/
|
|
31
|
+
|
|
32
|
+
publish:
|
|
33
|
+
needs: build
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
environment: pypi
|
|
36
|
+
permissions:
|
|
37
|
+
id-token: write # Required for Trusted Publishing
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- name: Download build artifacts
|
|
41
|
+
uses: actions/download-artifact@v4
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.venv/
|
|
25
|
+
venv/
|
|
26
|
+
ENV/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
*.swp
|
|
32
|
+
*.swo
|
|
33
|
+
|
|
34
|
+
# Testing
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
.coverage
|
|
37
|
+
htmlcov/
|
|
38
|
+
.tox/
|
|
39
|
+
.nox/
|
|
40
|
+
|
|
41
|
+
# Type checking
|
|
42
|
+
.mypy_cache/
|
|
43
|
+
|
|
44
|
+
# Linting
|
|
45
|
+
.ruff_cache/
|
|
46
|
+
|
|
47
|
+
# Local settings
|
|
48
|
+
.claude/settings.local.json
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# AGENTS.md - Operational Reference
|
|
2
|
+
|
|
3
|
+
## Project: UK Parliament MCP Server (Python Migration)
|
|
4
|
+
|
|
5
|
+
### Quick Reference
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Create virtual environment
|
|
9
|
+
uv venv
|
|
10
|
+
.venv\Scripts\activate # Windows
|
|
11
|
+
source .venv/bin/activate # Linux/Mac
|
|
12
|
+
|
|
13
|
+
# Install dependencies
|
|
14
|
+
uv pip install -e ".[dev]"
|
|
15
|
+
|
|
16
|
+
# Run MCP server
|
|
17
|
+
python -m uk_parliament_mcp
|
|
18
|
+
|
|
19
|
+
# Run tests
|
|
20
|
+
pytest
|
|
21
|
+
|
|
22
|
+
# Type checking
|
|
23
|
+
mypy src/
|
|
24
|
+
|
|
25
|
+
# Linting
|
|
26
|
+
ruff check src/
|
|
27
|
+
ruff format src/
|
|
28
|
+
|
|
29
|
+
# All checks (must pass before commit)
|
|
30
|
+
pytest && mypy src/ && ruff check src/
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Project Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
uk-parliament-mcp-lab/
|
|
37
|
+
├── specs/python-migration-spec.md # Migration specification
|
|
38
|
+
├── src/uk_parliament_mcp/ # Python package
|
|
39
|
+
│ ├── __main__.py # Entry point
|
|
40
|
+
│ ├── server.py # FastMCP setup
|
|
41
|
+
│ ├── http_client.py # HTTP with retry
|
|
42
|
+
│ └── tools/ # 14 tool modules
|
|
43
|
+
├── tests/ # pytest tests
|
|
44
|
+
├── context/ # API spec JSONs
|
|
45
|
+
└── OpenData.Mcp.Server/ # C# reference (DO NOT DELETE)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Key Conventions
|
|
49
|
+
|
|
50
|
+
- House IDs: 1 = Commons, 2 = Lords
|
|
51
|
+
- Date format: YYYY-MM-DD
|
|
52
|
+
- All tools are read-only and idempotent
|
|
53
|
+
- Tool response format: `{"url": "...", "data": "..."}` or `{"url": "...", "error": "...", "statusCode": N}`
|
|
54
|
+
|
|
55
|
+
### Tool Count Target
|
|
56
|
+
|
|
57
|
+
86 tools across 14 modules. Verify with:
|
|
58
|
+
```python
|
|
59
|
+
server = create_server()
|
|
60
|
+
assert len(list(server.list_tools())) == 86
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### C# Reference
|
|
64
|
+
|
|
65
|
+
Keep `OpenData.Mcp.Server/` as reference during migration. Only delete after all 86 tools verified working.
|
|
66
|
+
|
|
67
|
+
### Commit Format
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
feat: Add {module} tools ({count} tools)
|
|
71
|
+
fix: Correct {issue} in {module}
|
|
72
|
+
test: Add tests for {module}
|
|
73
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
UK Parliament MCP Server - A Model Context Protocol server that bridges AI assistants with official UK Parliament data APIs. Built with Python 3.11+, it provides 86 tools covering MPs/Lords, bills, votes, committees, Hansard, and more.
|
|
8
|
+
|
|
9
|
+
## Build Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Create virtual environment and install dependencies
|
|
13
|
+
python -m venv .venv
|
|
14
|
+
source .venv/bin/activate # Linux/Mac
|
|
15
|
+
# .venv\Scripts\activate # Windows
|
|
16
|
+
|
|
17
|
+
pip install -e ".[dev]"
|
|
18
|
+
|
|
19
|
+
# Run the MCP server (stdio transport)
|
|
20
|
+
python -m uk_parliament_mcp
|
|
21
|
+
|
|
22
|
+
# Run tests
|
|
23
|
+
pytest
|
|
24
|
+
|
|
25
|
+
# Type checking
|
|
26
|
+
mypy src/
|
|
27
|
+
|
|
28
|
+
# Linting
|
|
29
|
+
ruff check src/
|
|
30
|
+
ruff format src/
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Architecture
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
AI Assistant ──(MCP/stdio)──> uk_parliament_mcp ──(HTTP)──> UK Parliament APIs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Key Components:**
|
|
40
|
+
|
|
41
|
+
- **`__main__.py`**: Entry point. Configures logging to stderr (stdout reserved for MCP protocol), creates and runs the FastMCP server.
|
|
42
|
+
|
|
43
|
+
- **`server.py`**: FastMCP server setup. Creates the MCP server and registers all tool modules.
|
|
44
|
+
|
|
45
|
+
- **`http_client.py`**: HTTP client with retry logic. Provides:
|
|
46
|
+
- HTTP request handling with 3-retry exponential backoff
|
|
47
|
+
- 30-second timeout protection
|
|
48
|
+
- URL building with parameter filtering (`build_url`)
|
|
49
|
+
- Consistent response format: `{url, data}` or `{url, error, statusCode}`
|
|
50
|
+
|
|
51
|
+
- **`tools/*.py`**: 14 tool modules (86 total tools) each targeting a specific Parliament API:
|
|
52
|
+
| Module | API Domain | Purpose |
|
|
53
|
+
|--------|------------|---------|
|
|
54
|
+
| members.py | members-api.parliament.uk | MPs, Lords, constituencies, parties |
|
|
55
|
+
| bills.py | bills-api.parliament.uk | Legislation, amendments, stages |
|
|
56
|
+
| commons_votes.py | commonsvotes-api.parliament.uk | Commons divisions |
|
|
57
|
+
| lords_votes.py | lordsvotes-api.parliament.uk | Lords divisions |
|
|
58
|
+
| committees.py | committees-api.parliament.uk | Committee info, evidence |
|
|
59
|
+
| hansard.py | hansard-api.parliament.uk | Parliamentary record |
|
|
60
|
+
| oral_questions.py | oralquestionsandmotions-api.parliament.uk | EDMs, questions |
|
|
61
|
+
| interests.py | interests-api.parliament.uk | Register of interests |
|
|
62
|
+
| now.py | now-api.parliament.uk | Live chamber activity |
|
|
63
|
+
| whatson.py | whatson-api.parliament.uk | Calendar, sessions |
|
|
64
|
+
| statutory_instruments.py | statutoryinstruments-api.parliament.uk | Acts, SIs |
|
|
65
|
+
| treaties.py | treaties-api.parliament.uk | International treaties |
|
|
66
|
+
| erskine_may.py | erskinemay-api.parliament.uk | Procedure rules |
|
|
67
|
+
| core.py | N/A | Session management prompts |
|
|
68
|
+
|
|
69
|
+
- **`context/`**: OpenAPI spec JSON files for each Parliament API (reference documentation)
|
|
70
|
+
|
|
71
|
+
## Adding New Tools
|
|
72
|
+
|
|
73
|
+
Follow the established pattern in any `tools/*.py` file:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
"""New API tools for [description]."""
|
|
77
|
+
from urllib.parse import quote
|
|
78
|
+
|
|
79
|
+
from mcp.server.fastmcp import FastMCP
|
|
80
|
+
|
|
81
|
+
from uk_parliament_mcp.http_client import build_url, get_result
|
|
82
|
+
|
|
83
|
+
NEW_API_BASE = "https://api.parliament.uk"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def register_tools(mcp: FastMCP) -> None:
|
|
87
|
+
"""Register new tools with the MCP server."""
|
|
88
|
+
|
|
89
|
+
@mcp.tool()
|
|
90
|
+
async def get_something(param: str) -> str:
|
|
91
|
+
"""Action | keywords, synonyms | Use case | Returns format
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
param: Description of the parameter.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Description of what is returned.
|
|
98
|
+
"""
|
|
99
|
+
url = f"{NEW_API_BASE}/endpoint?param={quote(param)}"
|
|
100
|
+
return await get_result(url)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Tool descriptions use a 4-part semantic format: `Action | Keywords | Use case | Returns`
|
|
104
|
+
|
|
105
|
+
Then register in `server.py`:
|
|
106
|
+
```python
|
|
107
|
+
from uk_parliament_mcp.tools import new_api
|
|
108
|
+
# ...
|
|
109
|
+
new_api.register_tools(mcp)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Key Conventions
|
|
113
|
+
|
|
114
|
+
- **House IDs**: 1 = Commons, 2 = Lords
|
|
115
|
+
- **Date format**: YYYY-MM-DD throughout
|
|
116
|
+
- **Pagination**: `skip`/`take` parameters where supported
|
|
117
|
+
- All tools are read-only and idempotent
|
|
118
|
+
- Raw JSON responses from Parliament APIs are passed through (not transformed)
|
|
119
|
+
- Use `build_url(base, params)` for URL construction with parameter filtering
|
|
120
|
+
- Use `await get_result(url)` for HTTP requests with retry logic
|
|
121
|
+
|
|
122
|
+
## Dependencies
|
|
123
|
+
|
|
124
|
+
- mcp (>=1.0.0) - Anthropic's official MCP library
|
|
125
|
+
- httpx (>=0.27.0) - Async HTTP client
|
|
126
|
+
- tenacity (>=8.2.0) - Retry logic (available but manual retry used)
|
|
127
|
+
|
|
128
|
+
### Dev Dependencies
|
|
129
|
+
|
|
130
|
+
- pytest (>=8.0.0) - Testing
|
|
131
|
+
- pytest-asyncio (>=0.23.0) - Async test support
|
|
132
|
+
- pytest-httpx (>=0.30.0) - HTTP mocking
|
|
133
|
+
- ruff (>=0.3.0) - Linting and formatting
|
|
134
|
+
- mypy (>=1.8.0) - Type checking
|
|
135
|
+
|
|
136
|
+
## Project Structure
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
src/uk_parliament_mcp/
|
|
140
|
+
├── __init__.py
|
|
141
|
+
├── __main__.py # Entry point
|
|
142
|
+
├── server.py # FastMCP server setup
|
|
143
|
+
├── http_client.py # HTTP client with retry
|
|
144
|
+
└── tools/
|
|
145
|
+
├── __init__.py
|
|
146
|
+
├── core.py # Session management (2 tools)
|
|
147
|
+
├── members.py # Member tools (25 tools)
|
|
148
|
+
├── bills.py # Bills tools (21 tools)
|
|
149
|
+
├── committees.py # Committees tools (12 tools)
|
|
150
|
+
├── commons_votes.py # Commons votes (5 tools)
|
|
151
|
+
├── lords_votes.py # Lords votes (5 tools)
|
|
152
|
+
├── hansard.py # Hansard (1 tool)
|
|
153
|
+
├── oral_questions.py # Questions (3 tools)
|
|
154
|
+
├── interests.py # Interests (3 tools)
|
|
155
|
+
├── now.py # Live activity (2 tools)
|
|
156
|
+
├── whatson.py # Calendar (3 tools)
|
|
157
|
+
├── statutory_instruments.py # SIs (2 tools)
|
|
158
|
+
├── treaties.py # Treaties (1 tool)
|
|
159
|
+
└── erskine_may.py # Procedure (1 tool)
|
|
160
|
+
```
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Implementation Plan
|
|
2
|
+
|
|
3
|
+
> Generated by Ralph Wiggum planning phase
|
|
4
|
+
|
|
5
|
+
## Status Summary
|
|
6
|
+
|
|
7
|
+
- **Total tools required:** 86
|
|
8
|
+
- **Tools implemented:** 86
|
|
9
|
+
- **Core infrastructure:** COMPLETE
|
|
10
|
+
- **Python files exist:** YES
|
|
11
|
+
|
|
12
|
+
## Priority 1: Project Setup
|
|
13
|
+
|
|
14
|
+
- [x] Create `pyproject.toml` with dependencies (mcp, httpx, tenacity, pytest, ruff, mypy)
|
|
15
|
+
- [x] Create `.python-version` file (3.11)
|
|
16
|
+
- [x] Create `src/uk_parliament_mcp/__init__.py`
|
|
17
|
+
- [x] Create `src/uk_parliament_mcp/tools/__init__.py`
|
|
18
|
+
|
|
19
|
+
## Priority 2: Core Infrastructure
|
|
20
|
+
|
|
21
|
+
- [x] Create `src/uk_parliament_mcp/http_client.py` - HTTP client with retry logic
|
|
22
|
+
- [x] Create `src/uk_parliament_mcp/server.py` - FastMCP server setup
|
|
23
|
+
- [x] Create `src/uk_parliament_mcp/__main__.py` - Entry point
|
|
24
|
+
- [x] Verify server starts: `python -m uk_parliament_mcp`
|
|
25
|
+
|
|
26
|
+
## Priority 3: Core Tools (2 tools)
|
|
27
|
+
|
|
28
|
+
- [x] `tools/core.py` - hello_parliament
|
|
29
|
+
- [x] `tools/core.py` - goodbye_parliament
|
|
30
|
+
|
|
31
|
+
## Priority 4: Members Tools (25 tools)
|
|
32
|
+
|
|
33
|
+
- [x] `tools/members.py` - get_member_by_name
|
|
34
|
+
- [x] `tools/members.py` - get_answering_bodies
|
|
35
|
+
- [x] `tools/members.py` - get_member_by_id
|
|
36
|
+
- [x] `tools/members.py` - edms_for_member_id
|
|
37
|
+
- [x] `tools/members.py` - parties_list_by_house
|
|
38
|
+
- [x] `tools/members.py` - get_departments
|
|
39
|
+
- [x] `tools/members.py` - get_contributions
|
|
40
|
+
- [x] `tools/members.py` - get_constituencies
|
|
41
|
+
- [x] `tools/members.py` - get_election_results_for_constituency
|
|
42
|
+
- [x] `tools/members.py` - get_lords_interests_staff
|
|
43
|
+
- [x] `tools/members.py` - get_members_biography
|
|
44
|
+
- [x] `tools/members.py` - get_members_contact
|
|
45
|
+
- [x] `tools/members.py` - search_members
|
|
46
|
+
- [x] `tools/members.py` - search_members_historical
|
|
47
|
+
- [x] `tools/members.py` - get_member_experience
|
|
48
|
+
- [x] `tools/members.py` - get_member_focus
|
|
49
|
+
- [x] `tools/members.py` - get_member_registered_interests
|
|
50
|
+
- [x] `tools/members.py` - get_member_staff
|
|
51
|
+
- [x] `tools/members.py` - get_member_synopsis
|
|
52
|
+
- [x] `tools/members.py` - get_member_voting
|
|
53
|
+
- [x] `tools/members.py` - get_member_written_questions
|
|
54
|
+
- [x] `tools/members.py` - get_members_history
|
|
55
|
+
- [x] `tools/members.py` - get_member_latest_election_result
|
|
56
|
+
- [x] `tools/members.py` - get_member_portrait_url
|
|
57
|
+
- [x] `tools/members.py` - get_member_thumbnail_url
|
|
58
|
+
|
|
59
|
+
## Priority 5: Bills Tools (21 tools)
|
|
60
|
+
|
|
61
|
+
- [x] `tools/bills.py` - get_recently_updated_bills
|
|
62
|
+
- [x] `tools/bills.py` - search_bills
|
|
63
|
+
- [x] `tools/bills.py` - bill_types
|
|
64
|
+
- [x] `tools/bills.py` - bill_stages
|
|
65
|
+
- [x] `tools/bills.py` - get_bill_by_id
|
|
66
|
+
- [x] `tools/bills.py` - get_bill_stages
|
|
67
|
+
- [x] `tools/bills.py` - get_bill_stage_details
|
|
68
|
+
- [x] `tools/bills.py` - get_bill_stage_amendments
|
|
69
|
+
- [x] `tools/bills.py` - get_amendment_by_id
|
|
70
|
+
- [x] `tools/bills.py` - get_bill_stage_ping_pong_items
|
|
71
|
+
- [x] `tools/bills.py` - get_ping_pong_item_by_id
|
|
72
|
+
- [x] `tools/bills.py` - get_bill_publications
|
|
73
|
+
- [x] `tools/bills.py` - get_bill_stage_publications
|
|
74
|
+
- [x] `tools/bills.py` - get_publication_document
|
|
75
|
+
- [x] `tools/bills.py` - get_bill_news_articles
|
|
76
|
+
- [x] `tools/bills.py` - get_all_bills_rss
|
|
77
|
+
- [x] `tools/bills.py` - get_public_bills_rss
|
|
78
|
+
- [x] `tools/bills.py` - get_private_bills_rss
|
|
79
|
+
- [x] `tools/bills.py` - get_bill_rss
|
|
80
|
+
- [x] `tools/bills.py` - get_publication_types
|
|
81
|
+
- [x] `tools/bills.py` - get_sittings
|
|
82
|
+
|
|
83
|
+
## Priority 6: Committees Tools (12 tools)
|
|
84
|
+
|
|
85
|
+
- [x] `tools/committees.py` - get_committee_meetings
|
|
86
|
+
- [x] `tools/committees.py` - search_committees
|
|
87
|
+
- [x] `tools/committees.py` - get_committee_types
|
|
88
|
+
- [x] `tools/committees.py` - get_committee_by_id
|
|
89
|
+
- [x] `tools/committees.py` - get_events
|
|
90
|
+
- [x] `tools/committees.py` - get_event_by_id
|
|
91
|
+
- [x] `tools/committees.py` - get_committee_events
|
|
92
|
+
- [x] `tools/committees.py` - get_committee_members
|
|
93
|
+
- [x] `tools/committees.py` - get_publications
|
|
94
|
+
- [x] `tools/committees.py` - get_publication_by_id
|
|
95
|
+
- [x] `tools/committees.py` - get_written_evidence
|
|
96
|
+
- [x] `tools/committees.py` - get_oral_evidence
|
|
97
|
+
|
|
98
|
+
## Priority 7: Commons Votes Tools (5 tools)
|
|
99
|
+
|
|
100
|
+
- [x] `tools/commons_votes.py` - search_commons_divisions
|
|
101
|
+
- [x] `tools/commons_votes.py` - get_commons_voting_record_for_member
|
|
102
|
+
- [x] `tools/commons_votes.py` - get_commons_division_by_id
|
|
103
|
+
- [x] `tools/commons_votes.py` - get_commons_divisions_grouped_by_party
|
|
104
|
+
- [x] `tools/commons_votes.py` - get_commons_divisions_search_count
|
|
105
|
+
|
|
106
|
+
## Priority 8: Lords Votes Tools (5 tools)
|
|
107
|
+
|
|
108
|
+
- [x] `tools/lords_votes.py` - search_lords_divisions
|
|
109
|
+
- [x] `tools/lords_votes.py` - get_lords_voting_record_for_member
|
|
110
|
+
- [x] `tools/lords_votes.py` - get_lords_division_by_id
|
|
111
|
+
- [x] `tools/lords_votes.py` - get_lords_divisions_grouped_by_party
|
|
112
|
+
- [x] `tools/lords_votes.py` - get_lords_divisions_search_count
|
|
113
|
+
|
|
114
|
+
## Priority 9: Hansard Tools (1 tool)
|
|
115
|
+
|
|
116
|
+
- [x] `tools/hansard.py` - search_hansard
|
|
117
|
+
|
|
118
|
+
## Priority 10: Oral Questions Tools (3 tools)
|
|
119
|
+
|
|
120
|
+
- [x] `tools/oral_questions.py` - get_recently_tabled_edms
|
|
121
|
+
- [x] `tools/oral_questions.py` - search_early_day_motions
|
|
122
|
+
- [x] `tools/oral_questions.py` - search_oral_question_times
|
|
123
|
+
|
|
124
|
+
## Priority 11: Interests Tools (3 tools)
|
|
125
|
+
|
|
126
|
+
- [x] `tools/interests.py` - search_roi
|
|
127
|
+
- [x] `tools/interests.py` - interests_categories
|
|
128
|
+
- [x] `tools/interests.py` - get_registers_of_interests
|
|
129
|
+
|
|
130
|
+
## Priority 12: Now Tools (2 tools)
|
|
131
|
+
|
|
132
|
+
- [x] `tools/now.py` - happening_now_in_commons
|
|
133
|
+
- [x] `tools/now.py` - happening_now_in_lords
|
|
134
|
+
|
|
135
|
+
## Priority 13: Whats On Tools (3 tools)
|
|
136
|
+
|
|
137
|
+
- [x] `tools/whatson.py` - search_calendar
|
|
138
|
+
- [x] `tools/whatson.py` - get_sessions
|
|
139
|
+
- [x] `tools/whatson.py` - get_non_sitting_days
|
|
140
|
+
|
|
141
|
+
## Priority 14: Statutory Instruments Tools (2 tools)
|
|
142
|
+
|
|
143
|
+
- [x] `tools/statutory_instruments.py` - search_statutory_instruments
|
|
144
|
+
- [x] `tools/statutory_instruments.py` - search_acts_of_parliament
|
|
145
|
+
|
|
146
|
+
## Priority 15: Treaties Tools (1 tool)
|
|
147
|
+
|
|
148
|
+
- [x] `tools/treaties.py` - search_treaties
|
|
149
|
+
|
|
150
|
+
## Priority 16: Erskine May Tools (1 tool)
|
|
151
|
+
|
|
152
|
+
- [x] `tools/erskine_may.py` - search_erskine_may
|
|
153
|
+
|
|
154
|
+
## Priority 17: Testing
|
|
155
|
+
|
|
156
|
+
- [x] Create `tests/__init__.py`
|
|
157
|
+
- [x] Create `tests/conftest.py` - pytest fixtures
|
|
158
|
+
- [x] Create `tests/test_http_client.py` - HTTP client unit tests
|
|
159
|
+
- [x] Create `tests/test_tools/__init__.py`
|
|
160
|
+
- [x] Create `tests/test_tools/test_core.py`
|
|
161
|
+
- [x] Run `pytest` - all 24 tests pass
|
|
162
|
+
- [x] Run `mypy src/` - type checking passes (no issues in 19 files)
|
|
163
|
+
- [x] Run `ruff check src/` - linting passes
|
|
164
|
+
- [x] Verified all Python syntax via ast.parse() (19 source files, 5 test files)
|
|
165
|
+
|
|
166
|
+
## Priority 18: Documentation & Config
|
|
167
|
+
|
|
168
|
+
- [x] Update `CLAUDE.md` for Python development
|
|
169
|
+
- [x] Update `README.md` for Python installation
|
|
170
|
+
- [x] Create `config/claude_desktop_config.json.example`
|
|
171
|
+
- [x] Create `config/vscode_mcp_config.json.example`
|
|
172
|
+
|
|
173
|
+
## Priority 19: Final Verification
|
|
174
|
+
|
|
175
|
+
- [x] Server starts: `python -m uk_parliament_mcp`
|
|
176
|
+
- [x] Verify 86 tools registered
|
|
177
|
+
- [x] Test `hello_parliament` returns system prompt
|
|
178
|
+
- [x] Test `get_member_by_name("Keir Starmer")` returns valid JSON (Sir Keir Starmer, Labour)
|
|
179
|
+
- [x] Test `search_bills("climate")` returns valid JSON (20 bills found)
|
|
180
|
+
- [ ] Configure Claude Desktop and verify working
|
|
181
|
+
|
|
182
|
+
## Priority 20: Cleanup (ONLY after verification)
|
|
183
|
+
|
|
184
|
+
- [x] Delete `OpenData.Mcp.Server/` folder
|
|
185
|
+
- [x] Delete `OpenDataMcpServer.sln`
|
|
186
|
+
- [ ] Final commit with Python-only project
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Task Count Summary
|
|
191
|
+
|
|
192
|
+
| Priority | Category | Tasks | Status |
|
|
193
|
+
|----------|----------|-------|--------|
|
|
194
|
+
| 1 | Project Setup | 4 | COMPLETE |
|
|
195
|
+
| 2 | Core Infrastructure | 4 | COMPLETE |
|
|
196
|
+
| 3 | Core Tools | 2 | COMPLETE |
|
|
197
|
+
| 4 | Members Tools | 25 | COMPLETE |
|
|
198
|
+
| 5 | Bills Tools | 21 | COMPLETE |
|
|
199
|
+
| 6 | Committees Tools | 12 | COMPLETE |
|
|
200
|
+
| 7 | Commons Votes Tools | 5 | COMPLETE |
|
|
201
|
+
| 8 | Lords Votes Tools | 5 | COMPLETE |
|
|
202
|
+
| 9 | Hansard Tools | 1 | COMPLETE |
|
|
203
|
+
| 10 | Oral Questions Tools | 3 | COMPLETE |
|
|
204
|
+
| 11 | Interests Tools | 3 | COMPLETE |
|
|
205
|
+
| 12 | Now Tools | 2 | COMPLETE |
|
|
206
|
+
| 13 | Whats On Tools | 3 | COMPLETE |
|
|
207
|
+
| 14 | Statutory Instruments Tools | 2 | COMPLETE |
|
|
208
|
+
| 15 | Treaties Tools | 1 | COMPLETE |
|
|
209
|
+
| 16 | Erskine May Tools | 1 | COMPLETE |
|
|
210
|
+
| 17 | Testing | 8 | COMPLETE |
|
|
211
|
+
| 18 | Documentation | 4 | COMPLETE |
|
|
212
|
+
| 19 | Verification | 6 | 5/6 (Claude Desktop pending) |
|
|
213
|
+
| 20 | Cleanup | 3 | 2/3 (commit pending) |
|
|
214
|
+
| **Total** | | **114** | |
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Next Action
|
|
219
|
+
|
|
220
|
+
1. **Configure Claude Desktop** and verify MCP server works end-to-end
|
|
221
|
+
2. **Priority 20: Cleanup** - Delete old C# files after verification
|
|
222
|
+
|
|
223
|
+
## Reference Files
|
|
224
|
+
|
|
225
|
+
- Migration spec: `specs/python-migration-spec.md`
|
|
226
|
+
- C# reference: `OpenData.Mcp.Server/Tools/*.cs`
|
|
227
|
+
- Operational guide: `AGENTS.md`
|