Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![Iterable MCP Server Setup](images/iterable-mcp-setup.png)


With the new Iterable MCP server, you can now connect Iterable to your favorite AI tools like Cursor, Claude Desktop, Claude Code, Windsurf, and Gemini CLI!
With the new Iterable MCP server, you can now connect Iterable to your favorite AI tools like Cursor, Claude Desktop, Claude Code, Windsurf, Gemini CLI, and Antigravity!

## What is MCP?

Expand Down Expand Up @@ -94,15 +94,16 @@ claude mcp add-from-claude-desktop

For more information, see the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp).

### Manual configuration (Cursor, Claude Desktop, Windsurf & Gemini CLI)
### Manual configuration (Cursor, Claude Desktop, Windsurf, Gemini CLI & Antigravity)

The above commands will automatically configure your AI tool to use the MCP server by editing the appropriate configuration file, but you can also manually edit the appropriate configuration file:
- **Claude Desktop:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Cursor:** `~/.cursor/mcp.json`
- **Windsurf:** `~/.codeium/windsurf/mcp_config.json`
- **Antigravity:** `~/.gemini/antigravity/mcp_config.json`
- **Gemini CLI:** `~/.gemini/settings.json`

All four use the same configuration format:
All five use the same configuration format:

**Recommended: Using key manager:**
```bash
Expand Down Expand Up @@ -330,6 +331,26 @@ iterable-mcp keys update <key-name> --advanced

**Process persistence:** After switching API keys with `keys activate`, you must **fully restart Windsurf** (quit and reopen the application). Windsurf keeps MCP server processes running in the background, and they don't automatically reload when you switch keys.

#### Antigravity

**Tool limit:** Antigravity has a maximum limit of 100 tools per MCP server. When all permissions are enabled (`ITERABLE_USER_PII=true`, `ITERABLE_ENABLE_WRITES=true`, `ITERABLE_ENABLE_SENDS=true`), the Iterable MCP server exposes **104 tools**, which exceeds this limit.

**Workaround:** Use restricted permissions to stay under the 100-tool limit:
- With default permissions (all disabled): 26 tools ✅
- With PII only: 37 tools ✅
- With PII + writes: 86 tools ✅
- With all permissions: 104 tools ❌ (exceeds Antigravity limit)

You can configure permissions when adding a key:
```bash
iterable-mcp keys add --advanced
```

Or update an existing key's permissions:
```bash
iterable-mcp keys update <key-name> --advanced
```

## Beta Feature Reminder
Iterable's MCP server is currently in beta. MCP functionality may change, be
suspended, or be discontinued at any time without notice. This software is
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
"install-dev:cursor:debug": "pnpm install-dev && node dist/index.js setup --cursor --debug --local",
"install-dev:gemini-cli": "pnpm install-dev && node dist/index.js setup --gemini-cli --local",
"install-dev:gemini-cli:debug": "pnpm install-dev && node dist/index.js setup --gemini-cli --debug --local",
"install-dev:windsurf": "pnpm install-dev && node dist/index.js setup --windsurf --local",
"install-dev:windsurf:debug": "pnpm install-dev && node dist/index.js setup --windsurf --debug --local",
"install-dev:antigravity": "pnpm install-dev && node dist/index.js setup --antigravity --local",
"install-dev:antigravity:debug": "pnpm install-dev && node dist/index.js setup --antigravity --debug --local",
"lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix --quiet",
"prepublishOnly": "pnpm build",
"prestart": "pnpm build",
Expand Down
12 changes: 12 additions & 0 deletions src/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const TOOL_NAMES = {
"claude-code": "Claude Code",
"gemini-cli": "Gemini CLI",
windsurf: "Windsurf",
antigravity: "Antigravity",
manual: "Manual Setup",
} as const;

Expand Down Expand Up @@ -66,6 +67,12 @@ const TOOL_CONFIGS = {
);
}
})(),
antigravity: path.join(
os.homedir(),
".gemini",
"antigravity",
"mcp_config.json"
),
cursor: path.join(os.homedir(), ".cursor", "mcp.json"),
windsurf: path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json"),
"gemini-cli": path.join(os.homedir(), ".gemini", "settings.json"),
Expand Down Expand Up @@ -207,6 +214,7 @@ export const setupMcpServer = async (): Promise<void> => {
...(args.includes("--claude-code") ? ["claude-code" as const] : []),
...(args.includes("--gemini-cli") ? ["gemini-cli" as const] : []),
...(args.includes("--windsurf") ? ["windsurf" as const] : []),
...(args.includes("--antigravity") ? ["antigravity" as const] : []),
...(args.includes("--manual") ? ["manual" as const] : []),
];

Expand Down Expand Up @@ -235,6 +243,7 @@ export const setupMcpServer = async (): Promise<void> => {
[`${COMMAND_NAME} setup --claude-code`, "Configure for Claude Code"],
[`${COMMAND_NAME} setup --gemini-cli`, "Configure for Gemini CLI"],
[`${COMMAND_NAME} setup --windsurf`, "Configure for Windsurf"],
[`${COMMAND_NAME} setup --antigravity`, "Configure for Antigravity"],
[`${COMMAND_NAME} setup --manual`, "Show manual config instructions"],
[
`${COMMAND_NAME} setup --cursor --claude-desktop`,
Expand Down Expand Up @@ -568,6 +577,7 @@ export const setupMcpServer = async (): Promise<void> => {
{ name: "Claude Code (CLI)", value: "claude-code" },
{ name: "Gemini CLI", value: "gemini-cli" },
{ name: "Windsurf", value: "windsurf" },
{ name: "Antigravity", value: "antigravity" },
{ name: "Other / Manual Setup", value: "manual" },
],
validate: (arr) =>
Expand Down Expand Up @@ -709,6 +719,8 @@ export const setupMcpServer = async (): Promise<void> => {
if (fileBasedTools.includes("gemini-cli"))
configuredTools.push("Gemini CLI");
if (fileBasedTools.includes("windsurf")) configuredTools.push("Windsurf");
if (fileBasedTools.includes("antigravity"))
configuredTools.push("Antigravity");
if (needsManual) configuredTools.push("your AI tool");

const toolsList =
Expand Down
4 changes: 4 additions & 0 deletions src/utils/tool-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export function getWindsurfConfigPath(): string {
return path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
}

export function getAntigravityConfigPath(): string {
return path.join(os.homedir(), ".gemini", "antigravity", "mcp_config.json");
}

export function getClaudeDesktopConfigPath(): string {
switch (process.platform) {
case "darwin":
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/tool-config-paths.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,37 @@ import os from "os";
import path from "path";

import {
getAntigravityConfigPath,
getClaudeDesktopConfigPath,
getCursorConfigPath,
getWindsurfConfigPath,
} from "../../src/utils/tool-config.js";

describe("tool-config paths", () => {
describe("getAntigravityConfigPath", () => {
it("returns path in home directory .gemini/antigravity folder", () => {
const configPath = getAntigravityConfigPath();
expect(configPath).toBe(
path.join(os.homedir(), ".gemini", "antigravity", "mcp_config.json")
);
});

it("returns a path ending with mcp_config.json", () => {
const configPath = getAntigravityConfigPath();
expect(configPath).toMatch(/mcp_config\.json$/);
});

it("returns a path containing .gemini", () => {
const configPath = getAntigravityConfigPath();
expect(configPath).toContain(".gemini");
});

it("returns a path containing antigravity", () => {
const configPath = getAntigravityConfigPath();
expect(configPath).toContain("antigravity");
});
});

describe("getCursorConfigPath", () => {
it("returns path in home directory .cursor folder", () => {
const configPath = getCursorConfigPath();
Expand Down Expand Up @@ -76,12 +101,14 @@ describe("tool-config paths", () => {
expect(path.isAbsolute(getCursorConfigPath())).toBe(true);
expect(path.isAbsolute(getWindsurfConfigPath())).toBe(true);
expect(path.isAbsolute(getClaudeDesktopConfigPath())).toBe(true);
expect(path.isAbsolute(getAntigravityConfigPath())).toBe(true);
});

it("all config paths end with .json", () => {
expect(getCursorConfigPath()).toMatch(/\.json$/);
expect(getWindsurfConfigPath()).toMatch(/\.json$/);
expect(getClaudeDesktopConfigPath()).toMatch(/\.json$/);
expect(getAntigravityConfigPath()).toMatch(/\.json$/);
});
});
});