mcp server
mcp-calc
Production-grade MCP server and agent, 8,000 lines of Go. Built entirely from specification using a manual orchestrator.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 23, 2026MCP Calculator Server
A mathematical expression evaluator exposed via MCP (Model Context Protocol). Built as a learning project for Go patterns, observability, and modern APIs.
Note: This is a work in progress. Tests for the core calculator logic have been verified. The MCP server and agent mode are still being verified.
Supports: +, -, *, /, parentheses (), and negative numbers with proper operator precedence.
See docs/VISION.md for project goals and docs/ARCHITECTURE.md for design details.
Project Structure
mcp-calc/
├── cmd/
│ ├── calculator/ # CLI REPL interface
│ └── mcp-server/ # MCP server entry point
├── internal/
│ ├── agent/ # Agent mode (LLM-based equation extraction)
│ ├── calculator/ # Core calculation logic
│ ├── config/ # Configuration management
│ ├── evaluator/ # Evaluator interface (local/MCP modes)
│ ├── llm/ # LLM provider interface (OpenAI-compatible)
│ ├── mcp/ # MCP protocol implementation
│ └── observability/ # OpenTelemetry instrumentation
├── magefiles/ # Mage build targets (build, test, clean)
├── bin/ # Built binaries (gitignored)
├── .beads/ # Issue tracker (DO NOT EDIT MANUALLY)
└── go.mod
Build
We use Mage for build automation:
# Install mage (one time)
go install github.com/magefile/mage@latest
# Build all binaries to bin/
mage build
# Run tests with race detection
mage test
# Remove bin/
mage clean
Usage
Docker (Recommended)
docker build -t mcp-calc .
docker run -i --rm mcp-calc
See docs/DEPLOYMENT.md for full container documentation including Claude Desktop integration.
CLI Calculator (REPL)
Run the interactive calculator:
mage build
./bin/calculator
# With OpenTelemetry tracing:
./bin/calculator --enable-otel
MCP Server
Run the calculator as an MCP (Model Context Protocol) server:
mage build
./bin/mcp-server
# With OpenTelemetry tracing:
./bin/mcp-server --trace
The MCP server:
- Listens on stdio for MCP protocol messages
- Exposes a
calculatetool for evaluating mathematical expressions - Supports graceful shutdown with Ctrl+C or SIGTERM
- Runs in quiet mode by default (no stderr noise)
Configuration
Command-Line Flags
./bin/mcp-server --help
Options:
-trace enable OpenTelemetry trace output
-max-expr-len maximum expression length (default: 1000, 0 = no limit)
-version show version and exit
Environment Variables
| Variable | Description | Default |
|---|---|---|
MCP_TRACE | Enable tracing (true or 1) | false |
MCP_MAX_EXPRESSION_LENGTH | Max expression length | 1000 |
MCP_REQUEST_TIMEOUT | Request timeout (e.g., 30s, 1m) | 30s |
MCP_SERVER_NAME | Server name for MCP protocol | calculator-mcp-server |
MCP_SERVER_VERSION | Server version for MCP protocol | 1.0.0 |
Environment variables are loaded first, then command-line flags override them.
Performance
Run benchmarks:
go test -bench=. -benchmem ./internal/calculator/...
Benchmark Results (Apple M2 Max)
| Operation | Expression | ops/sec | ns/op | allocs |
|---|---|---|---|---|
| Simple eval | 2 + 3 | ~1.4M | 818 ns | 23 |
| Medium eval | 2 + 3 * 4 | ~1M | 1,096 ns | 30 |
| Complex eval | 10 operators | ~420K | 2,811 ns | 66 |
| Long chain | 15 additions | ~355K | 3,370 ns | 81 |
Key characteristics:
- Linear scaling: Performance scales linearly with expression complexity
- Allocation overhead: ~23 allocations for simple expressions, ~3-4 per additional operator
- Thread-safe: Parallel evaluation shows good scalability (~1M ops/sec with 12 cores)
- Tokenization: ~8M ops/sec for simple expressions (hot path is optimized)
MCP Client Mode
The calculator can operate as an MCP client, connecting to the MCP server for remote calculation. This separates the user interface from the calculation engine, enabling:
- Scalability: Run the calculation server on a different machine
- Isolation: Keep the calculation engine in a separate process
- Flexibility: Multiple clients can share one server
Architecture
┌─────────────────────┐ MCP Protocol ┌─────────────────────┐
│ Calculator CLI │◄────(JSON-RPC)────────►│ MCP Server │
│ (MCP Client) │ over stdio │ │
│ │ │ ┌───────────────┐ │
│ --use-mcp-server │ │ │ Calculator │ │
│ enables client mode│ │ │ Engine │ │
└─────────────────────┘ │ └───────────────┘ │
└─────────────────────┘
Interactive REPL Mode
Connect to the MCP server for interactive calculations:
# Build both binaries
mage build
# Run in MCP client mode (launches server automatically)
./bin/calculator --use-mcp-server
Example session:
Calculator REPL v1.0 (MCP subprocess mode)
Enter mathematical expressions (e.g., 2 + 3 * 4)
Type 'quit' or 'exit' to exit, or press Ctrl+D
> 2 + 3 * 4
= 14
> (2 + 3) * 4
= 20
> -5 + 8
= 3
Single-Expression Mode
Evaluate a single expression and exit (useful for shell scripting):
# Local evaluation (default)
./bin/calculator --evaluate '2 + 3 * 4'
# Output: 14
# MCP client mode
./bin/calculator --use-mcp-server --evaluate '(10 - 2) / 4'
# Output: 2
# Suppress non-result output
./bin/calculator --disable-nonresult-output --evaluate '100 / 4'
# Output: 25
Shell Scripting Examples
# Use in a script
result=$(./bin/calculator --evaluate '2 + 2')
echo "The answer is $result"
# Chain calculations
a=$(./bin/calculator --evaluate '10 * 5')
b=$(./bin/calculator --evaluate "$a / 2")
echo "Final result: $b" # 25
# Check exit codes for error handling
if ./bin/calculator --disable-nonresult-output --evaluate '10 / 0' 2>/dev/null; then
echo "Success"
else
echo "Calculation failed (exit code: $?)"
fi
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Calculation error (invalid expression, division by zero) |
| 2 | Connection error (MCP server not running, timeout) |
| 3 | Invalid arguments |
When to Use Local vs MCP Mode
| Use Case | Recommended Mode |
|---|---|
| Quick calculations | Local (default) |
| Shell scripting | Local with --evaluate |
| Testing MCP integration | MCP mode (--use-mcp-server) |
| Distributed architecture | MCP mode (--use-mcp-server) |
| Learning MCP protocol | MCP mode with --enable-otel |
Agent Mode
Agent mode allows the calculator to solve word problems by using an LLM to extract mathematical equations, then evaluating them. This is useful for natural language math queries.
Requirements
Agent mode requires an OpenAI-compatible LLM API. This includes:
- OpenAI API
- LM Studio (local)
- Ollama with OpenAI-compatible endpoint
- Any other OpenAI-compatible service
Agent Configuration
# Required flags for agent mode
./bin/calculator --mode agent --llm-url URL --llm-model MODEL
# Example with LM Studio (local)
./bin/calculator --mode agent \
--llm-url http://localhost:1234/v1 \
--llm-model local-model
# Example with OpenAI
./bin/calculator --mode agent \
--llm-url https://api.openai.com/v1 \
--llm-model gpt-4 \
--llm-api-key $OPENAI_API_KEY
Agent Environment Variables
| Variable | Description |
|---|---|
CALC_MODE | Calculator mode: simple (default) or agent |
LLM_URL | LLM API base URL |
LLM_MODEL | LLM model name |
LLM_API_KEY | LLM API key (optional for local models) |
Interactive Agent REPL
./bin/calculator --mode agent --llm-url http://localhost:1234/v1 --llm-model local-model
Example session:
Calculator Agent REPL v1.0
Enter word problems (e.g., 'What is 5 plus 3?')
Type 'quit' or 'exit' to exit, or press Ctrl+D
agent> What is 5 plus 3?
Equation: 5 + 3
= 8
agent> If I have 10 apples and give away 4, how many do I have left?
Equation: 10 - 4
= 6
agent> I bought 3 items at $5 each and 2 items at $8 each. What's the total?
Equation: 3 * 5 + 2 * 8
= 31
Agent Single Expression Mode
# Solve a word problem and exit
./bin/calculator --mode agent \
--llm-url http://localhost:1234/v1 \
--llm-model local-model \
--evaluate "What is twice the sum of 4 and 7?"
# Output:
# Equation: 2 * (4 + 7)
# 22
# Quiet mode (result only)
./bin/calculator --mode agent \
--llm-url http://localhost:1234/v1 \
--llm-model local-model \
--disable-nonresult-output \
--evaluate "Split 100 dollars among 4 people"
# Output: 25
Supported Word Problem Types
The agent can extract equations from various word problem formats:
- Addition: "What is 5 plus 3?"
- Subtraction: "If I have 10 and give away 4..."
- Multiplication: "6 boxes with 12 items each"
- Division: "Split 100 among 4 people"
- Complex: "3 items at $5 and 2 items at $8"
- Percentages: "25% of 80" →
80 * 0.25 - Grouping: "Twice the sum of 4 and 7" →
2 * (4 + 7)
Agent Error Handling
If the LLM cannot extract a valid equation, an error is returned:
agent> Hello, how are you?
Error: failed to extract equation: invalid equation in response: no valid equation could be extracted
Troubleshooting
MCP Connection Issues
Server not running:
Error: failed to connect to MCP server: failed to start MCP server: exec: "./bin/mcp-server": no such file or directory
Solution: Build the MCP server first:
mage build
Connection timeout:
Error: connection error: request timeout
Solution: The server may be overloaded or unresponsive. Check if the server process is running and healthy.
Protocol errors:
Error: protocol error: failed to unmarshal response
Solution: Ensure client and server versions are compatible. Rebuild both binaries.
Calculation Errors
Division by zero:
Error: calculation failed: division by zero
Invalid expression:
Error: calculation failed: invalid character '@' in expression
Empty expression:
Error: expression cannot be empty