Skip to content
Open
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
2 changes: 1 addition & 1 deletion .cursor/rules/important-files.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ These files should be included in every chat:
- `.cursor/rules/important-files.mdc`: This file
- `package.json`: Project configuration
- `tsconfig.json`: TypeScript configuration
- `src/main.ts`: Main entry point
- `src/index.ts`: Main entry point
- `.gitignore`: Git ignore file

If new files are added to the project that are important for understanding the codebase, please add them to this list.
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,15 @@ ORGANIZATION_ID=your_org_id_here

# IcePanel API Base URL (optional)
# ICEPANEL_API_BASE_URL=https://api.icepanel.dev/v1

# Allow http base URLs for local testing (optional, default: false)
# ICEPANEL_API_ALLOW_INSECURE=true

# API request timeout in ms (optional, default: 30000)
# ICEPANEL_API_TIMEOUT_MS=30000

# Max retries for GET/HEAD requests (optional, default: 2)
# ICEPANEL_API_MAX_RETRIES=2

# Base backoff delay in ms (optional, default: 300)
# ICEPANEL_API_RETRY_BASE_DELAY_MS=300
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dist/

# Dependencies
node_modules/
.pnpm-store/

# Environment variables
.env
Expand Down
241 changes: 213 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,157 @@ IcePanel MCP Server is currently in beta. We appreciate your feedback and patien

Please use MCP Servers with caution; only install tools you trust.

## 🚀 Getting Started
## Overview

IcePanel MCP Server exposes IcePanel architecture data (C4 model objects, connections, technologies, tags, domains) to MCP clients so assistants can read and update your architecture inventory.

## 🚀 Quick Start

1. Get your IcePanel Organization ID from the IcePanel app.
2. Generate an API key (read permissions recommended unless you plan to write).
3. Configure your MCP client:

```json
{
"mcpServers": {
"@icepanel/icepanel": {
"command": "npx",
"args": ["-y", "@icepanel/mcp-server@latest", "API_KEY=\"your-api-key\"", "ORGANIZATION_ID=\"your-org-id\""]
}
}
}
```

## How to Configure Your MCP Client

### stdio (default)

Use `command` + `args` to launch the server locally (shown above).

### Streamable HTTP

For MCP clients that support HTTP transport:

This mode is intended for localhost-only usage on your machine. If you choose to expose it beyond localhost, you must secure it yourself (for example, with a reverse proxy, authentication, and network controls).

```json
{
"mcpServers": {
"@icepanel/icepanel": {
"url": "http://localhost:9846/mcp"
}
}
}
```

## Reference: Tool Capabilities (v0.3.0)

All tools follow the `icepanel_*` naming convention and return structured output in `structuredContent`. Read tools support:

- `response_format`: `markdown` (default) or `json`
- Pagination (`limit`, `offset`) where applicable
- Pagination metadata: `total`, `count`, `has_more`, `next_offset`

### Read Tools

- `icepanel_list_landscapes`
- `icepanel_get_landscape`
- `icepanel_list_model_objects`
- `icepanel_get_model_object`
- `icepanel_get_model_object_connections`
- `icepanel_list_technologies`

### Write Tools

- `icepanel_create_model_object`
- `icepanel_update_model_object`
- `icepanel_delete_model_object`
- `icepanel_create_connection`
- `icepanel_update_connection`
- `icepanel_delete_connection`
- `icepanel_create_tag`
- `icepanel_update_tag`
- `icepanel_delete_tag`
- `icepanel_create_domain`
- `icepanel_update_domain`
- `icepanel_delete_domain`

## Reference: Environment Variables

- `API_KEY`: IcePanel API key (required)
- `ORGANIZATION_ID`: IcePanel organization ID (required)
- `ICEPANEL_API_BASE_URL`: Override API base URL (optional)
- `ICEPANEL_API_ALLOW_INSECURE`: Allow http base URLs for testing (optional, default: false)
- `ICEPANEL_API_TIMEOUT_MS`: API request timeout in ms (optional, default: 30000)
- `ICEPANEL_API_MAX_RETRIES`: Max retries for GET/HEAD requests (optional, default: 2)
- `ICEPANEL_API_RETRY_BASE_DELAY_MS`: Base backoff delay in ms (optional, default: 300)
- `MCP_TRANSPORT`: `stdio` (default) or `http`
- `MCP_PORT`: HTTP port for Streamable HTTP transport (default: 3000)

### Transport configuration precedence

