feat: add MCP server for AI-powered member management

This change implements a Model Context Protocol (MCP) server that
enables AI assistants to manage society members through natural
language interactions.

Changes:
- Add MCP server implementation (src/mcp_server.py)
- Implement 4 core tools:
  * list_members - Query all members
  * get_member - Get specific member by ID
  * create_member - Create new member
  * update_member - Update member information
- Add mcp and httpx dependencies to pyproject.toml
- Update README with comprehensive MCP server documentation
- Create OpenSpec proposal in openspec/changes/add-mcp-server/

The MCP server connects to the GraphQL API via HTTP and provides
structured tools that abstract away GraphQL complexity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 13:54:52 +01:00
co-authored by Claude
parent 5bb27bdadf
commit 8d14e7e75a
7 changed files with 1096 additions and 0 deletions
@@ -0,0 +1,29 @@
# Add MCP Server for Member Management
## Why
AI assistants need a standardized way to interact with the Clubber GraphQL API. The Model Context Protocol (MCP) provides a standard interface for AI tools to access application functionality. Currently, AI assistants can only interact with the API through raw GraphQL queries, which requires the assistant to construct queries manually and handle responses. An MCP server will provide structured tools that abstract away GraphQL complexity and enable seamless member management through AI agents like Claude.
## What Changes
- Add official MCP Python SDK (`mcp`) as dependency
- Create MCP server implementation in `src/mcp_server.py`
- Implement 4 core tools for member management:
- `list_members` - Query all members with their details
- `get_member` - Retrieve a single member by ID
- `create_member` - Create a new member (only firstName required)
- `update_member` - Update an existing member's information
- Use HTTP client (httpx) to connect to GraphQL API
- Configure via environment variable (CLUBBER_API_URL)
- Update README with MCP server setup, configuration, and usage instructions
- Document Claude Code integration steps
## Impact
- **Affected specs**: New capability `mcp-integration`
- **Affected code**:
- New file: `src/mcp_server.py` (~150-200 lines)
- Modified: `pyproject.toml` (add mcp dependency)
- Modified: `README.md` (add MCP server documentation)
- **User impact**: Enables AI assistants to manage society members through natural language
- **No breaking changes**: This is additive functionality
@@ -0,0 +1,99 @@
# MCP Integration Specification
## ADDED Requirements
### Requirement: MCP Server Implementation
The system SHALL provide an MCP (Model Context Protocol) server that exposes member management functionality as standardized AI tools.
#### Scenario: MCP server starts successfully
- **GIVEN** the GraphQL API is running at http://127.0.0.1:8000/graphql
- **WHEN** the MCP server is started with `python -m src.mcp_server`
- **THEN** the server SHALL initialize and listen for MCP protocol requests via stdio transport
#### Scenario: MCP server connects to GraphQL API
- **GIVEN** the MCP server is running
- **WHEN** an MCP tool is invoked
- **THEN** the server SHALL send GraphQL queries to the configured API endpoint via HTTP
### Requirement: List Members Tool
The MCP server SHALL provide a `list_members` tool that retrieves all members from the GraphQL API.
#### Scenario: List all members successfully
- **GIVEN** the GraphQL API has 3 members in the database
- **WHEN** the `list_members` tool is invoked
- **THEN** the tool SHALL return a JSON array containing all 3 members with their complete data
#### Scenario: List members when database is empty
- **GIVEN** the GraphQL API has no members
- **WHEN** the `list_members` tool is invoked
- **THEN** the tool SHALL return an empty JSON array
### Requirement: Get Member Tool
The MCP server SHALL provide a `get_member` tool that retrieves a single member by ID.
#### Scenario: Get member by valid ID
- **GIVEN** a member exists with ID 1
- **WHEN** the `get_member` tool is invoked with id=1
- **THEN** the tool SHALL return the member's complete data as JSON
#### Scenario: Get member with nonexistent ID
- **GIVEN** no member exists with ID 999
- **WHEN** the `get_member` tool is invoked with id=999
- **THEN** the tool SHALL return an error indicating the member was not found
### Requirement: Create Member Tool
The MCP server SHALL provide a `create_member` tool that creates new members via the GraphQL API.
#### Scenario: Create member with minimal data
- **GIVEN** only a first name "Alice" is provided
- **WHEN** the `create_member` tool is invoked
- **THEN** the tool SHALL create a new member with firstName="Alice" and return the created member with generated ID
#### Scenario: Create member with complete data
- **GIVEN** complete member data including name, address, email, and phone
- **WHEN** the `create_member` tool is invoked
- **THEN** the tool SHALL create a member with all fields populated and return the created member
#### Scenario: Create member with invalid email
- **GIVEN** an invalid email format "not-an-email"
- **WHEN** the `create_member` tool is invoked with this email
- **THEN** the tool SHALL return a validation error from the GraphQL API
### Requirement: Update Member Tool
The MCP server SHALL provide an `update_member` tool that updates existing member information.
#### Scenario: Update member successfully
- **GIVEN** a member exists with ID 1
- **WHEN** the `update_member` tool is invoked with id=1 and email="updated@example.com"
- **THEN** the tool SHALL update the member's email and return the updated member data
#### Scenario: Update member with invalid ID
- **GIVEN** no member exists with ID 999
- **WHEN** the `update_member` tool is invoked with id=999
- **THEN** the tool SHALL return an error indicating the member was not found
### Requirement: Configuration
The MCP server SHALL support configuration via environment variables.
#### Scenario: Custom API URL configuration
- **GIVEN** environment variable CLUBBER_API_URL is set to "http://localhost:3000/graphql"
- **WHEN** the MCP server starts
- **THEN** the server SHALL use "http://localhost:3000/graphql" as the GraphQL endpoint
#### Scenario: Default API URL
- **GIVEN** no CLUBBER_API_URL environment variable is set
- **WHEN** the MCP server starts
- **THEN** the server SHALL default to "http://127.0.0.1:8000/graphql"
### Requirement: Error Handling
The MCP server SHALL handle errors gracefully and return meaningful error messages.
#### Scenario: GraphQL API unavailable
- **GIVEN** the GraphQL API is not running
- **WHEN** any MCP tool is invoked
- **THEN** the tool SHALL return an error indicating the API is unreachable
#### Scenario: GraphQL validation error
- **GIVEN** the GraphQL API returns a validation error
- **WHEN** an MCP tool is invoked with invalid data
- **THEN** the tool SHALL return the validation error message to the client
+48
View File
@@ -0,0 +1,48 @@
# Implementation Tasks
## 1. Dependencies
- [ ] 1.1 Add `mcp` package to pyproject.toml dependencies
- [ ] 1.2 Run `uv sync` to install new dependency
## 2. MCP Server Implementation
- [ ] 2.1 Create `src/mcp_server.py` with server scaffold
- [ ] 2.2 Implement GraphQL client class with httpx
- [ ] 2.3 Implement `list_members` tool
- [ ] 2.4 Implement `get_member` tool with ID parameter
- [ ] 2.5 Implement `create_member` tool with member input
- [ ] 2.6 Implement `update_member` tool with member update input
- [ ] 2.7 Add configuration via environment variable CLUBBER_API_URL
- [ ] 2.8 Add proper error handling and validation
- [ ] 2.9 Add tool descriptions and parameter schemas
## 3. Documentation
- [ ] 3.1 Update README with "MCP Server" section
- [ ] 3.2 Document installation and setup steps
- [ ] 3.3 Document environment variable configuration
- [ ] 3.4 Add Claude Code integration instructions
- [ ] 3.5 Provide usage examples for each tool
- [ ] 3.6 Document running the server (`python -m src.mcp_server`)
## 4. Testing & Validation
- [ ] 4.1 Start GraphQL API server
- [ ] 4.2 Test `list_members` tool returns all members
- [ ] 4.3 Test `get_member` tool with valid ID
- [ ] 4.4 Test `get_member` tool with invalid ID (error handling)
- [ ] 4.5 Test `create_member` tool with minimal data (firstName only)
- [ ] 4.6 Test `create_member` tool with complete data
- [ ] 4.7 Test `create_member` tool with invalid email (validation error)
- [ ] 4.8 Test `update_member` tool updates member successfully
- [ ] 4.9 Test `update_member` tool with invalid ID (error handling)
- [ ] 4.10 Verify MCP server works with Claude Code
## 5. Code Quality
- [ ] 5.1 Run Black formatting: `uv run black src/mcp_server.py`
- [ ] 5.2 Run isort: `uv run isort src/mcp_server.py`
- [ ] 5.3 Run ruff linting: `uv run ruff check src/mcp_server.py`
- [ ] 5.4 Add type hints to all functions
- [ ] 5.5 Add docstrings to classes and key functions
## 6. Git & OpenSpec
- [ ] 6.1 Commit all changes with conventional commit message
- [ ] 6.2 Validate OpenSpec proposal: `openspec validate add-mcp-server --strict`
- [ ] 6.3 Push to remote branch