CLAUDE.md•5.42 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 for interacting with the Atlas of Living Australia (ALA) API. It exposes 7 specialized tools that allow MCP clients to search, retrieve, and download biodiversity data from 152+ million occurrence records.
## Architecture
### Core Components
**Server Layer** (`src/ala_mcp/server.py`):
- MCP server implementation using `mcp.server.stdio`
- Exposes `api_request` tool with schema validation
- Routes tool calls to the ALAClient
- Handles JSON serialization of responses and errors
**Client Layer** (`src/ala_mcp/client.py`):
- HTTP client using httpx for async requests
- Handles authentication via Bearer tokens (optional)
- Normalizes responses into structured format with status_code, headers, url, and data
- Logs requests to stderr (avoiding MCP stdio interference)
**Configuration** (`src/ala_mcp/config.py`):
- Pydantic Settings for environment-based configuration
- Automatically loads from `.env` file with `ALA_` prefix
- Key settings: `base_url`, `default_timeout`, `api_key`, `log_level`
**Logging** (`src/ala_mcp/logging_config.py`):
- All logs go to stderr to avoid interfering with MCP stdio communication
- Logger name: `ala_mcp`
### Entry Points
- **Package**: `python -m ala_mcp` (uses `src/ala_mcp/__main__.py`)
- **Legacy script**: `./server.py` (root-level, kept for backward compatibility)
- **Console script**: `ala-mcp` command (defined in pyproject.toml)
## Development Commands
### Setup
```bash
make install-dev # Install with dev dependencies
make pre-commit # Install pre-commit hooks
```
### Testing
```bash
make test # Run all tests with pytest
make test-cov # Run tests with coverage report (90%+ target)
pytest tests/test_client.py # Run specific test file
pytest tests/test_server.py::test_name # Run specific test
```
### Code Quality
```bash
make format # Format with Black + Ruff (line length: 100)
make lint # Check with Ruff
make type-check # Type check with MyPy (strict mode)
make security # Security scan with Bandit
make all # Run format + lint + type-check + test
```
### Running Server
```bash
make run # Same as: python -m ala_mcp
python -m ala_mcp # Standard way to run
./server.py # Legacy entry point
```
## Code Standards
### Type Annotations
- All functions require type hints (enforced by MyPy strict mode)
- Use `Optional[T]` for nullable values
- Use `Dict[str, Any]` for JSON-like structures
### Async/Await
- All HTTP requests use httpx AsyncClient
- Server handlers are async functions
- Use `asyncio.run()` for entry point
### Docstrings
- Required for all public functions and classes
- Format: Summary line, Args, Returns, Raises sections
- See `src/ala_mcp/client.py:request()` for reference
### Import Order
1. Standard library
2. Third-party packages
3. Local modules (relative imports with `.`)
### Testing Patterns
- Use pytest-asyncio for async tests
- Fixtures in `tests/conftest.py`
- Follow Arrange-Act-Assert pattern
- Mock external HTTP calls with pytest-mock
## Configuration
Environment variables with `ALA_` prefix:
- `ALA_BASE_URL`: API base URL (default: https://biocache-ws.ala.org.au/ws)
- `ALA_DEFAULT_TIMEOUT`: Request timeout in seconds (default: 30)
- `ALA_LOG_LEVEL`: Logging level (default: INFO)
- `ALA_API_KEY`: Optional Bearer token for API authentication
Create `.env` file for local development (see `.env.example`).
## MCP Tools
The server exposes 7 tools:
1. **search_occurrences** - Main search tool with filtering, faceting, and spatial search
2. **get_occurrence** - Retrieve specific occurrence by UUID
3. **download_occurrences** - Request bulk CSV/TSV downloads (async, sent via email)
4. **count_taxa** - Get occurrence counts for taxa lists
5. **create_query_id** - Cache complex queries for reuse
6. **get_query** - Retrieve cached query parameters
7. **api_request** - Advanced: Direct API access for custom endpoints
Each tool has specific parameter schemas that map to ALA API endpoints. The tools use a shared `_execute_request` helper that formats responses consistently.
**See API_ENDPOINTS.md** for complete endpoint documentation including:
- All 152+ million occurrence records searchable via `/occurrences/search`
- Download endpoints for bulk data export (requires email)
- Query management, assertions, and user properties
- Full OpenAPI spec at: https://biocache.ala.org.au/ws/v3/api-docs
## Tool Implementation Pattern
When adding new tools:
1. Define tool schema in `list_tools()` with clear descriptions and parameter types
2. Add routing logic in `call_tool()` to map tool arguments to API parameters
3. Use `_execute_request()` helper for consistent response handling
4. Add tests in `tests/test_server.py` for the new tool
5. Update documentation (README.md, CLAUDE.md, API_ENDPOINTS.md)
## Important Notes
- **Logging**: Always use stderr handlers to avoid interfering with MCP stdio on stdout/stdin
- **Error Handling**: The server catches all exceptions from the client and returns them as structured JSON
- **Testing**: The project maintains 90%+ coverage; add tests for all new functionality
- **Commit Format**: Use conventional commits (feat:, fix:, docs:, etc.) per CONTRIBUTING.md