CLAUDE.md•7.69 kB
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a Model Context Protocol (MCP) server implementation for the Finizi B4B API. The MCP server acts as a transparent authentication proxy, forwarding user JWT tokens to the B4B API for authentication and authorization while providing AI agents with structured tools to interact with invoice management, entities, vendors, and products.
**Key Architecture**: Token pass-through model - the MCP server stores user JWT tokens in session metadata and forwards them to B4B API endpoints, relying on B4B's existing authorization logic.
## Development Commands
Currently this is a planning-only repository. When implementation begins:
```bash
# Install UV package manager
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Run MCP server
uv run python -m finizi_b4b_mcp.server
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=src/finizi_b4b_mcp
# Lint code
uv run ruff check src/ tests/
# Format code
uv run ruff format src/ tests/
```
## B4B API Integration
### Accessing API Documentation
The B4B API documentation is essential for implementation:
```bash
# Download OpenAPI specification
curl http://localhost:8000/api/v1/openapi.json > docs/b4b-openapi.json
# Interactive documentation available at:
# - Swagger UI: http://localhost:8000/docs
# - ReDoc: http://localhost:8000/redoc
```
### Authentication Flow
1. **Login**: User provides phone/password → MCP calls `/api/v1/auth/login` → Store JWT in `ctx.session.metadata['user_token']`
2. **Tool Calls**: Extract token via `extract_user_token(ctx)` → Forward as `Authorization: Bearer {token}` header
3. **Authorization**: B4B API validates JWT and checks `UserEntityRelationship` table for entity access
**Critical**: All tools (except login/logout/whoami) must call `extract_user_token(ctx)` before making API requests.
## Architecture Guidelines
### Token Management
- JWT tokens expire after 120 minutes
- Store tokens in `ctx.session.metadata` (in-memory, never persisted)
- Never log tokens or passwords
- Implement token auto-refresh when < 15 minutes remain (Phase 4)
### MCP Tool Pattern
Every tool should follow this structure:
```python
@mcp.tool()
async def tool_name(
required_param: str,
optional_param: Optional[str] = None,
ctx: Context = None
) -> dict:
"""
Clear description of what the tool does.
Args:
required_param: Description
optional_param: Description
ctx: MCP context (automatically provided)
Returns:
Response structure description
"""
# 1. Extract user token
user_token = await extract_user_token(ctx)
# 2. Build request parameters/payload
params = {...}
try:
# 3. Call B4B API with token pass-through
response = await api_client.get/post(
"/api/v1/endpoint",
headers={"Authorization": f"Bearer {user_token}"},
params=params # or json=payload
)
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
# 4. Handle authorization errors with friendly messages
if e.response.status_code == 403:
return {"error": "User-friendly access denied message"}
elif e.response.status_code == 404:
return {"error": "Resource not found message"}
else:
return {"error": f"API error: {e.response.json().get('detail', str(e))}"}
except Exception as e:
logger.error(f"Error in tool_name: {str(e)}")
return {"error": str(e)}
```
### Error Handling Principles
- Return `{"error": "message"}` dict for all errors (never raise exceptions to user)
- 403 errors → "You don't have access to entity X"
- 404 errors → "Entity/Invoice X not found"
- Network errors → Automatic retry via Tenacity
- Never expose internal paths, IPs, or stack traces
### Multi-Tenant Authorization
- MCP server: No authorization logic (just passes token)
- B4B API: Enforces all authorization via JWT + `UserEntityRelationship` table
- Super admins (`is_super_admin=True`): Can access any entity
- Regular users: Can only access entities where they have active relationships
## Repository Structure
```
finizi-b4b-mcp-server/
├── src/finizi_b4b_mcp/
│ ├── server.py # MCP server entry point with lifespan management
│ ├── config.py # Pydantic Settings for environment variables
│ ├── auth/
│ │ └── token_handler.py # extract_user_token() helper
│ ├── client/
│ │ └── api_client.py # HTTPX async client with retry logic
│ ├── tools/
│ │ ├── auth.py # login, logout, whoami
│ │ ├── entities.py # Entity CRUD operations
│ │ ├── invoices.py # Invoice management & import
│ │ ├── vendors.py # Vendor management
│ │ └── products.py # Product search & matching
│ └── utils/
│ ├── validators.py # Input validation (UUIDs, phone, pagination)
│ └── formatters.py # Response formatting utilities
├── tests/
│ ├── test_auth.py
│ ├── test_entities.py
│ └── fixtures/mock_responses.json
└── docs/
├── API_MAPPING.md # B4B API endpoint → MCP tool mapping
└── DEVELOPMENT.md # Implementation guide
```
## B4B API Key Characteristics
- **Token Lifetime**: 120 minutes (requires refresh logic)
- **Pagination**: Use `page` and `per_page` (max 100)
- **Status Codes**: Invoice status is INTEGER (0=DRAFT, 1=ACTIVE, 2=CANCELLED, 3=ARCHIVED)
- **Date Filters**: ISO format YYYY-MM-DD for `date_from`/`date_to`
- **Entity Context**: Most endpoints require `entity_id` path parameter
- **Super Admin Bypass**: Super admins can access all entities without relationship check
## Implementation Phases
### Phase 1 - Foundation (P0)
- Configuration management (Pydantic Settings)
- HTTP client with retry logic (HTTPX + Tenacity)
- Token extraction helper
- Authentication tools: `login`, `logout`, `whoami`
### Phase 2 - Core Tools (P0)
- Entity management: `list_entities`, `get_entity`, `create_entity`, `update_entity`
- Invoice listing: `list_invoices`, `get_invoice`, `get_invoice_statistics`
### Phase 3 - Advanced Features (P1)
- Vendor tools: `list_vendors`, `get_vendor`
- Product tools: `list_products`, `search_similar_products`
- Invoice import: `import_invoice_xml`
### Phase 4 - Production Readiness (P2)
- Token auto-refresh before 120-minute expiry
- Rate limiting (token bucket algorithm)
- Comprehensive logging and metrics
- Security audit
## Testing Requirements
- Unit tests: Mock HTTPX responses, test token handling
- Integration tests: Test 403/404 error handling, authorization flows
- Fixtures: Use `tests/fixtures/mock_responses.json` for consistent mock data
- Coverage target: 80%+
## Code Quality Standards
- Type hints on all functions
- Structured logging with `structlog` (never `print()`)
- Input validation on all parameters
- Async/await for all I/O operations
- Follow FastMCP patterns for tool registration
## Security Checklist
- [ ] Never log JWT tokens or passwords
- [ ] Validate all UUIDs before passing to API
- [ ] Sanitize error messages (no internal paths/IPs)
- [ ] Use HTTPS for production B4B API
- [ ] Clear session metadata on logout
- [ ] Validate pagination parameters (max per_page=100)
- [ ] Validate phone number format for login