Introduction
In this 3-part series, we are building an autonomous coffee roasting agent with Warp. The first part covered how we fine-tuned a model to detect first crack — a critical phase in the roasting process. This was a nice warm-up implementing a key component for our end goal, but detection alone isn't enough. Now we need to expose this functionality so the agent we'll build can both detect first crack and control the roasting process.
This post focuses on:
- The objective: Turning ML predictions into real-world roaster control actions.
- Solution overview: Model Context Protocol (MCP) servers as the bridge between AI agents and hardware
- Implementation: The two MCP servers we built—First Crack Detector MCP + Hottop Controller MCP
📊 TL;DR
- Connect trained ML model to physical roaster control using an agent to achieve autonomous coffee roasting
- Build two MCP servers — FirstCrackDetector + HottopController
- Stack: Python MCP SDK, pyserial, pyhottop, Auth0 authentication
- Real-time detection + safe roaster control via AI agents (208+ tests passing)
- Using Warp Agent mode, Context7 MCP Server, Auth0 MCP Server during development
- Next Part: Part 3 orchestrates both servers with Microsoft Agent Framework
Integrating software, hardware and agents without reinventing the wheel
Traditional approach: Build custom APIs, handle authentication, manage state
- Write integration code using imperative/declarative patterns to manage task lifecycles.
- Homegrown specifications make it harder to leverage emerging ML/AI technologies.
- Each new AI model or agent requires custom integration work.
The MCP option: Standardised protocol for AI <-> tool communication
- Provides deterministic tools for non-deterministic AI systems.
- Benefits: Discoverability, type safety, streaming support, composability, and interoperability across AI models and agents.
- Write once, connect to MCP-compatible AI (Claude, ChatGPT, custom agents).
🤖 Warp Agent Contributions
- Provided MCP server scaffolding and tool definitions using standard MCP SDK.
- Helped integrate pyhottop library for Hottop serial protocol communication.
- Debugged serial communication timing issues and state synchronization.
- Generated Auth0 authentication middleware with role-based access control.
- Created comprehensive test suites (208+ tests across both MCP servers).
- Suggested testing strategies including simulation mode for hardware free development.
What is MCP (Model Context Protocol) and Why Use It?
What is MCP?
MCP is a protocol that enables AI assistants like Claude, ChatGPT, Warp Agent Mode to connect to external resources through a client-server architecture following standard protocols. This allows using the same MCP server with various agent technologies without having to modify the code.
Client-Server Concept
MCP Server
A program that exposes specific data and tools (functionality) that an AI Agents can use. For example, a server might provide access to a database, file system, or even as in our case specific hardware.
MCP Client
The application that connects to MCP servers and makes their capabilities available to the AI. As an example, Claude /ChatGPT acts as an MCP client.
Transport Types
MCP supports different ways for clients and servers to communicate:
- stdio (Standard Input/Output)
- Most common for local integrations
- Server runs as a subprocess, communicating via stdin/stdout
- Simple and works well for local tools
- SSE (Server-Sent Events)
-Used for remote servers over HTTP
- Server pushes updates to client
- Good for web-based integrations
- Custom transports can also be implemented
- The protocol is designed to be transport-agnostic
Flow
When user asks Claude (MCP Client) something that is exposed by an MCP Server, the client can call the MCP server to retrieve data or execute tools, then use that information in its response.
Server 1: First Crack Detector MCP
In this section, we will briefly cover how the detector we have trained in the previous article is exposed as an MCP Server.
The following diagram illustrates how the components are exposed as an MCP Server:
Implementation Details
- MCP SDK setup: Server initialisation using standard Python MCP SDK with stdio and SSE transports.
- Tool definitions: start_detection, stop_detection, get_status with Auth0 role-based authorisation.
- Session management: Thread-safe singleton pattern with idempotency enforcement.
- Real-time monitoring: Streaming detection events via SSE for live status updates.
- Error handling: Audio device enumeration failures, model loading issues, thread crashes, timeout scenarios.
Code Walkthrough
# Key implementation components:
# - MCP SDK decorators for tool registration
# - Auth0 JWT validation middleware
# - Session manager with thread-safe state
# - OpenTelemetry tracing integration
# First Crack Detection MCP Server setup
from mcp.server import Server
from mcp.types import Tool, TextContent
mcp_server = Server("first-crack-detection")
@mcp_server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="start_first_crack_detection",
description="Start monitoring audio for first crack events",
inputSchema={
"type": "object",
"properties": {
"audio_source_type": {
"type": "string",
"enum": ["audio_file", "usb_microphone", "builtin_microphone"]
}
},
"required": ["audio_source_type"]
}
)
]
@mcp_server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name == "start_first_crack_detection":
# Thread-safe session management
result = session_manager.start_session(
audio_config=AudioConfig(**arguments)
)
return [TextContent(
type="text",
text=json.dumps(result, indent=2)
)]
Testing Approach
- Custom test scripts: Python scripts using stdio communication (test_mcp_roaster.py)
- Shell integration tests: Bash scripts for end-to-end workflows (test_roaster_server.sh)
- Unit test coverage: 86 passing tests with pytest, mocking audio devices and model inference
- Manual hardware testing: Real USB microphone validation with live roasting sessions
Server 2: Hottop Roaster Controller MCP
The Second MCP Server is to expose the status of the roaster and also to run commands to set heat, fan as well as start / stop commands for the roast.
This is implemented as a separate MCP server due to different hardware requirements which might require running these on different hosts.
The Hottop KN-8828B-2K+ Protocol
Initial approach with pyhottop library
Initially, we have attempted to use the pyhottop library for serial communication with the Hottop KN-8828B-2K+ roaster. However, we encountered compatibility issues that prevented reliable operation and had to consider an alternative approach.
Adapting to Artisan's protocol
After pyhottop proved unreliable, we analyzed the Artisan roasting software source code — a mature, widely-used open-source application for coffee roaster control. Being a user of Artisan's Hottop integration, I knew it has been working well for me. Given it has been battle-tested by the roasting community for a long time, it was an obvious next choice.
Warp Agent Mode has successfully analysed and adapted Artisan's serial protocol implementation.
Implementation Details
- Serial connection management: USB serial at 115200 baud, continuous 0.3s command intervals (required by Hottop)
- Command encoding: Artisan-compatible 36-byte protocol with checksums
- Status parsing: Real-time temperature readings (bean + chamber) from serial responses
-
Input validation:
- Heat/fan values: 0-100% in 10% increments
- Connection state checks before commands
- Thread-safe state management with locks
-
Authentication: Auth0 JWT with role-based access control
-
read:roaster- Status monitoring only -
write:roaster- Full hardware control - Per-user audit logging
-
Code Architecture
# Key implementation layers:
# 1. MCP Server (sse_server.py) - Auth0 + tool definitions
# 2. SessionManager - Thread-safe orchestration
# 3. HardwareInterface - Artisan serial protocol
# 4. Continuous command loop - 0.3s intervals with temperature polling
Testing Strategy
- MockRoaster: Realistic thermal simulation for development without hardware. Unfortunately, due to time restrictions, this has provided limited utility.
- Hardware verification: Validated with physical Hottop KN-8828B-2K+ (October 2025).
- Test coverage: 122 passing unit tests.
- Manual test scripts: test_hottop_interactive.py, test_hottop_auto.py.
- Integration tests: SSE transport, Auth0 authentication, command sequences.
Hardware verification
The implementation was verified with physical Hottop KN-8828B-2K+ hardware on October 25, 2025:
- Drum motor control
- Heat control (0-100%)
- Fan control (0-100%)
- Bean drop sequence
- Cooling system
- Continuous temperature readings (Bean & Chamber)
Security and Safety Considerations
Transport and Security Architecture
Why SSE (Server-Sent Events)?
Although both MCP servers currently run on the same machine as the agent (hint hint: stdio transport would be simpler), we designed for a distributed architecture from the start. The plan is to eventually deploy:
- Roasting MCP servers need to run close to the hardware - Running on the machine physically connected to the roaster and microphone.
- Agent on a separate device - A cloud server or different local machine for orchestration.
This approach means we could potentially use a low powered computer (such as RaspBerry PI) for the servers and also make it easier to plugh and start instead of having to use a laptop next to roaster every time.
- SSE benefits: Real-time streaming, works over standard HTTP/HTTPS, firewall-friendly
- MCP compatibility: Follows MCP specification for HTTP+SSE transport
- Future-proof: Easy transition from localhost to remote deployment
Authentication and Authorisation with Auth0
Once MCP servers are exposed over the Internet / network, security becomes critical—especially for hardware control. This section briefly covers our approach for integrating Auth0 for authentication and authorisation.
Why Auth0?
- Ease of integration: Well-documented SDKs and middleware
- OAuth 2.0 Client Credentials: Perfect for machine-to-machine authentication
- Role-based access control: Granular permissions via scopes
- Bonus: Auth0 MCP Server for Warp Agent Mode to perform configuration tasks.
Security implementation:
- JWT validation: Every MCP request validates Auth0 JWT tokens
- Scope-based authorization:
- read:roaster - Status monitoring only (observer role)
- write:roaster - Full hardware control (operator role)
- admin:roaster - Administrative functions (future)
- Token expiration: JWTs expire, requiring regular re-authentication
This architecture ensures that only authorised clients can control the roaster, with full traceability of who did what and when—essential for safety-critical hardware operations.
Lessons Learned
It has been a fun side project seeing how far Warp Agent Mode (Coding Agent) and emerging MCP Servers for developer documentation (Context 7) and service access (Auth0 MCP Server) cam in terms of speeding up development process.
It is still required have a clear architecture, requirements and a final picture before starting. When these are used in conjunction with Agentic development tools, tasks could take several days can be completed in a day or so.
What Worked Well and Lessons Learned
- Standard MCP SDK: Provided solid foundation for both stdio and SSE transports.
-
SSE transport: Future-proofed the architecture for distributed deployment.
- Tested working with N8N, LangFlow and Python based local agents.
- Auth0 integration: Straightforward OAuth 2.0 implementation with role-based access control.
- Warp Agent Mode assistance: Accelerated MCP protocol understanding, test generation, and Auth0 middleware implementation.
- Context7 and Auth0 MCP servers: Using MCP servers to build MCP servers (via Warp) streamlined development.
- pyhottop library: Initial attempt failed, but pivoting to Artisan's proven protocol worked as expected.
-
MockRoaster simulation: Due to time restrictions, this was not explored sufficiently and ended up manually testing using local agents.
- This is needs to be revisited in the future especially to be able to test agent loop.
MCP-Specific Insights
- Transport choice matters: SSE enables remote deployment but requires careful auth implementation.
- Tool vs resource patterns: Tools for actions (hardware control), resources for data streams (status monitoring) so far working well with agents.
-
Idempotency is critical: Start/stop commands must be safe to call multiple times.
- Initial attempts caused hardware to go into start stop loop and required manual intervention.
-
Scope-based authorization: Fine-grained permissions (read:roaster vs write:roaster) essential for hardware safety.
- Although in the current integration mode, only a single client is used.
- Observability: Using Open Telemetry helped troubleshooting issues quickly.
- Testing strategies: Combination of unit tests (208 total), MockRoaster simulation, and manual hardware validation.
Real-World Usage Examples
Warp Agnt with Roaster Control (initial testing)
The following are sample prompts intended for testing the MCP server from Warp.
User: "Start the roaster"
Warp Agent Mode: [calls roaster_control MCP: start_roaster()]
"Roaster started. Ready to add beans."
User: "Check the roaster status"
Warp Agent Mode: [calls roaster_control MCP: read_roaster_status()]
"Status:
• Drum: Running
• Bean temp: 172°C
• Chamber temp: 185°C
• Heat: 0%
• Fan: 0%"
User: "Stop the drum"
Warp Agent Mode: [calls roaster_control MCP: stop_roaster()]
"Roaster drum stopped. Heat automatically turned off for safety."
What's Next: Part 3 Preview
Now that we have:
- A trained first crack detection model (Part 1).
- Built two MCP servers with hardware control + ML inference (Part 2).
- Used Auth0 for security and SSE transport for distributed deployment (Part 2).
In Part 3: Building an Autonomous Roasting Agent, we'll bring it all together:
- Comparing multiple Agent frameworks and assessing their suitability for such long running workflows.
- N8N
- LangFlow
- Python based
- Using Microsoft Agent Framework
- Using OpenAI Python SDK
- Real-time decision making: Agent analyses temperature trends, RoR, and first crack to adjust roast.
- Extending OpenTelemetry observability: Distributed tracing across agent + MCP servers + hardware.
-
Safety systems:
- Temperature bounds monitoring.
- Emergency stop on anomalies.
- Human override via UI.
- Full end-to-end test: Press start -> Preheat -> Add beans -> Hands off -> First crack -> Development -> Drop -> (hope for) Perfect roast :)
The goal: An AI that roasts coffee consistently, safely, and (hopefully) better than manual control.
Resources
MCP & Standards:
- Model Context Protocol Spec
- Official MCP Python SDK - Used in this project
Project Code:
- Coffee Roasting Repository - Complete source code
- First Crack Detector MCP
- Roaster Control MCP
Hardware & Serial Communication:
- Artisan Roaster Scope - Source of Hottop protocol implementation
- pyserial Documentation - USB serial communication
- Hottop KN-8828B-2K+ - Roaster hardware
Authentication:
- Auth0 Documentation - Identity provider
- OAuth 2.0 Client Credentials - Machine-to-machine auth
Tools:
- Warp Terminal - AI-assisted development environment
- Auth0 MCP Server - Used via Warp for Auth0 configuration
- Warp MCP Documentation
- Context7 MCP Server - Used for documentation lookup during development





Top comments (0)