This guide explains how to set up a fast, productive development workflow for the Katana MCP Server using hot-reload capabilities.
-
Install uv (if not already installed):
curl -LsSf https://astral.sh/uv/install.sh | shOr see uv installation docs
-
Python 3.12+ (for hot-reload mode)
-
Find your uv path: Run
which uv(usually~/.local/bin/uv)
Hot-reload with HTTP transport — ideal for testing with Claude.ai co-work or any HTTP MCP client:
# From the repo root
uv run poe devThe server starts on http://0.0.0.0:8765/mcp with automatic reload on file changes.
For Claude.ai co-work, you also need an HTTPS tunnel (Claude.ai requires HTTPS + public URL):
# Terminal 1: MCP server with hot-reload
uv run poe dev
# Terminal 2: HTTPS tunnel
ngrok http 8765
# → Paste the https:// URL into Claude.ai > Customize > ConnectorsHot-reload with stdio transport — for Claude Desktop:
uv run poe dev-stdioOr with mcp-hmr for fine-grained module reloading (preserves connection state):
cd katana_mcp_server
uv pip install mcp-hmr
uv run mcp-hmr katana_mcp.server:mcpLaunches a web UI for testing tools interactively:
uv run poe dev-inspectFor release testing and production use:
cd katana_mcp_server
uv build
pipx install --force dist/katana_mcp_server-*.whl| Command | Transport | Hot Reload | Use Case |
|---|---|---|---|
poe dev |
streamable-http | Yes | Claude.ai co-work, HTTP |
poe dev-stdio |
stdio | Yes | Claude Desktop, Claude Code |
poe dev-inspect |
Inspector UI | Yes | Visual tool debugging |
mcp-hmr |
stdio | Yes (fast) | Fine-grained module reload |
katana-mcp-server |
stdio (default) | No | Production |
You can configure Claude Desktop to support both modes simultaneously.
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"katana-erp-dev": {
"command": "/absolute/path/to/katana-openapi-client/.venv/bin/mcp-hmr",
"args": ["katana_mcp.server:mcp"],
"cwd": "/absolute/path/to/katana-openapi-client/katana_mcp_server",
"env": {
"KATANA_API_KEY": "your-api-key-here"
}
},
"katana-erp": {
"command": "katana-mcp-server",
"env": {
"KATANA_API_KEY": "your-api-key-here"
}
}
}
}Important:
- Replace
/absolute/path/to/with your actual repository path - The
.venv/bin/mcp-hmrexecutable is created when you runuv pip install mcp-hmr - On Windows, use
.venv\\Scripts\\mcp-hmr.exeinstead
- Development: Use
@katana-erp-devin Claude Desktop - Production: Use
@katana-erpin Claude Desktop - Both can be enabled at the same time
Tip: Use development mode while coding, then test against production mode before creating a PR.
# 1. Start development server (once)
cd katana_mcp_server
uv run mcp-hmr katana_mcp.server:mcp
# 2. Use the MCP server in Claude Desktop
# - Chat with Claude
# - Test your tools
# - Notice a bug or want to add a feature
# 3. Edit code in your editor
# - Modify src/katana_mcp/tools/inventory.py
# - Add logging, fix bugs, improve error handling
# - Save the file
# 4. Test immediately in Claude Desktop
# - No restart needed!
# - Try the tool again
# - See your changes instantly
# 5. Iterate until satisfied
# - Keep editing and saving
# - Changes apply in real-time✅ Reloads automatically:
- Tool implementations (
src/katana_mcp/tools/*.py) - Helper functions
- Request/response models
- Business logic
❌ Requires restart:
server.pychanges (FastMCP initialization)- Lifespan context changes
- New dependencies in
pyproject.toml
Hot reload makes debugging much faster:
# Before (in src/katana_mcp/tools/foundation/inventory.py)
async def _check_inventory_impl(
request: CheckInventoryRequest, context: Context
) -> list[StockInfo]:
services = get_services(context)
# ... fetch variants from cache, look up stock per variant ...
# After (add logging - save file - test immediately!)
from katana_mcp.logging import get_logger
logger = get_logger(__name__)
async def _check_inventory_impl(
request: CheckInventoryRequest, context: Context
) -> list[StockInfo]:
logger.info(
"inventory_check_started",
sku_count=sum(1 for x in request.skus_or_variant_ids if isinstance(x, str)),
variant_id_count=sum(1 for x in request.skus_or_variant_ids if isinstance(x, int)),
)
services = get_services(context)
# ... rest of functionSave → Test in Claude Desktop → See logs immediately!
mcp-hmr (Model Context Protocol Hot Module Replacement) provides:
- Fine-grained reloading: Only reloads changed modules, not the entire process
- Preserved state: Keeps connections alive, database pools intact
- Fast feedback: See changes in seconds, not minutes
- Standard Python: Uses importlib machinery, no magic
- Watches file system for changes to
.pyfiles - Uses Python's import hooks to reload modified modules
- Preserves the FastMCP server instance and lifespan context
- Updates tool registrations without restarting the server
# Run tests before committing
uv run poe test
# Pre-commit hooks will also run tests automatically
git commit -m "feat(mcp): add new inventory tool"- Development mode: Iterate rapidly with hot reload
- Production mode: Verify the installed package works
- Claude Desktop: Test actual tool usage
- Automated tests: Ensure everything passes
# After development, test the full cycle
uv run poe test # Unit tests pass
uv build # Build package
pipx install --force dist/*.whl # Install for real
# Test in Claude Desktop with production configProblem: Changes don't appear after saving
Solutions:
- Check that you saved the file
- Verify
mcp-hmris installed:uv run --extra dev mcp-hmr --version - Look for error messages in the terminal running the server
- Some changes (like
server.py) require a full restart
Problem: ModuleNotFoundError or ImportError
Solutions:
- Ensure you're running from the correct directory:
cd katana_mcp_server - Verify dependencies are installed:
uv sync --extra dev - Check that the file path in the command is correct:
src/katana_mcp/server.py:mcp
Problem: MCP server doesn't appear in Claude Desktop
Solutions:
- Verify
claude_desktop_config.jsonpath is correct - Check JSON syntax (use a validator if needed)
- Restart Claude Desktop after config changes
- Verify
cwdpath is absolute and correct - Check that
KATANA_API_KEYis set in env
Problem: PermissionError when running server
Solutions:
- Ensure the repository directory is writable
- Check that
.envfile has correct permissions - On Unix:
chmod 600 .envto secure API key file
# Start dev server once, keep it running all day
uv run mcp-hmr katana_mcp.server:mcp# Before creating a PR, verify production install
uv build
pipx install --force dist/*.whl
# Test in Claude Desktop with production config# Pre-commit hooks run automatically, but you can run manually:
uv run poe test # Just tests
uv run poe check # Full validation (lint + test + format)# Good: Helps debug issues
logger.info(f"Processing inventory check for SKU: {request.sku}")
logger.debug(f"Client config: base_url={client.base_url}, timeout={client.timeout}")
logger.warning(f"SKU not found: {request.sku}, returning empty stock")
# Bad: Not helpful
logger.info("Doing a thing")
logger.debug("Debug message")# Good: Separate implementation from FastMCP decorator
async def _check_inventory_impl(request, context) -> StockInfo:
\"\"\"Implementation with full business logic.\"\"\"
# ... implementation
@mcp.tool()
async def check_inventory(request, context) -> StockInfo:
\"\"\"FastMCP tool wrapper - minimal logic here.\"\"\"
return await _check_inventory_impl(request, context)This allows testing _check_inventory_impl directly with mocks.
- FastMCP Docs: https://github.com/jlowin/fastmcp
- mcp-hmr GitHub: https://github.com/mizchi/mcp-hmr
- MCP Specification: https://modelcontextprotocol.io
- Project README: ../katana_mcp_server/README.md
- Testing Guide: Client Testing Guide
- Issues: https://github.com/dougborg/katana-openapi-client/issues
- Discussions: https://github.com/dougborg/katana-openapi-client/discussions
- MCP Community: https://discord.gg/modelcontextprotocol
Happy coding! 🚀 The hot-reload workflow will dramatically speed up your development iteration time.