jadu/modgov-mcp-server
If you are the rightful owner of modgov-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
The Modgov MCP Server is a comprehensive Model Context Protocol server that provides access to modgov council APIs for retrieving councillor information, committee details, meeting schedules, election results, and parish council data across UK local councils.
Modgov MCP Server
A comprehensive Model Context Protocol (MCP) server that provides access to modgov council APIs for retrieving councillor information, committee details, meeting schedules, election results, and parish council data across UK local councils.
Table of Contents
- Quick Start
- Features
- Critical Server Bug Workarounds
- Testing
- Documentation
- Installation
- MCP Transport Options
- Usage
- Available Tools
- Tool Usage Examples
- Response Format
- Rate Limiting
- Error Handling
- Development
- Docker Configuration
- Architecture
- Supported Council Sites
- API Discovery
- Examples
- Best Practices
- Error Handling Examples
- Contributing
- License
Quick Start
Prerequisites
- Node.js (version 18+)
- Docker & Docker Compose (for production deployment)
Build & Run
-
Clone and Build:
git clone <repository-url> cd modgov-mcp-server npm install npm run build -
Run with STDIO transport:
node dist/index.js -
Run with HTTP transport:
MCP_TRANSPORT=http node dist/index.js # Server available at: http://localhost:3003/mcp -
Test with MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.js
Docker Deployment
For production deployment, use Docker:
# Build and run
make build && make up
# Server available at: http://localhost:3003/mcp
# Health check: http://localhost:3003/health
Features
- 100% Success Rate: 9/9 endpoints fully functional with automatic server bug workarounds
- Complete API Coverage: All major ModGov endpoints (councillors, committees, meetings, elections, etc.)
- Multi-site support: Tested across 3 UK council sites (Lichfield, Kirklees, Liverpool)
- Server Bug Handling: Automatic workarounds for WSDL vs actual server discrepancies
- Flexible querying: Multiple ways to access council data (by ward, committee, date, etc.)
- Rate limiting: Built-in rate limiting (1 request/second per domain) to prevent API abuse
- Error handling: Robust error handling with meaningful error messages
- Council lookup: Smart fuzzy matching to find councils by name or region
🚨 Critical Server Bug Workarounds
Major discrepancies exist between official WSDL documentation and actual ModGov server implementations. This MCP server automatically handles these issues:
Parameter Requirements Mismatch
Many parameters marked as "optional" in WSDL are actually required by servers:
| Endpoint | WSDL Shows Optional | Actually Required |
|---|---|---|
GetMeetings | sFromDate, sToDate | ✅ REQUIRED |
GetAllMeetingsByDate | lCommitteeId, bIsAscendingDateOrder | ✅ REQUIRED |
GetCalendarEvents | bGlobalCalendar, lUserId | ✅ REQUIRED |
GetWebCastMeetings | lCommitteeId, sFromDate, sToDate | ✅ REQUIRED |
GetElectionResults | lElectionId | ✅ REQUIRED |
GetMpOrMepsAndWards | bIsMPs | ✅ REQUIRED |
Automatic Workarounds Applied
The MCP server transparently applies these fixes:
- Missing dates: Defaults to current year range (
YYYY-01-01toYYYY-12-31) - Missing committee IDs: Defaults to Cabinet (138)
- Missing boolean flags: Provides sensible defaults (
truefor global calendar, etc.) - Missing user IDs: Defaults to 0 for public access
Testing Results
| Council | Working Endpoints | Success Rate |
|---|---|---|
| Lichfield DC | 9/9 | 100% |
| Kirklees | 9/9 | 100% |
| Liverpool | 9/9 | 100% |
All tested sites exhibit identical server bugs and all are handled automatically.
🧪 Testing
Test Structure
tests/
├── integration/ # End-to-end integration tests
├── debugging/ # Debug and investigation scripts
├── utils/ # Utility test scripts
└── README.md # Test documentation
Running Tests
Unit Tests (in Docker)
# Run Jest unit tests in Docker container
make test
# Or use Docker Compose directly
docker-compose run --rm modgov-mcp-server npm test
Integration Tests (in Docker)
# Test all 9 endpoints end-to-end in Docker
docker-compose run --rm modgov-mcp-server npm run test:integration
Debug Tests (in Docker)
# Investigate endpoint compatibility across sites
docker-compose run --rm modgov-mcp-server npm run test:debug
# Verify parameter handling
docker-compose run --rm modgov-mcp-server npm run test:params
Test Results
- ✅ 100% Success Rate: 9/9 endpoints working
- ✅ Server Bug Workarounds: All WSDL discrepancies handled automatically
- ✅ Cross-Site Compatibility: Tested across 3 council sites
📚 Documentation
OpenAPI/Swagger Specification
- File:
modgov-openapi-spec.yaml - Status: ✅ Complete and Authoritative
- Coverage: All 9 supported endpoints with real-world examples
- Features:
- Server bug workarounds clearly documented
- Request/response examples
- Parameter validation rules
- Cross-site compatibility notes
Developer Resources
- Robustness Report:
MCP_ROBUSTNESS_REPORT.md- Testing and performance details - Test Documentation:
tests/README.md- Complete test suite guide - Implementation Notes: Server bug workarounds and best practices (see sections above)
Installation
Native Node.js (Recommended for Development)
# Clone and install
git clone <repository-url>
cd modgov-mcp-server
npm install
npm run build
# Run with STDIO transport (default)
node dist/index.js
# Run with HTTP transport
MCP_TRANSPORT=http node dist/index.js
Docker (Recommended for Production)
# Using Makefile (recommended)
make build && make up
# Or using Docker Compose directly
docker-compose up --build
Available Make Commands:
make build- Build production imagemake up- Start production containermake test- Run tests in containermake logs- View container logsmake clean- Remove containers and imagesmake shell- Open shell in container for debugging
MCP Transport Options
The Modgov MCP Server supports both STDIO and HTTP transports:
STDIO Transport (Default)
Perfect for development and MCP client integration:
# Start with STDIO transport
node dist/index.js
# Test with MCP Inspector
npx @modelcontextprotocol/inspector node dist/index.js
STDIO transport characteristics:
- Default transport mode
- Interactive stdin/stdout communication
- Perfect for MCP clients (Claude Desktop, Cursor, etc.)
- Terminates after client disconnects
HTTP Transport (Streamable)
Ideal for web services and API integration:
# Start with HTTP transport
MCP_TRANSPORT=http node dist/index.js
# Or with custom port
MCP_TRANSPORT=http MCP_PORT=3005 node dist/index.js
HTTP transport endpoints:
- MCP Protocol:
http://localhost:3003/mcp - Health Check:
http://localhost:3003/health
HTTP transport characteristics:
- Runs as persistent web server
- RESTful MCP protocol over HTTP
- Supports streaming responses
- Built-in health monitoring
MCP Inspector
Test your server with the official MCP Inspector:
# For STDIO transport (default)
npx @modelcontextprotocol/inspector node dist/index.js
# For HTTP transport
npx @modelcontextprotocol/inspector http://localhost:3003/mcp
The inspector provides:
- ✅ Interactive tool testing
- ✅ Protocol validation
- ✅ Request/response debugging
- ✅ Schema verification
Usage
Docker (Production)
Production with HTTP Transport
# Build and run production container
make build && make up
# Or using Docker Compose directly
docker-compose up --build modgov-mcp-server
The server automatically starts in HTTP mode on port 3003 when the container starts.
HTTP API Endpoints
The MCP server runs in Docker and exposes these endpoints on port 3003:
MCP Protocol Endpoint
POST http://localhost:3003/mcp
Content-Type: application/json
# Example request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_councillors",
"arguments": {
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL"
}
}
}
Health Check Endpoint
GET http://localhost:3003/health
# Response
{
"status": "healthy",
"timestamp": "2025-01-11T10:20:30.000Z",
"server": "modgov-mcp-server",
"version": "1.0.0",
"transport": "streamable-http"
}
Docker Logging
The MCP server includes comprehensive logging for all tool calls when running in Docker:
# View real-time logs
docker logs modgov-mcp-server --follow
# View recent logs
docker logs modgov-mcp-server --tail 20
Example Log Output:
🛠️ Tool called: get_councillors_by_ward
📍 Parameters: site_url=https://democracy.lichfielddc.gov.uk/mgWebService.asmx
✅ Tool completed: get_councillors_by_ward (1280ms)
🛠️ Tool called: get_committees
📍 Parameters: site_url=https://democracy.lichfielddc.gov.uk/mgWebService.asmx
✅ Tool completed: get_committees (320ms)
Each tool call logs:
- 🔧 Tool initiation with emoji and tool name
- 📍 Parameters passed to the tool
- ✅ Completion with execution time in milliseconds
The MCP server runs at http://localhost:3003/mcp and supports the full MCP protocol for testing all registered tools.
Port Conflict Solutions: If you encounter port conflicts:
# Stop all containers
make down
# Or manually kill processes on ports 3003, 6274, 6277
lsof -ti:3003,6274,6277 | xargs kill -9 2>/dev/null || true
Stopping the Server:
# Stop the Docker container
make down
# Or use Docker Compose directly
docker-compose down
Troubleshooting:
- Check container logs:
make logs - Verify container is running:
docker ps - Test health endpoint:
curl http://localhost:3003/health
Available Tools
The MCP server exposes 18 tools for querying modgov council APIs and finding councils:
✅ Councillor Information (No Workarounds Needed)
get_councillors_by_ward- Get all councillors organized by ward with photos and political affiliationsget_councillors_by_ward_id- Get councillors for a specific ward IDget_councillors_by_postcode- Get councillors for a specific postcodeget_councillor_details- Get comprehensive councillor profiles including surgery times and contact details
✅ Governance & Committees (Automatic Workarounds Applied)
get_committees- Get all committees (Cabinet, Council, Planning, etc.)get_meetings- Get meetings with automatic date range defaults ⚙️get_meeting- Get details for a specific meeting by IDget_all_meetings_by_date- Get meetings for specific date with committee defaults ⚙️
✅ Events & Calendar (Automatic Workarounds Applied)
get_calendar_events- Get calendar events with automatic parameter handling ⚙️
✅ Local Government Structure (No Workarounds Needed)
get_parish_councils- Get parish councils and their information
✅ Elections & Democracy (Automatic Workarounds Applied)
get_election_results- Get election results with required election ID ⚙️
✅ Digital Services (Automatic Workarounds Applied)
get_webcast_meetings- Get webcast meetings with date and committee defaults ⚙️get_mp_or_meps_and_wards- Get MP/MEP information with boolean flag handling ⚙️get_mp_or_mep_and_wards_by_postcode- Get MP/MEP info for specific postcode ⚙️
✅ Council Discovery & Management
find_council- Find a council by name using fuzzy matchingsearch_councils- Search councils with confidence thresholdsget_council_by_region- Get all councils in a specific regionget_server_diagnostics- Get server diagnostic information
⚙️ Automatic server bug workarounds applied | ✅ All tools tested and working
Tool Usage Examples
All tools require a site_url parameter pointing to the council's modgov API endpoint.
Councillor Information
Get all councillors by ward:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL"
}
Get councillors for a specific ward:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL",
"ward_id": 1
}
Get councillors by postcode:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL",
"postcode": "WS14 9AB"
}
Governance & Committees
Get all committees:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL"
}
Get meetings for a specific committee:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL",
"committee_id": 1
}
Get a specific meeting by ID:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL",
"meeting_id": 123
}
Local Government Structure
Get parish councils:
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL"
}
## Response Format
The tool returns JSON data with the following structure:
```json
{
"site_url": "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL",
"total_wards": 25,
"total_councillors": 47,
"wards": [
{
"ward_name": "Alrewas and Fradley",
"councillor_count": "3",
"councillors": [
{
"id": "570",
"name": "Councillor Sonia Claverley",
"party": "The Conservative Party",
"group": "Conservative Group",
"district": "Lichfield District Council",
"representing": "Lichfield District Council",
"photos": {
"small": "https://democracy.lichfielddc.gov.uk/UserData/0/7/5/Info00000570/smallpic.jpg",
"large": "https://democracy.lichfielddc.gov.uk/UserData/0/7/5/Info00000570/bigpic.jpg"
},
"additional_info": "...",
"key_posts": "..."
}
]
}
]
}
Rate Limiting
The server implements rate limiting of 1 request per second per domain to prevent abuse and respect API limits.
Error Handling
The server provides comprehensive error handling:
- Network errors: Connection timeouts, DNS resolution failures
- API errors: Invalid responses, malformed XML
- Rate limiting: Automatic retry with exponential backoff
- Validation errors: Invalid parameters, missing required fields
Development
Development Environment
All development happens within Docker containers:
# Start development environment with live code mounting
make dev
# This mounts your source code and provides hot reloading
Running Tests
Unit Tests (in Docker)
# Run Jest unit tests in development container
make test
# Or run tests in watch mode for development
docker-compose --profile dev exec modgov-mcp-dev npm run test:watch
Integration Tests (in Docker)
Test the full MCP server functionality with real API calls:
# Start development environment (Terminal 1)
make dev
# Run integration tests (Terminal 2)
docker-compose --profile dev exec modgov-mcp-dev npm run test:mcp
The integration tests include:
- Health endpoint validation
- MCP protocol compliance
- Tool discovery and execution
- Council data retrieval and validation
See for detailed testing documentation.
Building
The build process happens automatically in the Docker container:
# Manual build in container
docker-compose --profile dev exec modgov-mcp-dev npm run build
Stopping Development Environment
# Stop development containers
make down
This stops all development containers and cleans up resources.
Docker Configuration
Production Container
The production container is optimized for deployment:
docker build -t modgov-mcp-server .
docker run -p 3003:3003 modgov-mcp-server
Features:
- Multi-stage build for minimal image size
- Non-root user for security
- Health checks
- Only production dependencies
- Always runs on port 3003 with HTTP transport
Testing Docker Setup
Verify your Docker container works:
# Build and test
make build
make up
# Check health endpoint
curl http://localhost:3003/health
Expected health response:
{
"status": "healthy",
"timestamp": "2025-01-11T10:20:30.000Z",
"server": "modgov-mcp-server",
"version": "1.0.0",
"transport": "streamable-http"
}
MCP Server Behavior
Important: The MCP server runs continuously in HTTP mode inside the Docker container. This is different from stdio mode where servers exit after each request.
- The server stays running and listens on port 3003
- Each MCP request is handled over HTTP
- The container will show as
running(not exited) - Use
make logsto monitor the server output
Architecture
The server consists of three main components:
- ModgovClient: Handles HTTP requests to modgov APIs, XML parsing, and rate limiting
- ModgovServer: MCP server implementation with tool registration and request handling
- Type Definitions: TypeScript interfaces for API responses and data structures
Supported Council Sites
The server works with any modgov-enabled council website. Our database includes 44 verified councils across all UK regions.
Complete Council Database
| Council | Region | Type | URL |
|---|---|---|---|
| Bath and North East Somerset Council | South West | Unitary Authority | https://democracy.bathnes.gov.uk/ |
| Brentwood Borough Council | East of England | Borough Council | https://brentwood.moderngov.co.uk/ |
| Brighton & Hove City Council | South East | City Council | https://democracy.brighton-hove.gov.uk/ |
| Bristol City Council | South West | City Council | https://democracy.bristol.gov.uk/ |
| Buckinghamshire Council | East of England | Unitary Authority | https://buckinghamshire.moderngov.co.uk/ |
| Cambridge City Council | East of England | City Council | https://democracy.cambridge.gov.uk/ |
| Cardiff Council | Wales | Unitary Authority | https://cardiff.moderngov.co.uk/ |
| Chichester District Council | South East | District Council | https://chichester.moderngov.co.uk/ |
| City of Lincoln Council | East Midlands | City Council | https://lincoln.moderngov.co.uk/ |
| City of Wolverhampton Council | West Midlands | Metropolitan Borough | https://wolverhampton.moderngov.co.uk/ |
| City of York Council | Yorkshire and Humber | City Council | https://democracy.york.gov.uk/ |
| Coventry City Council | West Midlands | City Council | https://edemocracy.coventry.gov.uk/ |
| East Hampshire District Council | South East | District Council | https://easthants.moderngov.co.uk/ |
| Greater London Authority (GLA) | London | Combined Authority | https://gla.moderngov.co.uk/ |
| Hastings Borough Council | South East | Borough Council | https://hastings.moderngov.co.uk/ |
| Leeds City Council | Yorkshire and Humber | City Council | https://democracy.leeds.gov.uk/ |
| Leicestershire County Council | East Midlands | County Council | https://democracy.leics.gov.uk/ |
| Lichfield District Council | West Midlands | District Council | https://lichfield.moderngov.co.uk/ |
| Liverpool City Council | North West | City Council | https://councillors.liverpool.gov.uk/ |
| London Borough of Barnet | London | London Borough | https://barnet.moderngov.co.uk/ |
| London Borough of Brent | London | London Borough | https://democracy.brent.gov.uk/ |
| London Borough of Camden | London | London Borough | https://camden.moderngov.co.uk/ |
| London Borough of Croydon | London | London Borough | https://croydon.moderngov.co.uk/ |
| London Borough of Haringey | London | London Borough | https://www.minutes.haringey.gov.uk/ |
| London Borough of Harrow | London | London Borough | https://moderngov.harrow.gov.uk/ |
| London Borough of Havering | London | London Borough | https://democracy.havering.gov.uk/ |
| London Borough of Hounslow | London | London Borough | https://democraticservices.hounslow.gov.uk/ |
| London Borough of Islington | London | London Borough | https://islington.moderngov.co.uk/ |
| London Borough of Southwark | London | London Borough | https://moderngov.southwark.gov.uk/ |
| London Borough of Sutton | London | London Borough | https://moderngov.sutton.gov.uk/ |
| London Borough of Tower Hamlets | London | London Borough | https://democracy.towerhamlets.gov.uk/ |
| Medway Council | South East | Unitary Authority | https://democracy.medway.gov.uk/ |
| Newcastle City Council | North East | City Council | https://democracy.newcastle.gov.uk/ |
| Portsmouth City Council | South East | City Council | https://democracy.portsmouth.gov.uk/ |
| Royal Borough of Kingston upon Thames | London | Royal Borough | https://kingston.moderngov.co.uk/ |
| Sheffield City Council | Yorkshire and Humber | City Council | https://democracy.sheffield.gov.uk/ |
| South Cambridgeshire District Council | East of England | District Council | https://scambs.moderngov.co.uk/ |
| Three Rivers District Council | East of England | District Council | https://moderngov.threerivers.gov.uk/ |
| Vale of White Horse District Council | South East | District Council | https://democratic.whitehorsedc.gov.uk/ |
| Warwickshire County Council | West Midlands | County Council | https://warwickshire.moderngov.co.uk/ |
| Watford Borough Council | East of England | Borough Council | https://watford.moderngov.co.uk/ |
| West of England Combined Authority | South West | Combined Authority | https://westofengland-ca.moderngov.co.uk/ |
| Wirral Council | North West | Metropolitan Borough | https://wirral.moderngov.co.uk/ |
| Worcestershire County Council | West Midlands | County Council | https://worcestershire.moderngov.co.uk/ |
Coverage Statistics
- Total Councils: 44
- Regions Covered: 11 (all UK regions)
- Council Types: 10 different authority types
- Tested Sites: 3 (Lichfield, Kirklees, Liverpool - 100% success rate)
Verified Working Examples
| Council | URL | Committee IDs | Notes |
|---|---|---|---|
| Lichfield District Council | https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL | Cabinet: 138, Council: 136, Planning: 135 | Primary test site |
| Kirklees Council | http://democracy.kirklees.gov.uk/mgWebService.asmx?WSDL | Same pattern | Identical behavior |
| Liverpool City Council | https://democracy.liverpool.gov.uk/mgWebService.asmx?WSDL | Same pattern | Identical behavior |
| London Borough of Sutton | https://moderngov.sutton.gov.uk/mgWebService.asmx | Full endpoint documentation | Comprehensive API testing |
Special Features
- London Borough of Sutton: Includes detailed endpoint documentation with parameter specifications, response formats, and working examples
- Council Discovery: Built-in fuzzy matching to find councils by name (
find_council) - Regional Search: Find all councils in a specific region (
get_council_by_region) - Confidence Scoring: Search with configurable confidence thresholds (
search_councils)
Council Discovery
Use the built-in council finder tools:
# Find a specific council
curl -X POST http://localhost:3003/mcp \
-H "Content-Type: application/json" \
-d '{"method": "tools/call", "params": {"name": "find_council", "arguments": {"council_name": "Leeds"}}}'
# Search councils by region
curl -X POST http://localhost:3003/mcp \
-H "Content-Type: application/json" \
-d '{"method": "tools/call", "params": {"name": "get_council_by_region", "arguments": {"region": "West Midlands"}}}'
API Discovery
To discover available operations for a specific council site, you can inspect the WSDL:
curl "https://democracy.lichfielddc.gov.uk/mgWebService.asmx?WSDL" | grep -i "council"
Examples
See the directory for complete configuration examples:
- Cursor:
examples/cursor-mcp.json - Claude Desktop:
examples/claude-desktop-config.json - VS Code:
examples/vscode-mcp.json - Docker Production:
examples/docker-compose.production.yml - Nginx Configuration:
examples/nginx.conf - Test Client:
examples/test-mcp-client.js - Postman Collection:
examples/postman-collection.json - Environment Config:
examples/env-example.txt
Quick Test
Test your setup with the provided script:
./examples/test-setup.sh
Configuration Notes
The MCP server supports both native Node.js execution and Docker deployment. Choose the configuration that matches your deployment method.
MCP Client Configuration
Choose the configuration that matches your transport preference:
✅ HTTP Transport (Recommended for production):
{
"mcpServers": {
"modgov-council": {
"url": "http://localhost:3003/mcp",
"headers": {
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream"
}
}
}
}
✅ STDIO Transport (Recommended for development):
{
"mcpServers": {
"modgov-council": {
"command": "node",
"args": ["dist/index.js"],
"cwd": "/path/to/modgov-mcp-server"
}
}
}
Server Requirements:
For HTTP Transport:
- Start the server:
MCP_TRANSPORT=http node dist/index.js - Or with Docker:
make build && make up - Server available at:
http://localhost:3003/mcp - Health check:
curl http://localhost:3003/health
For STDIO Transport:
- Build the project:
npm run build - Client will spawn:
node dist/index.js - No persistent server required
🎯 Best Practices
- Always use the MCP server - It handles all server bugs automatically
- Don't rely on WSDL alone - Test actual server behavior
- Handle 500 errors gracefully - May indicate server bugs, not client errors
- Use sensible defaults - The MCP provides them automatically
- Test across multiple sites - Behavior is consistent but verify
- Use council discovery tools - Find councils by name or region easily
🔧 Error Handling Examples
// The MCP server handles these automatically, but for direct API usage:
try {
const result = await modgovClient.getMeetings(siteUrl, 138);
} catch (error) {
if (error.message.includes('Missing parameter')) {
// This indicates a server bug, not client error
console.log('Server implementation bug detected - use MCP server instead');
}
}
Contributing
- Follow TDD principles - write tests first
- Ensure all tests pass before committing
- Add new features with comprehensive test coverage
- Update documentation for any API changes
License
MIT