Metadata-Version: 2.4
Name: calculator-mcp-rubens
Version: 0.3.0
Summary: A calculator MCP server
License-Expression: MIT
License-File: LICENSE
Keywords: math,calculator,utility
Author: Rubens Gomes
Author-email: rubens.s.gomes@gmail.com
Requires-Python: >=3.14.0,<4.0.0
Classifier: Programming Language :: Python :: 3
Requires-Dist: calculator-lib-rubens (>=0.2.0)
Requires-Dist: fastmcp (>=3.4.7,<4.0.0)
Requires-Dist: py-key-value-aio[disk] (>=0.4.5,<0.5.0)
Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
Project-URL: Documentation, https://github.com/rubensgomes/calculator-mcp/README.md
Project-URL: Homepage, https://github.com/rubensgomes/calculator-mcp/
Project-URL: Repository, https://github.com/rubensgomes/calculator-mcp/
Description-Content-Type: text/markdown

# Calculator MCP Server

An MCP (Model Context Protocol) server that exposes calculator operations as
tools. Each tool delegates computation to the `calculator-lib-rubens` library.

## 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)

## Prerequisites

- Python 3.14+
- [Poetry](https://python-poetry.org/) for dependency management
- Docker 23+ with the buildx and compose plugins (optional, for running the
  server in a container)

## Installation

```bash
poetry install
```

## Configuration

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:

```bash
export CALCULATOR_MCP_CONFIG=/path/to/your/config.yaml
```

When `CALCULATOR_MCP_CONFIG` is not set, the bundled default is used
automatically.

The configuration file has two sections:

```yaml
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 port
```

The `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):

```bash
# requires poetry to be installed
poetry install # only needed once
poetry run calculator-mcp
```

**As a Python module:**

```bash
# requires poetry to be installed
poetry install # only needed once
eval $(poetry env activate)
python -m calculator_mcp
deactivate
```

**With a custom configuration:**

```bash
# requires poetry to be installed
poetry install # only needed once
export CALCULATOR_MCP_CONFIG=/path/to/your/config.yaml
poetry run calculator-mcp
```

## Running the Server with Docker

The server can also run as a container. See [DOCKER.md](DOCKER.md) for the
full reference.

**Build the image:**

```bash
# requires Docker to be installed and running
docker build -t calculator-mcp:0.2.16 -t calculator-mcp:latest .
```

**Run the container:**

```bash
docker run -d --name calculator-mcp -p 9000:9000 \
    --restart unless-stopped calculator-mcp:0.2.16
```

**Verify it is up:**

```bash
curl http://127.0.0.1:9000/health     # -> OK
```

**With Docker Compose:**

```bash
docker compose up --build -d
docker compose logs -f calculator-mcp
docker compose down
```

Notes:

- The container listens on `0.0.0.0:9000`, per the bundled `config.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_CONFIG`
  to 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](#running-the-server) above.

**Run the client:**

```bash
# requires poetry to be installed
poetry install # only needed once
eval $(poetry env activate)
python tests/integration/client.py
deactivate
```

## Add MCP Server to Claude Code

- Add the MCP server to Claude Code using project scope. The file `.mcp.json` is
  added to the project root folder:

    ```bash
    # 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](https://google.github.io/styleguide/pyguide.html).
All docstrings use the Google format with `Args:`, `Returns:`, and `Raises:`
sections where applicable. Compliance is enforced via pylint, black, isort,
and mypy.

## Development

```bash
# 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_mcp
```

All 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 support
```

## License

See [LICENSE](LICENSE) for details.