- `--transport` / `--port` CLI flags override `MCP_TRANSPORT` / `MCP_PORT`
- `MCP_TRANSPORT` / `MCP_PORT` are honored when running `src/index.ts` directly
- If using the CLI wrapper, those values are forwarded to the server automatically

## How to Run Integration Tests

Use this guide to run the live integration tests against your IcePanel org.

### Prerequisites

- A valid IcePanel API key
- A target landscape name or ID provided via test environment variables

### Steps

1. Export your test credentials:

```bash
export ICEPANEL_MCP_API_KEY="your-api-key" \
ICEPANEL_MCP_ORGANIZATION_ID="your-org-id"
```

2. Point the tests at a specific landscape (by name or ID):

```bash
export ICEPANEL_MCP_TEST_LANDSCAPE_NAME="your-landscape-name"
# or
export ICEPANEL_MCP_TEST_LANDSCAPE_ID="your-landscape-id"
```

3. For tag write tests, provide a tag group id:

```bash
export ICEPANEL_MCP_TAG_GROUP_ID="your-tag-group-id"
```

4. Run the suite:

```bash
ICEPANEL_MCP_TEST_LANDSCAPE_NAME="your-landscape-name" pnpm test
```

### Notes

- Read tests run when `ICEPANEL_MCP_API_KEY` is set.
- Write tests run automatically when the API key has write scope.
- Tag write tests require `ICEPANEL_MCP_TAG_GROUP_ID`.

## Reference: Test Environment Variables

- `ICEPANEL_MCP_API_KEY`: API key for integration tests (read or write)
- `ICEPANEL_MCP_ORGANIZATION_ID`: Organization ID for tests
- `ICEPANEL_MCP_TEST_LANDSCAPE_NAME`: Landscape name to target
- `ICEPANEL_MCP_TEST_LANDSCAPE_ID`: Landscape ID to target (overrides name)
- `ICEPANEL_MCP_TAG_GROUP_ID`: Tag group id used for tag write tests

## Reference: CLI Flags

- `--transport <stdio|http>`: Transport type (overrides `MCP_TRANSPORT`)
- `--port <number>`: HTTP port for HTTP transport (overrides `MCP_PORT`)

## How to Run with Docker

### Prerequisites

Expand All @@ -16,49 +166,84 @@ Please use MCP Servers with caution; only install tools you trust.
- Cursor
- Windsurf

### Installation

