Skip to main content
Glama
ssvasan369

cbl-mcp-server

by ssvasan369
README.md
# COBOL MCP Server

A Model Context Protocol (MCP) server implementation written in COBOL. This server provides tools for tax calculations and demonstrates how COBOL can be used to build modern API services.

## Overview

This project implements an MCP server that communicates via JSON-RPC 2.0 over stdin/stdout. It provides:

- **Tax Calculation Tool**: Calculate 7.5% sales tax on any amount
- **MCP Protocol Compliance**: Supports initialize, tools/list, tools/call, and ping methods

## Project Structure

```
cbl-mcp-server/
├── src/
│   ├── server.cbl           # Main entry point and request loop
│   ├── transport.cbl        # I/O handling (read request, write response)
│   ├── parser.cbl           # JSON-RPC request parsing
│   ├── dispatcher.cbl       # Method routing
│   ├── response-builder.cbl # JSON-RPC response builders
│   └── tax-service.cbl      # Tax calculation logic
├── copybooks/
│   ├── CONSTANTS.cpy        # Protocol version constant
│   ├── STATUS.cpy           # Status flags (EOF, parsed)
│   ├── REQUEST.cpy          # Request data structure
│   ├── RESPONSE.cpy          # Response buffer structure
│   └── TOOL.cpy             # Tool definitions
├── Makefile                 # Build configuration
├── Dockerfile               # Container build
└── README.md                # This file
```

## Prerequisites

- GnuCOBOL compiler (`cobc`)
- Make build tool
- Docker (optional, for containerized deployment)

### Installing GnuCOBOL

**Ubuntu/Debian:**
```bash
sudo apt-get install gnucobol make
```

**macOS (Homebrew):**
```bash
brew install gnucobol
```

## Building

### Local Build

```bash
make
```

This produces the `mcp-server` executable.

### Docker Build

```bash
docker build -t cbl-mcp-server .
```

## Running

### Command Line

```bash
./mcp-server
```

The server reads JSON-RPC requests from stdin and writes responses to stdout.

### Docker

```bash
docker run --rm -i cbl-mcp-server
```

## Testing

Run the test suite to verify all functionality:

```bash
# Test with Docker (default)
node test.js

# Or with npm
npm test

# Test with local binary (requires GnuCOBOL installed)
USE_DOCKER=false node test.js
```

### Test Coverage

The test suite verifies:
- ✓ Server startup
- ✓ Initialize request/response
- ✓ Tools list endpoint
- ✓ Tax calculation (multiple amounts)
- ✓ Ping endpoint
- ✓ Error handling (unknown method)

Example output:
```
═══════════════════════════════════════════════════════
         CBL-MCP-SERVER TEST SUITE
═══════════════════════════════════════════════════════

  Test 1: Server startup
    ✓ Server started successfully

  Test 2: Initialize request
    ✓ Initialize response is valid

  Test 3: Tools list request
    ✓ Tools list response is valid

  Test 4-7: Tax calculations
    ✓ All tax calculations correct

  Test 8: Ping request
    ✓ Ping response is valid

  Test 9: Unknown method error handling
    ✓ Error response is valid

═══════════════════════════════════════════════════════
  Total: 9 | Passed: 9 ✓ | Failed: 0 ✗
═══════════════════════════════════════════════════════
```

## API Reference

### Methods

#### initialize

Initialize the MCP connection.

**Request:**
```json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}
```

**Response:**
```json
{
  "jsonrpc":"2.0",
  "id":1,
  "result":{
    "protocolVersion":"2025-06-18",
    "capabilities":{"tools":{}},
    "serverInfo":{"name":"cbl-mcp","version":"1.0.0"}
  }
}
```

#### tools/list

List available tools.

**Request:**
```json
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
```

**Response:**
```json
{
  "jsonrpc":"2.0",
  "id":2,
  "result":{
    "tools":[{
      "name":"calculate_tax",
      "description":"Calculate 7.5 percent sales tax on an amount",
      "inputSchema":{
        "type":"object",
        "properties":{
          "amount":{"type":"number","description":"The pre-tax amount"}
        },
        "required":["amount"]
      }
    }]
  }
}
```

#### tools/call

Execute a tool with arguments.

**Request:**
```json
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"calculate_tax","arguments":{"amount":100}}}
```

**Response:**
```json
{
  "jsonrpc":"2.0",
  "id":3,
  "result":{
    "content":[{
      "type":"text",
      "text":"Amount 100.00, tax 7.50, total 107.50"
    }]
  }
}
```

#### ping

Health check endpoint.

**Request:**
```json
{"jsonrpc":"2.0","id":6,"method":"ping"}
```

**Response:**
```json
{"jsonrpc":"2.0","id":6,"result":{}}
```

## Example Usage

### Single Request

