Skip to content

Commit 5f3377b

Browse files
refactor: hardcode port 8443, remove CUCM_PORT env var
CUCM HTTPS port is always 8443 — not configurable. Removed CUCM_PORT env var, cucm_port tool parameter, and port from CucmCredentials interface. Port is now a constant. Standard env vars: CUCM_HOST, CUCM_USERNAME, CUCM_PASSWORD. Same as cisco-axl-mcp. Set once in ~/.zshrc, all MCPs use them.
1 parent ded6747 commit 5f3377b

9 files changed

Lines changed: 36 additions & 54 deletions

File tree

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,17 @@ npx @calltelemetry/cisco-ris-mcp
8686

8787
### Environment Variables
8888

89-
| Variable | Required | Default | Description |
90-
|----------|----------|---------|-------------|
91-
| `CUCM_HOST` | Yes || CUCM publisher hostname or IP |
92-
| `CUCM_USERNAME` | Yes || CUCM admin username |
93-
| `CUCM_PASSWORD` | Yes || CUCM admin password |
94-
| `CUCM_PORT` | No | `8443` | CUCM HTTPS port |
95-
| `RIS_MCP_LOG_LEVEL` | No | `warn` | Log level: `debug`, `info`, `warn`, `error` |
96-
| `RIS_MCP_TLS_MODE` | No | `permissive` | Set to `strict` to reject self-signed certs |
97-
98-
All credentials can also be passed per-tool-call via `cucm_host`, `cucm_username`, `cucm_password`, `cucm_port` parameters — useful for querying multiple clusters in a single session.
89+
| Variable | Required | Description |
90+
|----------|----------|-------------|
91+
| `CUCM_HOST` | Yes | CUCM publisher hostname or IP |
92+
| `CUCM_USERNAME` | Yes | CUCM admin username |
93+
| `CUCM_PASSWORD` | Yes | CUCM admin password |
94+
| `RIS_MCP_LOG_LEVEL` | No | Log level: `debug`, `info`, `warn`, `error` (default: `warn`) |
95+
| `RIS_MCP_TLS_MODE` | No | Set to `strict` to reject self-signed certs (default: permissive) |
96+
97+
These are the same env vars used by [`@calltelemetry/cisco-axl-mcp`](https://github.com/calltelemetry/cisco-axl-mcp). Set them once in `~/.zshrc` and all CallTelemetry MCP servers use them. Port is always 8443.
98+
99+
Per-tool-call overrides (`cucm_host`, `cucm_username`, `cucm_password`) are available for querying multiple clusters in a single session.
99100

100101
### Counter Presets
101102

src/lib/credential-resolver.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
import type { CucmCredentials, ToolCredentialOverrides } from "../types/credentials.js";
22

3+
/** CUCM HTTPS port — always 8443, not configurable */
4+
export const CUCM_PORT = 8443;
5+
36
/**
47
* Resolve CUCM credentials from per-call overrides or standard env vars.
58
*
6-
* Standard env vars (shared with @calltelemetry/cisco-axl-mcp):
7-
* CUCM_HOST, CUCM_USERNAME, CUCM_PASSWORD, CUCM_PORT
9+
* Standard env vars (shared across all CallTelemetry MCP servers):
10+
* CUCM_HOST, CUCM_USERNAME, CUCM_PASSWORD
811
*
9-
* Set these once in ~/.zshrc and all CallTelemetry MCP servers use them.
12+
* Set these once in ~/.zshrc and all MCP servers use them.
13+
* Port is always 8443 — not configurable.
1014
*/
1115
export function resolveCredentials(overrides?: ToolCredentialOverrides): CucmCredentials {
1216
const host = overrides?.cucm_host || process.env.CUCM_HOST;
1317
const username = overrides?.cucm_username || process.env.CUCM_USERNAME;
1418
const password = overrides?.cucm_password || process.env.CUCM_PASSWORD;
15-
const port = overrides?.cucm_port || Number(process.env.CUCM_PORT) || 8443;
1619

1720
if (!host) throw new Error("CUCM host required. Set CUCM_HOST or pass cucm_host parameter.");
1821
if (!username) throw new Error("CUCM username required. Set CUCM_USERNAME or pass cucm_username parameter.");
1922
if (!password) throw new Error("CUCM password required. Set CUCM_PASSWORD or pass cucm_password parameter.");
2023

21-
return { host, username, password, port };
24+
return { host, username, password };
2225
}

src/services/perfmon/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { escapeXml, fetchServiceabilitySoap, toArray } from "../../lib/soap-clie
22
import { withRateLimit } from "../../lib/rate-limiter.js";
33
import { log } from "../../lib/logger.js";
44
import type { CucmCredentials } from "../../types/credentials.js";
5+
import { CUCM_PORT } from "../../lib/credential-resolver.js";
56
import type { PerfmonCounterValue, PerfmonCounterInfo, MonitorJob, TimestampedSample } from "../../types/perfmon-types.js";
67

78
const PERFMON_PATH = "/perfmonservice2/services/PerfmonService";
@@ -92,7 +93,7 @@ export async function perfmonCollectCounterData(
9293
const envelope = buildCollectCounterDataEnvelope(perfmonHost, object);
9394

9495
const body = await withRateLimit(creds.host, () =>
95-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonCollectCounterData", envelope, timeoutMs ?? 30_000)
96+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonCollectCounterData", envelope, timeoutMs ?? 30_000)
9697
);
9798

9899
const resp = body.perfmonCollectCounterDataResponse as Record<string, unknown> | undefined;
@@ -114,7 +115,7 @@ export async function perfmonListCounter(
114115
const envelope = buildListCounterEnvelope(perfmonHost);
115116

116117
const body = await withRateLimit(creds.host, () =>
117-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonListCounter", envelope, timeoutMs ?? 30_000)
118+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonListCounter", envelope, timeoutMs ?? 30_000)
118119
);
119120

120121
const resp = body.perfmonListCounterResponse as Record<string, unknown> | undefined;
@@ -143,7 +144,7 @@ export async function perfmonListInstance(
143144
const envelope = buildListInstanceEnvelope(perfmonHost, object);
144145

145146
const body = await withRateLimit(creds.host, () =>
146-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonListInstance", envelope, timeoutMs ?? 30_000)
147+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonListInstance", envelope, timeoutMs ?? 30_000)
147148
);
148149

149150
const resp = body.perfmonListInstanceResponse as Record<string, unknown> | undefined;
@@ -159,7 +160,7 @@ export async function perfmonOpenSession(creds: CucmCredentials, timeoutMs?: num
159160
const envelope = buildOpenSessionEnvelope();
160161

161162
const body = await withRateLimit(creds.host, () =>
162-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonOpenSession", envelope, timeoutMs ?? 30_000)
163+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonOpenSession", envelope, timeoutMs ?? 30_000)
163164
);
164165

165166
const resp = body.perfmonOpenSessionResponse as Record<string, unknown> | undefined;
@@ -176,7 +177,7 @@ export async function perfmonAddCounter(
176177
): Promise<void> {
177178
const envelope = buildAddCounterEnvelope(sessionHandle, counters);
178179
await withRateLimit(creds.host, () =>
179-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonAddCounter", envelope, timeoutMs ?? 30_000)
180+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonAddCounter", envelope, timeoutMs ?? 30_000)
180181
);
181182
}
182183

@@ -188,7 +189,7 @@ export async function perfmonCollectSessionData(
188189
const envelope = buildCollectSessionDataEnvelope(sessionHandle);
189190

190191
const body = await withRateLimit(creds.host, () =>
191-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonCollectSessionData", envelope, timeoutMs ?? 30_000)
192+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonCollectSessionData", envelope, timeoutMs ?? 30_000)
192193
);
193194

194195
const resp = body.perfmonCollectSessionDataResponse as Record<string, unknown> | undefined;
@@ -209,7 +210,7 @@ export async function perfmonCloseSession(
209210
): Promise<void> {
210211
const envelope = buildCloseSessionEnvelope(sessionHandle);
211212
await withRateLimit(creds.host, () =>
212-
fetchServiceabilitySoap(creds.host, creds.port, creds, PERFMON_PATH, "perfmonCloseSession", envelope, timeoutMs ?? 30_000)
213+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, PERFMON_PATH, "perfmonCloseSession", envelope, timeoutMs ?? 30_000)
213214
);
214215
}
215216

src/services/ris/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { escapeXml, fetchServiceabilitySoap, toArray } from "../../lib/soap-clie
22
import { withRateLimit } from "../../lib/rate-limiter.js";
33
import { log } from "../../lib/logger.js";
44
import type { CucmCredentials } from "../../types/credentials.js";
5+
import { CUCM_PORT } from "../../lib/credential-resolver.js";
56
import type { RisDevice, RisNode, RisDeviceResult, CtiItem, CtiResult, LineStatus } from "../../types/ris-types.js";
67

78
const RIS_PATH = "/realtimeservice2/services/RISService70";
@@ -138,7 +139,7 @@ export async function selectCmDevice(
138139
const timeout = args.timeoutMs ?? 60_000;
139140

140141
const body = await withRateLimit(creds.host, () =>
141-
fetchServiceabilitySoap(creds.host, creds.port, creds, RIS_PATH, "selectCmDevice", envelope, timeout)
142+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, RIS_PATH, "selectCmDevice", envelope, timeout)
142143
);
143144

144145
const resp = body.selectCmDeviceResponse as Record<string, unknown> | undefined;
@@ -236,7 +237,7 @@ export async function selectCtiItem(
236237
const timeout = args.timeoutMs ?? 30_000;
237238

238239
const body = await withRateLimit(creds.host, () =>
239-
fetchServiceabilitySoap(creds.host, creds.port, creds, RIS_PATH, "selectCtiItem", envelope, timeout)
240+
fetchServiceabilitySoap(creds.host, CUCM_PORT, creds, RIS_PATH, "selectCtiItem", envelope, timeout)
240241
);
241242

242243
const resp = body.selectCtiItemResponse as Record<string, unknown> | undefined;

src/tools/counter-tools.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const credentialProperties = {
1616
cucm_host: { type: "string", description: "CUCM hostname (overrides CUCM_HOST env)" },
1717
cucm_username: { type: "string", description: "CUCM username (overrides CUCM_USERNAME env)" },
1818
cucm_password: { type: "string", description: "CUCM password (overrides CUCM_PASSWORD env)" },
19-
cucm_port: { type: "number", description: "CUCM port (default 8443)" },
2019
};
2120

2221
export const counterTools: ToolDefinition[] = [

src/tools/device-tools.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const credentialProperties = {
99
cucm_host: { type: "string", description: "CUCM hostname (overrides CUCM_HOST env)" },
1010
cucm_username: { type: "string", description: "CUCM username (overrides CUCM_USERNAME env)" },
1111
cucm_password: { type: "string", description: "CUCM password (overrides CUCM_PASSWORD env)" },
12-
cucm_port: { type: "number", description: "CUCM port (default 8443)" },
1312
};
1413

1514
export const deviceTools: ToolDefinition[] = [

src/tools/insight-tools.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const credentialProperties = {
1010
cucm_host: { type: "string", description: "CUCM hostname (overrides CUCM_HOST env)" },
1111
cucm_username: { type: "string", description: "CUCM username (overrides CUCM_USERNAME env)" },
1212
cucm_password: { type: "string", description: "CUCM password (overrides CUCM_PASSWORD env)" },
13-
cucm_port: { type: "number", description: "CUCM port (default 8443)" },
1413
};
1514

1615
export const insightTools: ToolDefinition[] = [

src/types/credentials.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ export interface CucmCredentials {
22
host: string;
33
username: string;
44
password: string;
5-
port: number;
65
}
76

87
export interface ToolCredentialOverrides {
98
cucm_host?: string;
109
cucm_username?: string;
1110
cucm_password?: string;
12-
cucm_port?: number;
1311
}

test/credential-resolver.test.ts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2-
import { resolveCredentials } from "../src/lib/credential-resolver.js";
1+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
2+
import { resolveCredentials, CUCM_PORT } from "../src/lib/credential-resolver.js";
33

44
describe("resolveCredentials", () => {
55
const originalEnv = { ...process.env };
66

77
beforeEach(() => {
8-
// Clear all CUCM env vars
98
delete process.env.CUCM_HOST;
109
delete process.env.CUCM_USERNAME;
1110
delete process.env.CUCM_PASSWORD;
12-
delete process.env.CUCM_PORT;
1311
});
1412

1513
afterEach(() => {
@@ -25,7 +23,6 @@ describe("resolveCredentials", () => {
2523
expect(creds.host).toBe("cucm1.example.com");
2624
expect(creds.username).toBe("admin");
2725
expect(creds.password).toBe("secret");
28-
expect(creds.port).toBe(8443);
2926
});
3027

3128
it("per-call overrides take precedence over env vars", () => {
@@ -37,12 +34,10 @@ describe("resolveCredentials", () => {
3734
cucm_host: "override-host",
3835
cucm_username: "override-user",
3936
cucm_password: "override-pass",
40-
cucm_port: 9443,
4137
});
4238
expect(creds.host).toBe("override-host");
4339
expect(creds.username).toBe("override-user");
4440
expect(creds.password).toBe("override-pass");
45-
expect(creds.port).toBe(9443);
4641
});
4742

4843
it("throws with helpful message when host is missing", () => {
@@ -66,24 +61,10 @@ describe("resolveCredentials", () => {
6661

6762
expect(() => resolveCredentials()).toThrow(/CUCM password required/);
6863
});
64+
});
6965

70-
it("default port is 8443", () => {
71-
process.env.CUCM_HOST = "host";
72-
process.env.CUCM_USERNAME = "admin";
73-
process.env.CUCM_PASSWORD = "secret";
74-
75-
const creds = resolveCredentials();
76-
expect(creds.port).toBe(8443);
77-
});
78-
79-
it("CUCM_PORT env overrides default port", () => {
80-
process.env.CUCM_HOST = "host";
81-
process.env.CUCM_USERNAME = "admin";
82-
process.env.CUCM_PASSWORD = "secret";
83-
process.env.CUCM_PORT = "9999";
84-
85-
const creds = resolveCredentials();
86-
expect(creds.port).toBe(9999);
66+
describe("CUCM_PORT constant", () => {
67+
it("is always 8443", () => {
68+
expect(CUCM_PORT).toBe(8443);
8769
});
88-
8970
});

0 commit comments

Comments
 (0)