Skip to main content
Glama
README.md
# @calltelemetry/cucm-emulator-mcp

OpenAPI-driven Model Context Protocol (MCP) server for Cisco Unified Communications Manager (CUCM) Emulator.

## Overview

`@calltelemetry/cucm-emulator-mcp` is an OpenAPI-driven MCP server that connects AI coding assistants and automation agents directly to Cisco CUCM Emulator instances. It parses the emulator's OpenAPI 3.1.0 contract specification to dynamically generate strongly-typed discrete MCP tools across all 6 core telephony domains:

1. **Fixtures & Topology**: `cucm_emulator_seed_fixtures`, `cucm_emulator_reset_store`, `cucm_emulator_inspect_fixtures`
2. **Nodes & Cluster Health**: `cucm_emulator_list_nodes`, `cucm_emulator_simulate_node_failover` (ADR 0120/0122 failover)
3. **Phones & Registration**: `cucm_emulator_list_phones`, `cucm_emulator_set_phone_status`, `cucm_emulator_get_phone_web`
4. **Call Simulation & Legs**: `cucm_emulator_simulate_call`, `cucm_emulator_call_action`, `cucm_emulator_list_active_calls`
5. **CURRI / ECC Policy Routing**: `cucm_emulator_evaluate_curri`, `cucm_emulator_get_curri_history`
6. **CDR / CMR Buffers**: `cucm_emulator_generate_cdrs`, `cucm_emulator_get_cdr_history`
7. **Dynamic OpenAPI Operations**: 46+ auto-compiled operations (`cucm_emulator_get_summary`, `cucm_emulator_get_topology`, `cucm_emulator_query_sql`, `cucm_emulator_list_inventory`, `cucm_emulator_upsert_inventory`, etc.)

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    AI Agents / MCP Clients                  │
│                (Claude Code, Cursor, Windsurf)              │
└──────────────────────────────┬──────────────────────────────┘
                               │ JSON-RPC 2.0 (Stdio / SSE)
┌──────────────────────────────▼──────────────────────────────┐
│                  CucmEmulatorMcpServer                      │
│                                                             │
│  ┌───────────────────────┐      ┌────────────────────────┐  │
│  │     Tool Registry     │      │   OpenAPI Spec Parser  │  │
│  │ (15 Domain + Dynamic) │◄─────┤   (Dereferencer/Build) │  │
│  └───────────┬───────────┘      └────────────────────────┘  │
│              │                                              │
│  ┌───────────▼───────────────────────────────────────────┐  │
│  │             ICucmEmulatorClient Abstraction           │  │
│  └───────────┬───────────────────────────┬───────────────┘  │
└──────────────┼───────────────────────────┼──────────────────┘
               │                           │
