Skip to main content
Glama

Temporal Nexus Calculator MCP Server

README.md14.9 kB
# Temporal Nexus MCP Example A comprehensive sample application demonstrating how to bridge [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) tools with [Temporal's Nexus RPC framework](https://docs.temporal.io/nexus). This calculator provides various mathematical operations through MCP, backed by the reliability and durability of Temporal workflows. Uses a [forked version](https://github.com/steveandroulakis/nexus-mcp-python) of [@bergundy](https://github.com/bergundy)'s nexus-mcp-python, a lightweight way of adding MCP capability to Temporal Nexus Operations. [![Watch the demo](./assets/demo.jpg)](https://drive.google.com/file/d/1oZ_fXj14stUpOaWlao1dJfAzHoODWH3H/view?usp=sharing) [Watch the 4 minute demo](https://drive.google.com/file/d/1oZ_fXj14stUpOaWlao1dJfAzHoODWH3H/view?usp=sharing) to understand how interaction works. [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/) [![MCP](https://img.shields.io/badge/protocol-MCP-green.svg)](https://modelcontextprotocol.io/) [![Temporal](https://img.shields.io/badge/powered%20by-Temporal-purple.svg)](https://temporal.io/) ## Features ### Calculator Operations - **Expression Evaluation**: Safely evaluate mathematical expressions using AST parsing - **Basic Arithmetic**: Add, subtract, multiply, divide operations - **Advanced Operations**: Power calculations, list summation - **Built-in Functions**: Support for abs, round, max, min, sum ### MCP Integration - **Automatic Tool Discovery**: All calculator operations exposed as MCP tools - **Type-Safe**: Full Pydantic model validation - **Error Handling**: Comprehensive error handling with meaningful messages ### Temporal Benefits - **Reliability**: Operations backed by Temporal's fault-tolerant execution - **Durability**: Long-running calculations survive process restarts - **Observability**: Full visibility through Temporal UI with workflow and activity executions - **Scalability**: Distribute across multiple workers - **Monitoring**: Each calculator operation creates visible workflow executions for easy debugging ## Quick Start ### Prerequisites - Python 3.13+ - Running Temporal server (local dev server or Temporal Cloud) - [Temporal CLI](https://docs.temporal.io/cli) installed ### Installation 1. **Clone and set up the project:** ```bash cd nexus-mcp-calculator uv sync --dev ``` 2. **Set up Temporal infrastructure:** ```bash ./scripts/setup_temporal.sh ``` This creates: - Handler namespace (`my-handler-namespace`) - where the calculator worker runs - Caller namespace (`my-caller-namespace`) - where the MCP gateway runs - Nexus endpoint (`mcp-gateway`) - bridges the two namespaces ### Running the Application The application consists of two main components that need to run simultaneously: #### 1. Start the Calculator Worker ```bash uv run python -m nexus_mcp_calculator.worker ``` This starts the Temporal worker that handles the actual calculator operations. #### 2. Start the MCP Server ```bash uv run python -m nexus_mcp_calculator.mcp_server ``` This starts the MCP server that bridges MCP clients to the Temporal worker. ## Usage Examples ### Using from a Temporal Workflow The calculator can be called from within Temporal workflows: ```bash uv run python -m nexus_mcp_calculator.demo_workflow ``` This demonstrates: - Tool discovery through MCP - Calling calculator operations from workflows - Handling results and errors - Integration with Temporal's execution model ### Using with MCP Clients #### Claude Desktop Configuration Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { "mcpServers": { "nexus-calculator": { "command": "uv", "args": ["run", "python", "-m", "nexus_mcp_calculator.mcp_server"], "cwd": "/path/to/nexus-mcp-calculator" } } } ``` #### Goose Extension Configuration Add this command: `uv run --directory /path/to/sample python -m nexus_mcp_calculator.mcp_server` #### Available Tools Once connected, you'll have access to these calculator tools: - `calculate` - Evaluate mathematical expressions - `add` - Add two numbers - `subtract` - Subtract two numbers - `multiply` - Multiply two numbers - `divide` - Divide two numbers - `power` - Raise to a power - `sum_list` - Sum a list of numbers ### Example MCP Calls ```python # Expression evaluation calculate({"expression": "2 + 3 * 4"}) # Returns: {"result": 14.0, "expression": "2 + 3 * 4"} # Basic arithmetic add({"a": 10, "b": 5}) # Returns: {"result": 15.0, "operation": "10.0 + 5.0 = 15.0"} # List operations sum_list({"numbers": [1, 2, 3, 4, 5]}) # Returns: {"result": 15.0, "operation": "sum([1, 2, 3, 4, 5]) = 15.0"} # Advanced expressions calculate({"expression": "abs(-10) + round(3.14159, 2)"}) # Returns: {"result": 13.14, ...} ``` ## Architecture ``` ┌─────────────────┐ MCP Protocol ┌──────────────────┐ │ MCP Client │◄──────────────────►│ MCP Server │ │ (Claude Desktop)│ │ (mcp_server.py) │ └─────────────────┘ └──────────────────┘ │ │ Temporal Client ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Temporal Cluster │ │ │ │ ┌─────────────────┐ Nexus RPC ┌────────────────────────────┐│ │ │ Caller Namespace│◄─────────────►│ Handler Namespace ││ │ │ │ │ ││ │ │ ┌─────────────┐│ │ ┌──────────────────────┐ ││ │ │ │ MCP Gateway ││ │ │ Calculator Worker │ ││ │ │ │ Workflow ││ │ │ │ ││ │ │ └─────────────┘│ │ │ ┌──────────────────┐ │ ││ │ └─────────────────┘ │ │ │ Service Handlers │ │ ││ │ │ │ └──────────────────┘ │ ││ │ │ └──────────────────────┘ ││ │ └────────────────────────────┘│ └─────────────────────────────────────────────────────────────────┘ ``` ## Configuration ### Command Line Options #### Worker (`worker.py`) ```bash uv run python -m nexus_mcp_calculator.worker --help Options: --temporal-host TEXT Temporal server host (default: localhost:7233) --namespace TEXT Temporal namespace (default: my-handler-namespace) --task-queue TEXT Task queue name (default: mcp) ``` #### MCP Server (`mcp_server.py`) ```bash uv run python -m nexus_mcp_calculator.mcp_server --help Options: --temporal-host TEXT Temporal server host (default: localhost:7233) --namespace TEXT Temporal namespace (default: my-caller-namespace) --endpoint TEXT Nexus endpoint name (default: mcp-gateway) ``` #### Demo Workflow (`demo_workflow.py`) ```bash uv run python -m nexus_mcp_calculator.demo_workflow --help Options: --temporal-host TEXT Temporal server host (default: localhost:7233) --namespace TEXT Temporal namespace (default: my-caller-namespace) --task-queue TEXT Task queue name (default: calculator-demo) --endpoint TEXT Nexus endpoint name (default: mcp-gateway) ``` ### Setup Scripts #### Setup Infrastructure ```bash ./scripts/setup_temporal.sh --help Options: --handler-namespace NAME Handler namespace (default: my-handler-namespace) --caller-namespace NAME Caller namespace (default: my-caller-namespace) --endpoint-name NAME Nexus endpoint name (default: mcp-gateway) --task-queue NAME Task queue name (default: mcp) ``` #### Cleanup Infrastructure ```bash ./scripts/cleanup_temporal.sh --help Options: --handler-namespace NAME Handler namespace (default: my-handler-namespace) --caller-namespace NAME Caller namespace (default: my-caller-namespace) --endpoint-name NAME Nexus endpoint name (default: mcp-gateway) ``` ## Development ### Project Structure ``` nexus-mcp-calculator/ ├── nexus_mcp_calculator/ # Main package │ ├── __init__.py # Package initialization │ ├── service.py # Nexus service definitions │ ├── service_handler.py # MCP-enabled service handlers (workflow operations) │ ├── workflows.py # Temporal workflows for calculator operations │ ├── activities.py # Temporal activities for actual calculations │ ├── worker.py # Temporal worker (registers workflows & activities) │ ├── mcp_server.py # MCP server/gateway │ └── demo_workflow.py # Demonstration workflow ├── scripts/ # Setup and utility scripts │ ├── setup_temporal.sh # Infrastructure setup │ └── cleanup_temporal.sh # Infrastructure cleanup ├── pyproject.toml # Project configuration ├── README.md # This file └── CLAUDE.md # Development documentation ``` ### Code Quality ```bash # Format code uv run ruff format # Lint code uv run ruff check # Type checking uv run mypy nexus_mcp_calculator/ # Run tests uv run pytest ``` ### Adding New Operations 1. **Define request/response models in `service.py`:** ```python class NewOperationRequest(BaseModel): value: float = Field(..., description="Input value") class NewOperationResponse(BaseModel): result: float = Field(..., description="Result") ``` 2. **Add operation to service:** ```python @nexusrpc.service(name="Calculator") class CalculatorService: new_operation: nexusrpc.Operation[NewOperationRequest, NewOperationResponse] ``` 3. **Create activity in `activities.py`:** ```python @activity.defn async def new_operation_activity(input: NewOperationRequest) -> NewOperationResponse: activity.logger.info(f"New operation activity called with: {input.value}") result = process_value(input.value) return NewOperationResponse(result=result) ``` 4. **Create workflow in `workflows.py`:** ```python @workflow.defn class NewOperationWorkflow: @workflow.run async def run(self, input: NewOperationRequest) -> NewOperationResponse: return await workflow.execute_activity( new_operation_activity, input, start_to_close_timeout=workflow.timedelta(seconds=30), ) ``` 5. **Add workflow_run_operation to `service_handler.py`:** ```python @nexus.workflow_run_operation async def new_operation( self, ctx: nexus.WorkflowRunOperationContext, input: NewOperationRequest ) -> nexus.WorkflowHandle[NewOperationResponse]: return await ctx.start_workflow( NewOperationWorkflow.run, input, id=f"new_operation-{uuid.uuid4()}", ) ``` 6. **Register in `worker.py`:** ```python # Add to workflows list NewOperationWorkflow, # Add to activities list new_operation_activity, ``` The operation will be automatically discovered and exposed as an MCP tool, with full workflow and activity visibility in the Temporal UI. ### Excluding Operations from MCP Use the `@exclude` decorator to prevent operations from being exposed as MCP tools: ```python from nexusmcp import exclude @exclude @nexusrpc.handler.sync_operation async def internal_operation(self, _ctx, input): # This won't be available to MCP clients pass ``` ## Troubleshooting ### Common Issues 1. **"Namespace not found" errors** - Ensure you've run `./scripts/setup_temporal.sh` - Check that your Temporal server is running 2. **"Endpoint not found" errors** - Verify the Nexus endpoint was created successfully - Check endpoint name matches between worker and MCP server 3. **MCP connection issues** - Ensure both worker and MCP server are running - Check that the worker has started and registered handlers - Verify namespace and endpoint configuration 4. **Tool discovery fails** - Check worker logs for service registration - Verify MCP server can connect to Temporal - Ensure endpoint is routing to correct task queue ### Viewing Temporal UI Access the Temporal Web UI at http://localhost:8233 to: - **Monitor workflow executions**: Every calculator operation now creates a visible workflow - **Track activity executions**: See the actual calculation activities within workflows - **View task queues and workers**: Monitor worker health and task processing - **Debug failed operations**: Full stack traces and execution history - **Inspect Nexus endpoints**: Monitor cross-namespace communication - **Observe operation patterns**: See timing, success rates, and performance metrics ### Logging Enable debug logging: ```python import logging logging.basicConfig(level=logging.DEBUG) ``` ## Security Considerations ### Expression Evaluation The calculator uses AST parsing for safe expression evaluation: - Only allows mathematical operators and functions - Prevents arbitrary code execution - Validates input before processing ### Allowed Operations - Arithmetic: `+`, `-`, `*`, `/`, `%`, `**` - Functions: `abs`, `round`, `max`, `min`, `sum` - Constants: Numbers only ### Blocked Operations - Variable assignment - Function definitions - Import statements - File system access - Network operations ## License This project is licensed under the MIT License. See the LICENSE file for details.

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/steveandroulakis/temporal-nexus-mcp-demo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server