From 8c6e7fcbb3b258623a43fd444aa4f8596b7f8910 Mon Sep 17 00:00:00 2001 From: Greg Methvin Date: Mon, 24 Nov 2025 11:14:53 -0800 Subject: [PATCH] fix baseURL typo --- package.json | 2 +- pnpm-lock.yaml | 10 +++---- src/config.ts | 8 +++--- src/server.ts | 2 +- tests/unit/prompts.test.ts | 5 ++-- tests/unit/tool-filter-defaults.test.ts | 29 +++++++++++-------- tests/unit/tool-filter.test.ts | 37 +++++++++++++------------ tests/utils/test-config.ts | 17 ++++++++++++ 8 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 tests/utils/test-config.ts diff --git a/package.json b/package.json index 1a8991b..98c7358 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ }, "dependencies": { "@alcyone-labs/zod-to-json-schema": "4.0.10", - "@iterable/api": "0.3.0", + "@iterable/api": "0.4.0", "@modelcontextprotocol/sdk": "1.18.1", "@primno/dpapi": "^2.0.1", "@types/json-schema": "7.0.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index beb5403..31f3507 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: 4.0.10 version: 4.0.10(zod@4.1.11) '@iterable/api': - specifier: 0.3.0 - version: 0.3.0(typescript@5.9.3) + specifier: 0.4.0 + version: 0.4.0(typescript@5.9.3) '@modelcontextprotocol/sdk': specifier: 1.18.1 version: 1.18.1 @@ -654,8 +654,8 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - '@iterable/api@0.3.0': - resolution: {integrity: sha512-DDxAoLUpopTJ6Wf/Uy2bA31aN/vB2JpfT+NNVDtUPOOCugEC8NtKAtmDRY2nvJwKhvwo9NBioDoJ2/g/8kmbNw==} + '@iterable/api@0.4.0': + resolution: {integrity: sha512-NwRWqLdqFx0NMeCYAiEl67SVocUiPQB4nNY/WBeTO536S5VzW/Lji7oMg3MHh4nMtOXFY3s1opb0OW9VmaZkPw==} engines: {node: '>=18.0.0'} '@jest/console@30.2.0': @@ -3226,7 +3226,7 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@iterable/api@0.3.0(typescript@5.9.3)': + '@iterable/api@0.4.0(typescript@5.9.3)': dependencies: '@t3-oss/env-core': 0.13.8(typescript@5.9.3)(zod@4.1.11) axios: 1.13.2 diff --git a/src/config.ts b/src/config.ts index deec5bc..a09762c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -14,10 +14,10 @@ export interface McpServerConfig { readonly allowWrites: boolean; /** If false, exclude tools that can send messages (campaign/journey/event-triggered sends) */ readonly allowSends: boolean; - /** The active Iterable API key (optional for tests) */ - readonly apiKey?: string; - /** The Iterable API base URL (defaults to https://api.iterable.com) */ - readonly baseUrl?: string; + /** The active Iterable API key */ + readonly apiKey: string; + /** The Iterable API base URL */ + readonly baseUrl: string; } export function resolveAllowFlags( diff --git a/src/server.ts b/src/server.ts index 597ebbb..4e82720 100644 --- a/src/server.ts +++ b/src/server.ts @@ -208,7 +208,7 @@ export class IterableMcpServer { // Initialize Iterable client with API key and base URL from config this.iterableClient = new IterableClient({ apiKey: mcpConfig.apiKey, - baseURL: mcpConfig.baseUrl || "https://api.iterable.com", + baseUrl: mcpConfig.baseUrl, }); this.setupHttpInterceptors(); diff --git a/tests/unit/prompts.test.ts b/tests/unit/prompts.test.ts index a817e42..0fdca60 100644 --- a/tests/unit/prompts.test.ts +++ b/tests/unit/prompts.test.ts @@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it } from "@jest/globals"; import { generatePromptMessage, generatePrompts } from "../../src/prompts.js"; import { filterTools } from "../../src/tool-filter.js"; import { createAllTools } from "../../src/tools/index.js"; +import { createTestConfig } from "../utils/test-config.js"; describe("MCP Prompts", () => { let client: IterableClient; @@ -115,11 +116,11 @@ describe("MCP Prompts", () => { it("should work with filtered read-only tools", () => { // Test the pattern used in the server: filter to read-only tools first const allTools = createAllTools(client); - const readOnlyConfig = { + const readOnlyConfig = createTestConfig({ allowUserPii: true, allowWrites: false, allowSends: false, - }; + }); const readOnlyTools = filterTools(allTools, readOnlyConfig); const prompts = generatePrompts(readOnlyTools); diff --git a/tests/unit/tool-filter-defaults.test.ts b/tests/unit/tool-filter-defaults.test.ts index d2fd673..9ca4d4b 100644 --- a/tests/unit/tool-filter-defaults.test.ts +++ b/tests/unit/tool-filter-defaults.test.ts @@ -1,4 +1,5 @@ -import { filterTools } from "../../src/tool-filter"; +import { filterTools } from "../../src/tool-filter.js"; +import { createTestConfig } from "../utils/test-config.js"; describe("filterTools defaults", () => { const readOnlyTool: any = { @@ -16,21 +17,27 @@ describe("filterTools defaults", () => { } as any; it("excludes write tools when allowWrites=false", () => { - const out = filterTools([readOnlyTool, writeTool], { - allowUserPii: false, - allowWrites: false, - allowSends: true, - }); + const out = filterTools( + [readOnlyTool, writeTool], + createTestConfig({ + allowUserPii: false, + allowWrites: false, + allowSends: true, + }) + ); expect(out.map((t) => t.name)).toContain("get_campaigns"); expect(out.map((t) => t.name)).not.toContain("create_campaign"); }); it("includes write tools when allowWrites=true", () => { - const out = filterTools([readOnlyTool, writeTool], { - allowUserPii: false, - allowWrites: true, - allowSends: true, - }); + const out = filterTools( + [readOnlyTool, writeTool], + createTestConfig({ + allowUserPii: false, + allowWrites: true, + allowSends: true, + }) + ); expect(out.map((t) => t.name)).toContain("create_campaign"); }); }); diff --git a/tests/unit/tool-filter.test.ts b/tests/unit/tool-filter.test.ts index 917ef9d..df05190 100644 --- a/tests/unit/tool-filter.test.ts +++ b/tests/unit/tool-filter.test.ts @@ -12,6 +12,7 @@ import { READ_ONLY_TOOLS, } from "../../src/tool-filter.js"; import { createAllTools } from "../../src/tools/index.js"; +import { createTestConfig } from "../utils/test-config.js"; // Mock Iterable client for testing const mockClient = {} as any; @@ -23,11 +24,11 @@ describe("Tool Filter", () => { describe("Safe tool lists validation", () => { it("should have all NON_PII_TOOLS in actual tool names", () => { // Get the safe non-PII tools by testing with restrictive config - const restrictiveConfig: McpServerConfig = { + const restrictiveConfig: McpServerConfig = createTestConfig({ allowUserPii: false, allowWrites: true, // Allow writes to isolate PII filtering allowSends: true, - }; + }); const nonPiiTools = filterTools(allTools, restrictiveConfig); const nonPiiToolNames = nonPiiTools.map((tool) => tool.name); @@ -40,11 +41,11 @@ describe("Tool Filter", () => { it("should have all READ_ONLY_TOOLS in actual tool names", () => { // Get the read-only tools by testing with restrictive config - const restrictiveConfig: McpServerConfig = { + const restrictiveConfig: McpServerConfig = createTestConfig({ allowUserPii: true, // Allow PII to isolate write filtering allowWrites: false, allowSends: true, - }; + }); const readOnlyTools = filterTools(allTools, restrictiveConfig); const readOnlyToolNames = readOnlyTools.map((tool) => tool.name); @@ -70,23 +71,23 @@ describe("Tool Filter", () => { }); it("should filter tools when restrictions are applied", () => { - const permissiveConfig: McpServerConfig = { + const permissiveConfig: McpServerConfig = createTestConfig({ allowUserPii: true, allowWrites: true, allowSends: true, - }; + }); - const restrictivePiiConfig: McpServerConfig = { + const restrictivePiiConfig: McpServerConfig = createTestConfig({ allowUserPii: false, allowWrites: true, allowSends: true, - }; + }); - const restrictiveWriteConfig: McpServerConfig = { + const restrictiveWriteConfig: McpServerConfig = createTestConfig({ allowUserPii: true, allowWrites: false, allowSends: true, - }; + }); const allToolsCount = filterTools(allTools, permissiveConfig).length; const nonPiiToolsCount = filterTools( @@ -107,11 +108,11 @@ describe("Tool Filter", () => { describe("Configuration filtering", () => { it("should filter PII tools when allowUserPii is false", () => { - const config: McpServerConfig = { + const config: McpServerConfig = createTestConfig({ allowUserPii: false, allowWrites: true, allowSends: true, - }; + }); const filteredTools = filterTools(allTools, config); const filteredNames = filteredTools.map((tool) => tool.name); @@ -134,11 +135,11 @@ describe("Tool Filter", () => { }); it("should filter write tools when allowWrites is false", () => { - const config: McpServerConfig = { + const config: McpServerConfig = createTestConfig({ allowUserPii: true, allowWrites: false, allowSends: true, - }; + }); const filteredTools = filterTools(allTools, config); const filteredNames = filteredTools.map((tool) => tool.name); @@ -163,22 +164,22 @@ describe("Tool Filter", () => { }); it("should allow all tools when both restrictions are disabled", () => { - const config: McpServerConfig = { + const config: McpServerConfig = createTestConfig({ allowUserPii: true, allowWrites: true, allowSends: true, - }; + }); const filteredTools = filterTools(allTools, config); expect(filteredTools).toHaveLength(allTools.length); }); it("should apply both restrictions when both are enabled", () => { - const config: McpServerConfig = { + const config: McpServerConfig = createTestConfig({ allowUserPii: false, allowWrites: false, allowSends: false, - }; + }); const filteredTools = filterTools(allTools, config); diff --git a/tests/utils/test-config.ts b/tests/utils/test-config.ts new file mode 100644 index 0000000..7ea28ac --- /dev/null +++ b/tests/utils/test-config.ts @@ -0,0 +1,17 @@ +import type { McpServerConfig } from "../../src/config.js"; + +/** + * Helper to create test config with required fields + */ +export function createTestConfig( + overrides: Partial = {} +): McpServerConfig { + return { + apiKey: "test-api-key", + baseUrl: "https://api.iterable.com", + allowUserPii: false, + allowWrites: false, + allowSends: false, + ...overrides, + }; +}