This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This project provides both an MCP server and a CLI for the Brewfather API. The shared tools/ layer (src/brewfather_mcp/tools/) contains the formatting logic used by both.
The API is documented, but not well, at https://docs.brewfather.app/api In order to make robust code, we need to "test in production" by making calls to tools and debug the results. This is fine to do directly for get and list operations, but not for operations that change data. For that, we might be able to create a test entry (inventory, recipe, batch) first, then test, then clean up by carefully deleting the test item.
uv run pytest- Run test suiteuv run pytest tests/test_file.py::TestClass::test_method- Run specific testuv run pytest --cov- Run tests with coverageuv install- Install dependenciesuv sync- Sync dependencies
uv run brewfather-cli --help- Show CLI commandsuv run brewfather-cli auth configure- Set up credentials interactivelyuv run brewfather-cli inventory summary- Test inventory outputuv run brewfather-cli batch list --json- Test JSON output mode
The server supports two transport modes:
When using claude code, use mcpt commands to test changes to this server. The inbuilt mcp tools don't get reloaded after changes.
uv run --with mcp[cli] mcp install- Install MCP CLI toolsuv run --with 'mcp[cli]' mcp run src/main.py- Run serveruv run --with 'mcp[cli]' mcp dev src/main.py- Run server with inspectormcpt tools uv run --with 'mcp[cli]' mcp run src/main.py- Use MCP Tools to list toolsmcpt call list_batches uv run --with 'mcp[cli]' mcp run src/main.py- Call a toolmcpt call get_batch_detail --params '{ "batch_id": "C3hZC7P4zeNH6QJsc7FXizVGN8dkQe" }' uv run --with 'mcp[cli]' mcp run src/main.py- Call a tool with paramsBREWFATHER_MCP_DEBUG=1 mcpt call get_batch_detail --params '{ "batch_id": "C3hZC7P4zeNH6QJsc7FXizVGN8dkQe" }' uv run --with 'mcp[cli]' mcp run src/main.py- Call tool with debug mode to save API calls to filealias -g BF="uv run --with 'mcp[cli]' mcp run src/main.py"- Alias to use with mcpt, egmcpt tools BF
For testing the HTTP server or deployment to cloud platforms:
Start HTTP Server:
PYTHONPATH=src python src/http_runner.py --port 8000- Start HTTP/SSE server on port 8000PYTHONPATH=src python src/http_runner.py --host 0.0.0.0 --port 8000 --log-level DEBUG- Start with custom settings
Testing HTTP Server with mcpt:
mcpt tools http://localhost:8000/sse- List available tools via HTTPmcpt call list_inventory_categories http://localhost:8000/sse- Call a simple toolmcpt call inventory_summary http://localhost:8000/sse- Call a complex toolmcpt call get_fermentable_detail --params '{"identifier": "default-08f456e"}' http://localhost:8000/sse- Call tool with parametersmcpt call update_fermentable_inventory --params '{"item_id": "default-08f456e", "inventory_amount": 5.0}' http://localhost:8000/sse- Call update tool
Health Check:
curl http://localhost:8000/sse- Check if SSE endpoint is responding (will hang waiting for events, which is expected)
The HTTP server can be deployed to any cloud platform that supports Python web applications:
Railway:
- Connect GitHub repo to Railway
- Set environment variables:
BREWFATHER_API_USER_ID,BREWFATHER_API_KEY - Set start command:
PYTHONPATH=src python src/http_runner.py --port $PORT
Fly.io:
fly launchto create app- Set secrets:
fly secrets set BREWFATHER_API_USER_ID=xxx BREWFATHER_API_KEY=yyy - Configure start command in fly.toml
Render:
- Connect repo to Render
- Set build command:
uv sync - Set start command:
PYTHONPATH=src python src/http_runner.py --port $PORT - Set environment variables in Render dashboard
Access deployed server:
- MCP endpoint:
https://your-app.platform.com/sse - Test with:
mcpt tools https://your-app.platform.com/sse
API Client (src/brewfather_mcp/api.py)
BrewfatherClient- Main HTTP client for Brewfather API- Uses httpx with basic auth (BREWFATHER_API_USER_ID, BREWFATHER_API_KEY)
- Implements CRUD operations for all inventory categories and recipes
- Base URL:
https://api.brewfather.app/v2
MCP Server (src/brewfather_mcp/server.py)
- Uses FastMCP framework to expose tools and prompts
- Thin wrappers that delegate to the
tools/layer - Includes specialized prompts for beer style suggestions based on inventory
- Logs to
/tmp/brewfather_mcp.log
CLI (src/brewfather_mcp/cli/)
- Click-based command hierarchy:
brewfather-cli <category> <command> [--json] - Auth: env vars >
~/.config/brewfather-cli/auth.json - Text mode calls
tools/functions;--jsonreturns raw API data
Tools Layer (src/brewfather_mcp/tools/)
- Shared async functions
(client, ...) -> strused by both MCP server and CLI - One file per domain: fermentable, hop, yeast, misc, batch, recipe, inventory
Type Definitions (src/brewfather_mcp/types.py)
- Pydantic models for all Brewfather API responses
- Separate models for list views vs detail views
- Handles complex nested structures (recipes, water profiles, fermentation schedules)
Inventory Utilities (src/brewfather_mcp/inventory.py)
- Helper functions for creating inventory summaries
- Used by the
inventory_summaryMCP tool
Required environment variables:
BREWFATHER_API_USER_ID- Your Brewfather API user IDBREWFATHER_API_KEY- Your Brewfather API key
For testing, use .test.env file (automatically loaded by pytest).
When developing, use .env file
- Uses pytest with pytest-vcr for HTTP request recording/replay
- VCR cassettes stored in
tests/cassettes/ - Test configuration in
tests/conftest.pyincludes auth header filtering - Coverage configuration excludes test files
The server exposes these main tool categories:
- Inventory: List/detail/update for fermentables, hops, yeasts, misc items
- Recipes: List and detailed recipe information including ingredients and process
- Batches: List, detail, and update brewing batches with measured values
- Summaries: Combined inventory overviews and brewing style suggestions
- All API methods are async and use httpx
- Pydantic models validate all API responses
- Tools layer produces formatted string outputs
- Exceptions propagate without logging
- Consistent URL building pattern using
_build_url()method