# FastMCP Shared Server Implementation Plan for Imagen-MCP
## Overview
This document outlines the implementation plan to reduce CPU usage for the Imagen-MCP server by implementing a shared server architecture using HTTP transport instead of the default stdio transport.
## Problem Statement
MCP servers built with `fastmcp` consume excessive CPU (~1.3% per instance) while idle, due to a busy-polling pattern in the asyncio event loop. With multiple VS Code windows open, each spawns its own MCP server instance, leading to significant cumulative CPU usage:
- 7 VS Code windows × 1.3% CPU = ~10% idle CPU usage for imagen-mcp alone
- Combined with other MCP servers, this can reach 18-20% idle CPU usage
## Recommended Solution
**Shared Server Architecture with Streamable HTTP Transport**
Instead of spawning a new MCP server instance for each VS Code window (stdio transport), run a single shared server using HTTP transport that all windows connect to.
### Benefits
| Metric | Before (stdio) | After (HTTP) |
|--------|----------------|--------------|
| Instances (7 windows) | 7 | 1 |
| CPU usage (idle) | ~10% | ~1.3% |
| Startup time | Per window | Once |
| Memory usage | 7× | 1× |
## Implementation Steps
### Step 1: Update CLI to Support HTTP Transport
**File:** [`Imagen_MCP/cli.py`](Imagen_MCP/cli.py)
Modify the CLI to accept transport, port, host, and log-level options using Click:
```python
import click
from Imagen_MCP.server import mcp
@click.group()
def cli() -> None:
"""Imagen MCP Server CLI."""
pass
@cli.command()
@click.option(
"--transport",
type=click.Choice(["stdio", "sse", "streamable-http", "http"]),
default="stdio",
help="Transport protocol for the MCP server.",
)
@click.option(
"--port",
type=int,
default=8082,
help="Port for HTTP/SSE transport.",
)
@click.option(
"--host",
type=str,
default="127.0.0.1",
help="Host for HTTP/SSE transport.",
)
@click.option(
"--log-level",
type=click.Choice(["debug", "info", "warning", "error"]),
default="info",
help="Log level for the server.",
)
def serve(transport: str, port: int, host: str, log_level: str) -> None:
"""Start the MCP server."""
if transport == "stdio":
mcp.run()
elif transport == "sse":
mcp.run(transport="sse", host=host, port=port, log_level=log_level)
elif transport in ("streamable-http", "http"):
mcp.run(transport="streamable-http", host=host, port=port, log_level=log_level)
def main() -> None:
"""Run the Imagen MCP server (default: serve command)."""
cli()
if __name__ == "__main__":
main()
```
**Note:** Port 8082 is chosen to avoid conflicts with other MCP servers (svg-mcp uses 8081).
### Step 2: Add Click Dependency
**File:** [`pyproject.toml`](pyproject.toml)
Add `click` to the project dependencies:
```toml
[tool.poetry.dependencies]
click = "^8.1.0"
```
### Step 3: Create systemd Service Template
**File:** `scripts/imagen-mcp.service.template`
```ini
[Unit]
Description=Imagen-MCP Server (Shared HTTP Mode)
Documentation=https://github.com/your-org/Imagen-MCP
After=network.target
[Service]
Type=simple
WorkingDirectory=__WORKING_DIR__
ExecStart=__MCP_PATH__ serve --transport streamable-http --host 127.0.0.1 --port __PORT__
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=default.target
```
### Step 4: Add justfile Actions
**File:** [`justfile`](justfile)
Add the following recipes at the end of the justfile:
```just
# =============================================================================
# Shared HTTP Server Mode (for reduced CPU usage with multiple VS Code windows)
# =============================================================================
# Run MCP server with Streamable HTTP transport (shared mode)
# This allows multiple VS Code windows to connect to a single server instance,
# reducing idle CPU usage from ~10% (7 instances) to ~1.3% (1 instance).
serve-http host="127.0.0.1" port="8082":
#!/usr/bin/env bash
set -euo pipefail
echo "Starting imagen-mcp server in shared HTTP mode..."
echo "Configure VS Code to connect to: http://{{ host }}:{{ port }}/mcp"
poetry run imagen-mcp serve --transport streamable-http --host "{{ host }}" --port "{{ port }}"
# Check if MCP HTTP server is running
mcp-status port="8082":
#!/usr/bin/env bash
set -euo pipefail
if curl -s --max-time 2 "http://127.0.0.1:{{ port }}/mcp" >/dev/null 2>&1; then
echo "MCP HTTP server is running on port {{ port }}"
else
echo "MCP HTTP server is NOT running on port {{ port }}"
exit 1
fi
# Install and enable systemd user service for MCP HTTP server
install-systemd-service:
#!/usr/bin/env bash
set -euo pipefail
# ... (see full implementation in guide)
# Uninstall systemd user service for MCP HTTP server
uninstall-systemd-service:
#!/usr/bin/env bash
set -euo pipefail
# ... (see full implementation in guide)
```
### Step 5: Update VS Code MCP Configuration
**Before (stdio transport):**
```json
{
"mcpServers": {
"imagen": {
"command": "imagen-mcp",
"args": ["serve"],
"alwaysAllow": ["generate_image", "start_image_batch", "get_next_image", "get_batch_status", "list_models", "get_model_details"]
}
}
}
```
**After (streamable-http transport):**
```json
{
"mcpServers": {
"imagen": {
"type": "streamable-http",
"url": "http://127.0.0.1:8082/mcp",
"alwaysAllow": ["generate_image", "start_image_batch", "get_next_image", "get_batch_status", "list_models", "get_model_details"]
}
}
}
```
## File Changes Summary
| File | Action | Description |
|------|--------|-------------|
| `Imagen_MCP/cli.py` | Modify | Add Click-based CLI with transport options |
| `pyproject.toml` | Modify | Add click dependency |
| `scripts/imagen-mcp.service.template` | Create | systemd service template |
| `justfile` | Modify | Add serve-http, mcp-status, install/uninstall-systemd-service recipes |
## Port Allocation
Following the convention from the guide:
| Server | Port |
|--------|------|
| svg-mcp | 8081 |
| imagen-mcp | 8082 |
## Testing Plan
1. Run `just serve-http` and verify server starts
2. Test with `curl http://127.0.0.1:8082/mcp`
3. Configure VS Code to use HTTP transport
4. Verify all tools work correctly
5. Monitor CPU usage to confirm reduction
## Rollback Plan
If issues arise, revert to stdio transport by:
1. Changing VS Code configuration back to command-based
2. Stopping the systemd service: `systemctl --user stop imagen-mcp`
## References
- [FastMCP CPU Usage Issue](/home/adam/tmp/empty-AI/docs/fastmcp-cpu-usage-issue.md)
- [FastMCP Shared Server Guide](/home/adam/tmp/SVG-MCP/docs/fastmcp-shared-server-guide.md)
- [FastMCP Documentation](https://gofastmcp.com/)
- [Roo Code MCP Transports](https://docs.roocode.com/features/mcp/transports)
## Date
Created: 2025-12-25