Model Context Protocol (MCP) is revolutionizing how AI assistants interact with external tools and services. In this guide, we’ll build a simple calculator server that demonstrates the core concepts of MCP by creating a tool that Claude (or other MCP clients) can use to perform mathematical calculations.

What is MCP?

The Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect to data sources and tools. Instead of hardcoding integrations, MCP allows you to create servers that expose tools, resources, and prompts that AI assistants can dynamically discover and use.

Key Components

  • MCP Server: Exposes tools and resources (like our calculator)
  • MCP Client: AI assistants like Claude Desktop that consume MCP services
  • Tools: Functions that the AI can call (like our calculate function)
  • JSON-RPC: The underlying communication protocol

Building the Calculator Server

Let’s start by examining our MCP calculator server implementation:

package main

import (
    "context"
    "fmt"
    "log"
    "github.com/mark3labs/mcp-go/mcp"
    "github.com/mark3labs/mcp-go/server"
)

func main() {
    // Create MCP server
    s := server.NewMCPServer("calculator-server", "0.1.0")

    // Add calculator tool
    s.AddTool(mcp.NewTool(
        "calculate",
        mcp.WithDescription("Perform basic mathematical operations like add, subtract, multiply, and divide on two numbers"),
        mcp.WithString("expression",
            mcp.Description("A mathematical expression to evaluate (e.g., '2 + 3', '10 * 5', '15 / 3')"),
            mcp.Required(),
        ),
    ), handleCalculate)

    // Serve using stdio
    if err := server.ServeStdio(s); err != nil {
        log.Fatalf("Server error: %v", err)
    }
}

Tool Registration

The heart of our MCP server is tool registration. We define:

  • Tool name: calculate
  • Description: What the tool does
  • Parameters: Input schema (expression string)
  • Handler: The function that processes requests

Understanding the MCP Protocol Flow

1. Tool Name Resolution

When you configure an MCP server in Claude Desktop, it gets a namespace:

local__calculator__calculate
│     │           │
│     │           └── Function: "calculate" 
│     └── Category: "calculator"  (from config)
└── Namespace: "local"

The server uses simple tool names such as “calculate”, but the client adds namespace prefixes for organization.

2. Client-Server Communication

The communication follows this JSON-RPC flow:

Tool Discovery

First, the client asks for available tools:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list",
  "params": {}
}

Server responds with:

{
  "id": 2,
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {
        "name": "calculate",
        "description": "Perform basic mathematical operations like add, subtract, multiply, and divide on two numbers",
        "inputSchema": {
          "properties": {
            "expression": {
              "description": "A mathematical expression to evaluate (e.g., '2 + 3', '10 * 5', '15 / 3')",
              "type": "string"
            }
          },
          "required": ["expression"],
          "type": "object"
        }
      }
    ]
  }
}

Tool Execution

When Claude wants to calculate “3 + 3”, it sends:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "calculate",
    "arguments": {
      "expression": "3 + 3"
    }
  }
}

Our server processes this and responds:

{
  "id": 3,
  "jsonrpc": "2.0",
  "result": {
    "content": [
      {
        "text": "6",
        "type": "text"
      }
    ]
  }
}

Testing the MCP Server

I’ve created a test client to help debug MCP servers. Here’s how the interaction looks:

go run -tags=client client.go /home/yina/go/bin/mcp-calculator-server

Test Results

 Starting MCP server: /home/yina/go/bin/mcp-calculator-server

============================================================
  MCP Client - Choose an action:
1. Initialize connection
2. List available tools  
3. Calculate 3 + 3
4. Calculate custom expression
5. Send custom JSON-RPC message
6. Exit
============================================================

Configuration and Setup

Claude Desktop Configuration

Add this to the Claude Desktop configuration:

{
  "mcpServers": {
    "calculator": {
      "command": "/path/to/mcp-calculator-server"
    }
  }
}

The key "calculator" becomes the category in the namespaced tool name.

Installation

go install github.com/yinebebt/mcp-calculator-server

Key Insights

1. Naming Convention

  • Server side: Use simple, descriptive names (calculate)
  • Client side: Automatically adds namespacing (local__calculator__calculate)
  • Configuration: The category comes from the MCP client config

2. Protocol Structure

  • Initialization: Establish connection and capabilities
  • Discovery: List available tools
  • Execution: Call tools with parameters and return structured results

3. Error Handling

Proper error responses follow the JSON-RPC spec:

{
  "error": {
    "code": -32602,
    "message": "tool 'invalid-tool' not found: tool not found"
  },
  "id": 3,
  "jsonrpc": "2.0"
}

Real-World Usage

Once configured, you can ask Claude:

  • “Can you calculate 25 * 4?”
  • “What’s 15 divided by 3?”
  • “Help me with this math: (10 + 5) * 2”

Claude will automatically use the calculator server to provide accurate results.

Conclusion

Building an MCP server is straightforward once you understand the protocol flow. The key principles are:

  1. Simple tool registration with clear descriptions
  2. Proper JSON-RPC handling for communication
  3. Structured responses that clients can process
  4. Good error handling for robust operation

This calculator example demonstrates the fundamentals, but MCP can power much more complex integrations - from database queries to API calls to file system operations.

The future of AI assistance lies in this kind of modular, protocol-driven architecture where AI assistants can dynamically discover and use the tools they need to help users accomplish their goals.


Source code available at: github.com/yinebebt/mcp-calculator-server