1. **Get your organization's ID**
- Visit [IcePanel](https://app.icepanel.io/)
- Head to your Organization's Settings:
- Click on your landscape in the top left to open the dropdown
- Beside your org name, click the gear icon
- Keep your "Organization Identifier" handy!

### Build the Docker Image

2. **Generate API Key**
- Visit [IcePanel](https://app.icepanel.io/)
- Head to your Organization's Settings:
- Click on your landscape in the top left to open the dropdown
- Beside your org name, click the gear icon
- Click on the 🔑 API keys link in the sidebar
- Generate a new API key
- Read permissions recommended

3. **Install**
- Add the configuration to your MCP Client's MCP config file. (See below)
```bash
docker build -t icepanel-mcp-server .
```

#### Environment Variables
### Run with Docker

- `API_KEY`: Your IcePanel API key (required)
- `ORGANIZATION_ID`: Your IcePanel organization ID (required)
- `ICEPANEL_API_BASE_URL`: (Optional) Override the API base URL for different environments
```bash
docker run -i --rm \
-e API_KEY="your-api-key" \
-e ORGANIZATION_ID="your-org-id" \
icepanel-mcp-server
```

#### Configure your MCP Client
### Configure MCP Client for Docker (stdio)

Add this to your MCP Clients' MCP config file:

```json
{
"mcpServers": {
"@icepanel/icepanel": {
"command": "npx",
"args": ["-y", "@icepanel/mcp-server@latest", "API_KEY=\"your-api-key\"", "ORGANIZATION_ID=\"your-org-id\""]
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "API_KEY=your-api-key",
"-e", "ORGANIZATION_ID=your-org-id",
"icepanel-mcp-server"
]
}
}
}
```

### Run with Streamable HTTP Transport

For standalone HTTP server mode, use the `--transport http` flag:

```bash
docker run -d -p 127.0.0.1:9846:9846 \
-e API_KEY="your-api-key" \
-e ORGANIZATION_ID="your-org-id" \
icepanel-mcp-server --transport http --port 9846
```

The server exposes:
- `GET/POST/DELETE /mcp` - Main MCP endpoint (Streamable HTTP)
- `GET /health` - Health check endpoint

## Reference: Transport Options

This server supports two transport mechanisms:

### stdio (default)
- Standard input/output transport
- Used when MCP client spawns the server process directly
- Best for: Local development, npx usage, per-user deployments

### Streamable HTTP
- Single endpoint HTTP transport (`/mcp`)
- Supports both request/response and streaming modes
- Best for: Docker deployments, shared servers, enterprise environments
- Replaces the deprecated SSE transport (MCP spec 2025-03-26)

## v0.3.0 Breaking Changes

Tool names have been updated to follow MCP best practices and use snake_case with an `icepanel_` prefix. Update any clients or prompts that refer to the old tool names:

- `getLandscapes` → `icepanel_list_landscapes`
- `getLandscape` → `icepanel_get_landscape`
- `getModelObjects` → `icepanel_list_model_objects`
- `getModelObject` → `icepanel_get_model_object`
- `getModelObjectRelationships` → `icepanel_get_model_object_connections`
- `getTechnologyCatalog` → `icepanel_list_technologies`

Read tools now accept `response_format` (`markdown` or `json`) plus `limit`/`offset` pagination parameters where applicable.

## ✉️ Support

- Reach out to [Support](mailto:support@icepanel.io) if you experience any issues.
Expand Down
47 changes: 36 additions & 11 deletions bin/icepanel-mcp-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,46 @@
* IcePanel MCP Server
*
* Environment variables:
* - API_KEY: Your IcePanel API key
* - ORGANIZATION_ID: Your IcePanel organization ID
* - API_KEY: Your IcePanel API key (required)
* - ORGANIZATION_ID: Your IcePanel organization ID (required)
* - ICEPANEL_API_BASE_URL: (Optional) Override the API base URL for different environments
* - MCP_TRANSPORT: Transport type: 'stdio' (default) or 'http'
* - MCP_PORT: HTTP server port for HTTP transport (default: 3000)
*
* CLI flags:
* - --transport <stdio|http>: Transport type (overrides MCP_TRANSPORT)
* - --port <number>: HTTP port for HTTP transport (overrides MCP_PORT)
*/

// Parse any environment variables passed as arguments
process.argv.slice(2).forEach(arg => {
const match = arg.match(/^([^=]+)=(.*)$/);
if (match) {
const [, key, value] = match;
process.env[key] = value.replace(/^["'](.*)["']$/, '$1'); // Remove quotes if present
}
});
import { parseCliConfig } from "../dist/cli/config.js";

// Parse command line arguments
const args = process.argv.slice(2);
const { transport, port, portRaw, updatedEnv, usedDeprecatedSse } = parseCliConfig(args, process.env);
Object.assign(process.env, updatedEnv);

// Support legacy 'sse' transport name (map to 'http')
if (usedDeprecatedSse) {
console.warn("Warning: 'sse' transport is deprecated. Using 'http' (Streamable HTTP) instead.");
}

// Validate transport
if (!['stdio', 'http'].includes(transport)) {
console.error(`Invalid transport: ${transport}. Must be 'stdio' or 'http'.`);
process.exit(1);
}

// Validate port
if (isNaN(port) || port < 1 || port > 65535) {
console.error(`Invalid port: ${portRaw}. Must be a number between 1 and 65535.`);
process.exit(1);
}

// Store config for main module
process.env._MCP_TRANSPORT = transport;
process.env._MCP_PORT = String(port);

import('../dist/main.js').catch(err => {
import('../dist/index.js').catch(err => {
console.error('Failed to start IcePanel MCP Server:', err);
process.exit(1);
});
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"name": "@icepanel/mcp-server",
"version": "0.2.0",
"version": "0.3.0",
"description": "IcePanel MCP Server for integrating with MCP clients",
"type": "module",
"main": "dist/main.js",
"main": "dist/index.js",
"bin": {
"icepanel-mcp-server": "./bin/icepanel-mcp-server.js"
},
"scripts": {
"build": "tsc",
"dev": "tsx watch --env-file=.env src/main.ts",
"dev": "tsx watch --env-file=.env src/index.ts",
"test": "vitest run",
"prepublishOnly": "npm run build",
"publish": "npm publish --access public"
},
Expand All @@ -32,7 +33,8 @@
"devDependencies": {
"@types/node": "^22.0.0",
"tsx": "^4.7.0",
"typescript": "^5.8.0"
"typescript": "^5.8.0",
"vitest": "^4.0.18"
},
"engines": {
"node": ">=18"
Expand Down
Loading