A toolset for managing members of non-profit societies (Vereine) with AI-powered administration.
## Overview
Clubber provides a GraphQL API for member management combined with an MCP (Model Context Protocol) server that enables AI assistants to help with society administration tasks.
**Current Status**: Early development - OpenSpec documentation and project structure in place.
## Architecture
The system consists of two main components:
1.**GraphQL API** - Core backend for member data management
- Built with FastAPI and Strawberry GraphQL
- Database-agnostic design (SQLite for development, PostgreSQL for production)
- SQLAlchemy 2.0 ORM with async support
2.**MCP Server** - AI assistant integration layer
- Connects to the GraphQL API
- Provides tools for AI agents to manage society operations
- Service account authentication
## Tech Stack
- **Python 3.11+** - Primary language
- **uv** - Fast package and project manager
- **FastAPI** - Async web framework
- **Strawberry GraphQL** - Type-safe GraphQL with Python type hints
- **SQLAlchemy 2.0** - Database ORM
- **Alembic** - Database migrations
## Project Structure
```
clubber/
├── openspec/ # Specification-driven development
│ ├── project.md # Project conventions and context
-`apartmentNumber` (optional) - Apartment or unit number
-`zip` (optional) - Postal code
-`city` (optional) - City
-`country` (optional) - Country
-`email` (optional) - Email address (validated when provided)
-`phone` (optional) - Phone number in E.164 format (validated when provided)
**Key Feature**: Only `firstName` is required. All other fields are optional and can be populated later. Email and phone are validated only when provided (not when null/empty).
### GraphQL Queries
List all members:
```graphql
{
members{
id
firstName
lastName
email
phone
city
}
}
```
Get a single member:
```graphql
{
member(id:1){
id
firstName
lastName
email
street
city
country
}
}
```
### GraphQL Mutations
Create a member (minimal - only firstName):
```graphql
mutation{
createMember(input:{
firstName:"Alice"
}){
id
firstName
email
}
}
```
Create a member with all fields:
```graphql
mutation{
createMember(input:{
firstName:"Bob"
lastName:"Johnson"
street:"123 Main St"
apartmentNumber:"4B"
zip:"12345"
city:"Springfield"
country:"USA"
email:"bob.johnson@example.com"
phone:"+14155551234"
}){
id
firstName
lastName
email
phone
}
}
```
Update a member:
```graphql
mutation{
updateMember(input:{
id:1
email:"updated@example.com"
phone:"+14155559999"
}){
id
firstName
email
phone
}
}
```
Delete a member:
```graphql
mutation{
deleteMember(id:2)
}
```
### Using curl
Query members:
```bash
curl -X POST http://127.0.0.1:8000/graphql \
-H "Content-Type: application/json"\
-d '{"query": "{ members { id firstName lastName email } }"}'
The MCP (Model Context Protocol) server enables AI assistants like Claude to manage society members through natural language interactions.
### What is MCP?
The Model Context Protocol (MCP) is a standard protocol that allows AI assistants to use tools and access external systems. The Clubber MCP server provides 4 tools that connect to the GraphQL API:
- **list_members** - List all members with their complete information
- **get_member** - Get detailed information about a specific member by ID
- **create_member** - Create a new member (only firstName required)
- **update_member** - Update an existing member's information
### Running the MCP Server
The MCP server requires the GraphQL API to be running first:
```bash
# Terminal 1: Start the GraphQL API
uv run uvicorn src.main:app --host 127.0.0.1 --port 8000
# Terminal 2: Run the MCP server
python -m src.mcp_server
```
### Configuration
The MCP server can be configured via environment variables:
```bash
# Use a custom API URL (default: http://127.0.0.1:8000/graphql)