┌──────────────▼────────────┐ ┌────────────▼──────────────────┐
│      HttpCucmClient       │ │    DirectStoreCucmClient      │
│  Live In-Guest / Container│ │  In-Memory Mock Store State   │
│ (http://127.0.0.1:8443)   │ │  (100% Offline Zero-Config)   │
└───────────────────────────┘ └───────────────────────────────┘
```

## Installation & Quick Start

### Global CLI

```bash
npm install -g @calltelemetry/cucm-emulator-mcp
```

### Run Stdio Server (for AI Agents / Claude Desktop)

```bash
cucm-emulator-mcp --transport stdio
```

### Run SSE Server

```bash
cucm-emulator-mcp --transport sse --port 3000 --host 127.0.0.1
```

### Configuration Options

| Option | Flag | Environment Variable | Default | Description |
|---|---|---|---|---|
| Transport | `-t, --transport` | `MCP_TRANSPORT` | `stdio` | Transport type: `stdio` or `sse` |
| Port | `-p, --port` | `PORT` / `MCP_PORT` | `3000` | Port for SSE HTTP server |
| Host | `-h, --host` | `HOST` / `MCP_HOST` | `127.0.0.1` | Bind host for SSE transport |
| Target URL | `-u, --target-url` | `CUCM_EMULATOR_URL` | `undefined` | Target live emulator URL |
| Spec Path | `-s, --spec-path` | `CUCM_OPENAPI_SPEC` | Bundled | Path or URL to OpenAPI 3.1.0 spec |
| Mock Mode | `-m, --mock` | `CUCM_MOCK` | `false` | Force in-process in-memory mock store |
| Seed Profile | `--seed-profile` | `CUCM_SEED_PROFILE` | `lab-small` | `lab-small`, `standard-enterprise`, `empty` |
| Auth Token | `--auth-token` | `CUCM_EMULATOR_AUTH_TOKEN` | `undefined` | Bearer auth token for live emulator |
| Redact Secrets | `--redact-secrets`| `REDACT_SECRETS` | `false` | Redact sensitive strings in logs |

## MCP Client Configuration

### Claude Desktop (`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "cucm-emulator": {
      "command": "cucm-emulator-mcp",
      "args": ["--transport", "stdio", "--mock", "--seed-profile", "lab-small"]
    }
  }
}
```

### SSE Integration

```json
{
  "mcpServers": {
    "cucm-emulator-sse": {
      "url": "http://127.0.0.1:3000/sse"
    }
  }
}
```

## Available Tool Reference

### Fixtures & Topology
- `cucm_emulator_seed_fixtures`: Seeds deterministic cluster topology, nodes, phones, dial plan partitions, CSS, and CURRI policies.
- `cucm_emulator_reset_store`: Resets or wipes emulator state and re-seeds with a specified topology profile.
- `cucm_emulator_inspect_fixtures`: Inspects and returns a comprehensive summary of active CUCM cluster state.

### Nodes & Failover
- `cucm_emulator_list_nodes`: Lists all CUCM cluster nodes (Publisher, Subscribers, TFTP) with roles and RIS return codes.
- `cucm_emulator_simulate_node_failover`: Sets node status (`Online`, `Offline`, `NotFound`, `SearchLimitExceeded`) for ADR 0120/0122 failover testing.

### Phones & Registration
- `cucm_emulator_list_phones`: Lists configured and registered Cisco IP phone endpoints with directory numbers and MACs.
- `cucm_emulator_set_phone_status`: Updates phone registration status (`Registered`, `UnRegistered`, `Rejected`, `Unknown`).
- `cucm_emulator_get_phone_web`: Fetches phone XML, HTML, or JSON serviceability / status web responses.

### Call Simulation
- `cucm_emulator_simulate_call`: Simulates an end-to-end telephone call through CUCM dial plan routing with RTP media metrics.
- `cucm_emulator_call_action`: Executes mid-call actions (`answer`, `hold`, `resume`, `drop`).
- `cucm_emulator_list_active_calls`: Lists active in-progress call sessions in the emulator.

### CURRI / ECC Policy Routing
- `cucm_emulator_evaluate_curri`: Evaluates external call routing policies via CURRI / ECC, returning permit, deny, or divert verdicts.
- `cucm_emulator_get_curri_history`: Retrieves the log of past CURRI routing evaluation decisions.

### CDR / CMR Buffers
- `cucm_emulator_generate_cdrs`: Generates batches of synthetic CDR records (normal, abandoned, curri-blocked, burst).
- `cucm_emulator_get_cdr_history`: Retrieves recent CDR records in structured JSON or raw Cisco CSV export format.

### SOAP AXL / RIS / DIME (short aliases)
Cursor rejects any MCP `tools/list` that contains a name longer than 64 characters. The DIME log-collection path otherwise compiles to a 72-character name, which dropped the whole SOAP surface in 0.1.2. These aliases post the same emulator SOAP endpoints (no second HTTP API):

- `cucm_emulator_axl`: `POST /axl/` (AXL envelope in `body`)
- `cucm_emulator_ris`: `POST /realtimeservice2/services/RISService70`
- `cucm_emulator_dime`: `POST /logcollectionservice2/services/LogCollectionPortTypeService`
- `cucm_emulator_dime_file`: `POST /logcollectionservice/services/DimeGetFileService`

Inventory, CGI, and screenshots stay on v2 HTTP / `cucm_emulator_get_phone_*`.

## Development & Verification

```bash
# Typecheck
npm run typecheck

# Build TypeScript
npm run build

# Run Full Test Suite (155 Tests)
npm test

# Run with Coverage
npm run test:coverage

# Verify Packaging
npm pack --dry-run
```

## License

MIT © Call Telemetry

TDQS

C2.3/5.0

Scored across 73 tools

Disambiguation2/5

Many tools form parallel legacy and v2 surfaces for the same concepts (e.g., emu_list_active_calls vs emu_list_call_sessions, emu_get_cdr_history vs emu_list_cdr_records, emu_simulate_call vs emu_create_call_session), so an agent must infer which generation to use. The SOAP passthrough tools also overlap with higher-level tools for AXL, RIS, PerfMon, and CDR operations.

Naming Consistency2/5

The emu_ verb_noun convention is visible, but it is broken by unwieldy endpoint-derived names like emu_post_realtimeservice2_services_risservice70 and emu_post_logcollectionservice_services_dime_get_file_service, as well as by inconsistent verb choices (list/get/inspect/fetch/query, create/generate/upsert/seed/bootstrap). The legacy/v2 distinction is not encoded in names, making the pattern unpredictable.

Tool Count1/5

73 tools is far beyond the 50+ threshold and includes extensive meta surfaces (contracts, OpenAPI, scenarios, operation runs, snapshots, evidence) alongside parallel legacy SOAP passthrough endpoints. The core CUCM emulation could be exposed through a much smaller, purpose-built toolset.

Completeness4/5

The server covers cluster nodes, phones, call sessions, CDR/CMR, CURRI, syslog, publishers, snapshots, and AXL/RIS/serviceability operations, so most domain workflows have a path. Minor gaps remain: phone/node lifecycle is mostly limited to status changes and generic inventory upserts, and canonical v2 lacks some direct update/delete semantics that legacy tools patch over.

Maintenance

ActivityMaintained
ResponsivenessNo issues