calculator-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@calculator-mcpround 3.14159 to 2 decimal places"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Calculator MCP Server
calculator-mcp is a small MCP server that exposes 16 arithmetic operations as callable tools for an LLM. It contains no math of its own — every tool is a thin synchronous wrapper that logs its arguments and delegates to a shared Calculator instance from the external calculator-lib-rubens package.
Features
16 calculator tools available via MCP:
Two-operand operations: add, subtract, multiply, divide, power,
nth_root, modulo, floor_divide
Single-operand operations: sqrt, absolute, floor, ceil, log10,
ln, exp
Rounding: round_number (with configurable decimal places)
Related MCP server: Simple Calculator MCP Server
Prerequisites
Python 3.14+
Poetry for dependency management
Docker 23+ with the buildx and compose plugins (optional, for running the server in a container)
Installation
poetry installConfiguration
The server ships with a default config.yaml bundled inside the package. To
override it, set the CALCULATOR_MCP_CONFIG environment variable to the
absolute path of your custom configuration file:
export CALCULATOR_MCP_CONFIG=/path/to/your/config.yamlWhen CALCULATOR_MCP_CONFIG is not set, the bundled default is used
automatically.
The configuration file has two sections:
server:
transport: "http" # "stdio" or "http"
host: "0.0.0.0" # Host for HTTP transport (0.0.0.0 = all interfaces)
port: 9000 # Port for HTTP transport
timeout: 10 # Tool execution timeout in seconds
client:
is_oauth: false # Enable OAuth authentication
url: "http://127.0.0.1:9000/mcp" # Server URL for HTTP transport
token_dir: "/home/user/.fastmcp" # OAuth token storage directory
callback_port: 10000 # OAuth callback server portThe logging section controls Python logging via dictConfig. The default
configuration logs calculator_mcp messages at INFO level to stderr.
Running the Server
There are three ways to start the server:
Console script (installed by Poetry):
# requires poetry to be installed
poetry install # only needed once
poetry run calculator-mcpAs a Python module:
# requires poetry to be installed
poetry install # only needed once
eval $(poetry env activate)
python -m calculator_mcp
deactivateWith a custom configuration:
# requires poetry to be installed
poetry install # only needed once
export CALCULATOR_MCP_CONFIG=/path/to/your/config.yaml
poetry run calculator-mcpRunning the Server with Docker
The server can also run as a container. See DOCKER.md for the full reference.
Build the image:
# requires Docker to be installed and running
docker build --build-arg VERSION="$(poetry version -s)" \
-t "calculator-mcp:$(poetry version -s)" -t calculator-mcp:latest .Run the container:
docker run -d --name calculator-mcp -p 9000:9000 \
--restart unless-stopped "calculator-mcp:$(poetry version -s)"Verify it is up:
curl http://127.0.0.1:9000/health # -> OKWith Docker Compose:
docker compose up --build -d
docker compose logs -f calculator-mcp
docker compose downNotes:
The container listens on
0.0.0.0:9000, per the bundledconfig.yaml.The MCP endpoint is
http://127.0.0.1:9000/mcp.The server runs as a non-root user (
uid=1001).To use a custom configuration, mount it and set
CALCULATOR_MCP_CONFIGto the mounted path.
Running the Client
A sample integration test client is provided in tests/integration/client.py
to demonstrate the MCP protocol with the server. It lists all available tools
and calls each one with sample arguments.
Important: The server must be running before you start the client. See Running the Server above.
Run the client:
# requires poetry to be installed
poetry install # only needed once
eval $(poetry env activate)
python tests/integration/client.py
deactivateAdd MCP Server to Claude Code
Add the MCP server to Claude Code using project scope. The file
.mcp.jsonis added to the project root folder:# It is assumed that the MCP server is running on http://127.0.0.1:9000 cd $(git rev-parse --show-toplevel) || exit claude mcp add \ --scope project \ --transport http \ calculator-mcp http://127.0.0.1:9000/mcp
Style Guide
This project follows the
Google Python Style Guide.
All docstrings use the Google format with Args:, Returns:, and Raises:
sections where applicable. Compliance is enforced via pylint, black, isort, and
mypy.
Development
# Run tests
poetry run pytest
# Run tests with coverage
poetry run pytest --cov
# Lint
poetry run pylint src/calculator_mcp
# Format code
poetry run black src tests
poetry run isort src tests
# Type check
poetry run mypy src/calculator_mcpAll four tools — pylint, black, isort and mypy — are declared in the
dev dependency group, so poetry install is all that is needed to run them.
Project Structure
calculator-mcp/
├── pyproject.toml # Project metadata, dependencies, tool config
├── Dockerfile # Multi-stage container image build
├── .dockerignore # Files excluded from the build context
├── docker-compose.yml # Compose service definition
├── DOCKER.md # Container build and deployment guide
├── src/calculator_mcp/
│ ├── __init__.py
│ ├── __main__.py # python -m calculator_mcp entry point
│ ├── config.py # Loads config.yaml, configures logging
│ ├── config.yaml # Bundled default runtime config
│ ├── main.py # CLI entry point, signal handling
│ └── server.py # FastMCP server with 16 @mcp.tool functions
└── tests/
├── __init__.py
├── test_config.py # Unit tests for config module
├── test_main.py # Unit tests for main module
├── test_server.py # Integration tests via MCP Client
├── test_tools.py # Unit tests for tool functions
└── integration/
├── __init__.py
└── client.py # Sample MCP client with OAuth supportLicense
See LICENSE for details.
MCP Protocol
The MCP protocol, briefly
MCP (Model Context Protocol) is an open standard for connecting LLM applications to external context and capabilities. The shape of it:
Wire format. JSON-RPC 2.0 — requests (with id), responses, and notifications. Nothing MCP-specific about the envelope; the protocol is the vocabulary of methods on top of it.
MCP Participants
Participants. A host (Claude Code, Claude Desktop, an agent app) runs one client per connected server. The connection is 1:1 and stateful.
MCP Lifecycle
Lifecycle:
client initializes request → server replies with its protocol version,capabilities, and serverInfo
client sends the notifications/initialized notification → normal operation.
Capabilities are negotiated at that handshake, so neither side calls methods the other never advertised.
MCP Server Primitives
Server primitives. Three things a server can offer:
Tools — model-controlled functions the LLM decides to invoke (tools/list, tools/call).
Resources — application-controlled data addressed by URI (resources/list, resources/read).
Prompts — user-controlled templates, typically surfaced as slash commands.
MCP Client Primitives
Client primitives. Sampling (server asks the client's model to complete something), roots (filesystem scope), and elicitation (server asks the user a question).
MCP Transport
Transports. Two standard ones:
stdio (server is a subprocess; JSON-RPC over newline-delimited stdin/stdout, with stderr free for logs) and
Streamable HTTP (a single /mcp endpoint taking POSTs, optionally upgrading to SSE for server→client streaming, with sessions tracked by an Mcp-Session-Id header). Remote HTTP servers authenticate with OAuth 2.1.
How This Project Implements the MCP Protocol
It doesn't hand-roll any of the protocol. FastMCP (fastmcp >=3.4.7) supplies the JSON-RPC layer, the initialize handshake, capability advertisement, session management, and both transports. The project's job is to declare what it serves.
Tool declaration is derived from Python
Each @mcp.tool-decorated function is turned into an MCP tool descriptor automatically:
The function name becomes the tool name (add, nth_root, round_number).
The type hints (a: float, b: float, decimals: int = 0) become the tool's JSON Schema inputSchema, including which parameters are required — that's what lets FastMCP reject bad arguments before your code runs.
The Google-style docstring becomes the tool description the model reads when deciding what to call. This is why src/calculator_mcp/server.py treats docstrings as a contract rather than internal commentary.
A raised ValueError (divide by zero, sqrt of a negative) is converted into a JSON-RPC tool error — tests/test_server.py asserts this by expecting ToolError from divide (1, 0).
Protocol-level metadata the server sets explicitly
mcp = FastMCP ("Calculator MCP Server", version=_VERSION, instructions="...", website_url=_HOMEPAGE)
instructions is part of the initialize response — server-level guidance the host can put in front of the model, summarizing the tool families so it doesn't have to infer them tool by tool.
Every tool also carries MCP behavioral annotations:
annotations={"readOnlyHint": True, "idempotentHint": True, "openWorldHint": False}
These are hints to the host, not enforcement: nothing is mutated, calling twice is safe, and the tool touches no external world. Hosts use them to decide whether a call needs a confirmation prompt — which is why a calculator can run unattended. timeout=_TIMEOUT (10s from config) bounds each call.
Transport
config.yaml selects the transport and main.py acts on it:
if transport == "http": mcp.run (transport="http", host=get_host (), port=get_port ()) else: mcp.run (transport="stdio")
The shipped default is http on 0.0.0.0:9000 — bound to all interfaces deliberately so the server is reachable from outside the container. The stdio path is what a host would use to launch it as a subprocess. Note the logging config sends handlers to ext://sys.stderr; under stdio that's mandatory, since stdout carries the JSON-RPC frames.
/health is registered via @mcp.custom_route — a plain Starlette route on the same ASGI app, outside the MCP protocol. Container orchestration needs a probe that doesn't speak JSON-RPC. tests/test_server.py::test_health_check exercises it in-process with httpx.ASGITransport over mcp.http_app (), no port required.
The client side
tests/integration/client.py is the mirror image — a real MCP client built from the same config module. It does the full round trip: client.ping (), client.list_tools (), then call_tool on each discovered tool with sample arguments. For the deployed instance at https://rubens-calculator-mcp.fastmcp.app/mcp it wraps fastmcp.client.auth.OAuth, persisting tokens in a DiskStore behind a FernetEncryptionWrapper keyed from OAUTH_STORAGE_ENCRYPTION_KEY, with a fixed callback port so the OAuth redirect URI stays stable across runs.
The unit tests use the same Client (mcp) API against the in-process server object, so tests go through genuine MCP tool dispatch rather than calling the Python functions directly.
Observability
config.yaml pre-wires loggers for the protocol internals — mcp.server.lowlevel.server, mcp.server.streamable_http, mcp.server.streamable_http_manager, mcp.client.streamable_http, plus httpx/httpcore — each at INFO with a comment saying to flip it to DEBUG to see the raw JSON-RPC messages or HTTP wire traffic. That's the debugging path when a host and this server disagree.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceA calculator server that exposes mathematical functions as tools (add, subtract, multiply, divide, square, power, square root), enabling language models to perform calculations through Model Context Protocol (MCP).
- AlicenseNot gradedqualityDmaintenanceEnables basic arithmetic operations (add, subtract, multiply, divide, modulo) via natural language, with a FastMCP-based server and client for exploring MCP tool calling.MIT
- FlicenseNot gradedqualityCmaintenanceAn advanced calculator MCP server that provides a wide range of mathematical operations over streamable HTTP, enabling users to perform complex calculations via natural language with any MCP client.
- AlicenseNot gradedqualityBmaintenanceA calculator MCP server built as part of a step-by-step tutorial that demonstrates core MCP primitives—tools, resources, and prompts—and can be upgraded to a live weather server.MIT
Related MCP Connectors
This MCP server enables users to perform scientific computations regarding linear algebra and vect…
Educational MCP server with 17 math/stats tools, visualizations, and persistent workspace
MCP server for generating rough-draft project plans from natural-language prompts.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/rubensgomes-org/calculator-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server