```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"calculate_tax","arguments":{"amount":500}}}' | ./mcp-server
```

### Multiple Requests

```bash
cat << 'EOF' | ./mcp-server
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"calculate_tax","arguments":{"amount":100}}}
EOF
```

### With Docker

```bash
echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"calculate_tax","arguments":{"amount":1000}}}' | docker run --rm -i cbl-mcp-server
```

## Using with LLMs (Claude Desktop, etc.)

This MCP server can be connected to LLM clients that support the Model Context Protocol, allowing natural language interaction.

### Claude Desktop Setup

1. **Build the Docker image:**
   ```bash
   docker build -t cbl-mcp-server .
   ```

2. **Add to Claude Desktop config:**

   Edit your Claude Desktop configuration file:
   - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
   - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
   - **Linux**: `~/.config/Claude/claude_desktop_config.json`

   Add the server configuration:
   ```json
   {
     "mcpServers": {
       "cbl-mcp-server": {
         "command": "docker",
         "args": ["run", "--rm", "-i", "cbl-mcp-server"]
       }
     }
   }
   ```

3. **Restart Claude Desktop**

4. **Use natural language:**
   ```
   You: What's the sales tax on $150?

   Claude: I'll calculate the 7.5% sales tax for you.
   [Uses calculate_tax tool]
   The sales tax on $150 is $11.25, making the total $161.25.
   ```

### Local Binary Setup

If you have GnuCOBOL installed locally:

1. **Build:**
   ```bash
   make
   ```

2. **Configure Claude Desktop:**
   ```json
   {
     "mcpServers": {
       "cbl-mcp-server": {
         "command": "/home/srinivasan/cbl-mcp-server/mcp-server",
         "args": []
       }
     }
   }
   ```

### Example Conversations

Once connected, you can interact naturally:

**Example 1 - Tax Calculation:**
```
You: Calculate the sales tax for a $500 purchase

Claude: [Calls calculate_tax tool]
For a $500 purchase with 7.5% sales tax:
- Tax: $37.50
- Total: $537.50
```

**Example 2 - Price Comparison:**
```
You: Which costs more after tax: $99.99 or $100?

Claude: [Calls calculate_tax tool twice]
After 7.5% sales tax:
- $99.99 → $107.48 (tax: $7.49)
- $100.00 → $107.50 (tax: $7.50)

$100 actually costs 2 cents more after tax ($107.50 vs $107.48).
```

**Example 3 - Budget Planning:**
```
You: I have $200 budget. What's the maximum pre-tax price I can afford?

Claude: [Calculates reverse: 200 / 1.075 ≈ 186.05]
With 7.5% tax, $186.05 pre-tax becomes $200.00 total.
Let me verify:
- Pre-tax: $186.05
- Tax (7.5%): $13.95
- Total: $200.00

You can afford items up to $186.05 before tax.
```

## Tax Calculation Details

- **Tax Rate**: 7.5%
- **Precision**: 2 decimal places
- **Formula**: 
  - Tax = Amount × 0.075
  - Total = Amount + Tax

### Examples

| Amount | Tax | Total |
|--------|-----|-------|
| $100.00 | $7.50 | $107.50 |
| $500.00 | $37.50 | $537.50 |
| $1,000.00 | $75.00 | $1,075.00 |
| $99.99 | $7.49 | $107.48 |
| $0.01 | $0.00 | $0.01 |

## Architecture

### Request Flow

```
stdin → READ-REQUEST → PARSE-REQUEST → DISPATCH-REQUEST → BUILD-*-RESPONSE → WRITE-RESPONSE → stdout
```

### Components

| Module | Purpose |
|--------|---------|
| `server.cbl` | Main loop, orchestrates request processing |
| `transport.cbl` | Low-level I/O operations (ACCEPT, DISPLAY) |
| `parser.cbl` | JSON parsing using UNSTRING |
| `dispatcher.cbl` | Method routing via EVALUATE |
| `response-builder.cbl` | JSON response construction via STRING |
| `tax-service.cbl` | Business logic for tax calculation |

## Development

### Clean Build

```bash
make clean && make
```

### Compiler Flags

The Makefile uses these GnuCOBOL flags:
- `-free`: Free-format source code
- `-fnot-reserved=ALL`: Don't reserve common words
- `-I copybooks`: Include copybook directory
- `-x`: Create executable

### Adding New Tools

1. Add tool schema to `BUILD-TOOLS-LIST-RESPONSE` in `response-builder.cbl`
2. Add case handler in `dispatcher.cbl` EVALUATE block
3. Create response builder in `response-builder.cbl`
4. Implement business logic (e.g., new service file)

## License

This project is provided as-is for educational and demonstration purposes.

## Contributing

Contributions are welcome! Please ensure all COBOL code follows free-format style and includes appropriate comments.