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.This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues