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
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
55 changes: 55 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# IcePanel MCP Server Dockerfile
# Multi-stage build for minimal production image

# Stage 1: Build
FROM node:22-alpine AS builder

WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml ./

# Install pnpm and dependencies
RUN corepack enable && corepack prepare pnpm@latest --activate
RUN pnpm install

# Copy source code
COPY tsconfig.json ./
COPY src/ ./src/
COPY bin/ ./bin/

# Build TypeScript
RUN pnpm run build

# Stage 2: Production
FROM node:22-alpine AS production

WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml ./

# Install pnpm and production dependencies only
RUN corepack enable && corepack prepare pnpm@latest --activate
RUN pnpm install --prod

# Copy built files from builder stage
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/bin ./bin

# Environment variables (to be provided at runtime)
# Required:
# API_KEY - Your IcePanel API key
# ORGANIZATION_ID - Your IcePanel organization ID
# Optional:
# ICEPANEL_API_BASE_URL - Override API base URL
# MCP_TRANSPORT - Transport type: 'stdio' (default) or 'http'
# MCP_PORT - HTTP port for Streamable HTTP transport (default: 3000)

# Default port for HTTP transport (can be overridden with --port flag)
EXPOSE 3000

# Run the MCP server
# Supports CLI flags: --transport <stdio|http> --port <number>
# Example: docker run -p 3000:3000 ... icepanel-mcp-server --transport http --port 3000
ENTRYPOINT ["node", "bin/icepanel-mcp-server.js"]
92 changes: 92 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ Please use MCP Servers with caution; only install tools you trust.
- `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`: (Optional) Transport type: `stdio` (default) or `http`
- `MCP_PORT`: (Optional) HTTP port for Streamable HTTP transport (default: 3000)

#### CLI Flags

When running directly or via Docker, you can use these flags:

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

#### Configure your MCP Client

Expand All @@ -59,6 +68,89 @@ Add this to your MCP Clients' MCP config file:
}
```

## 🐳 Docker

You can also run the IcePanel MCP Server as a Docker container.

### Build the Docker Image

```bash
docker build -t icepanel-mcp-server .
```

### Run with Docker

```bash
docker run -i --rm \
-e API_KEY="your-api-key" \
-e ORGANIZATION_ID="your-org-id" \
icepanel-mcp-server
```

### Configure MCP Client for Docker (stdio)

Add this to your MCP Clients' MCP config file:

```json
{
"mcpServers": {
"@icepanel/icepanel": {
"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 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

### Configure MCP Client for Streamable HTTP

For MCP clients that support HTTP transport:

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

## 🔄 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)

## ✉️ Support

- Reach out to [Support](mailto:support@icepanel.io) if you experience any issues.
Expand Down
59 changes: 54 additions & 5 deletions bin/icepanel-mcp-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,68 @@
* 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 => {
// Parse command line arguments
const args = process.argv.slice(2);
let transport = process.env.MCP_TRANSPORT || 'stdio';
let port = parseInt(process.env.MCP_PORT || '3000', 10);

for (let i = 0; i < args.length; i++) {
const arg = args[i];

// Handle --transport flag
if (arg === '--transport' && args[i + 1]) {
transport = args[i + 1];
i++; // Skip next arg
continue;
}

// Handle --port flag
if (arg === '--port' && args[i + 1]) {
port = parseInt(args[i + 1], 10);
i++; // Skip next arg
continue;
}

// Handle environment variables passed as arguments (KEY=value format)
const match = arg.match(/^([^=]+)=(.*)$/);
if (match) {
const [, key, value] = match;
process.env[key] = value.replace(/^["'](.*)["']$/, '$1'); // Remove quotes if present
}
});
}

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

// 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: ${port}. 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 => {
console.error('Failed to start IcePanel MCP Server:', err);
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@icepanel/mcp-server",
"version": "0.2.0",
"version": "0.1.1",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Package and server version mismatch after changes

Medium Severity

The diff changes package.json version from 0.2.0 to 0.1.1 while simultaneously changing src/main.ts version from 0.1.1 to 0.2.0. The new http-server.ts also hardcodes "0.2.0" in the health endpoint. After this PR, the package version is 0.1.1 but the server reports 0.2.0 in both the MCP handshake and health endpoint, creating an inconsistency that complicates debugging and version tracking.

Additional Locations (2)

Fix in Cursor Fix in Web

"description": "IcePanel MCP Server for integrating with MCP clients",
"type": "module",
"main": "dist/main.js",
Expand All @@ -25,11 +25,15 @@
"author": "IcePanel",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "1.24.0",
"@modelcontextprotocol/sdk": "1.9.0",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDK downgrade breaks StreamableHTTPServerTransport import

High Severity

The @modelcontextprotocol/sdk dependency is being downgraded from version 1.24.0 to 1.9.0, but the code imports StreamableHTTPServerTransport from @modelcontextprotocol/sdk/server/streamableHttp.js. The Streamable HTTP transport was added to the MCP spec in 2025-03-26 and is not available in the older 1.9.0 SDK version. This will cause a runtime module resolution failure when HTTP transport is used.

Additional Locations (1)

Fix in Cursor Fix in Web

"cors": "^2.8.5",
"express": "^5.0.1",
"fuse.js": "^7.1.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/node": "^22.0.0",
"tsx": "^4.7.0",
"typescript": "^5.8.0"
Expand Down
Loading