✨ Vercel-ready with Fluid compute | Serverless MCP deployment with streaming support
An MCP (Model Context Protocol) server for AI image generation through Runware's API. Generate images from text using FLUX.1, FLUX.2, HiDream, and more with full control over dimensions, steps, schedulers, and other parameters.
✨ Fully compatible with Vercel with Fluid compute - Deploy as a serverless MCP endpoint with streaming support.
# Install
npm install
# Configure
cp .env.example .env
# Edit .env and add your RUNWARE_API_KEY
# Build and run
npm run build
npm startPrerequisites: Node.js 22+, Runware API key (get one)
Create a .env file in the project root:
# Required - Your Runware API key
RUNWARE_API_KEY=rwk_abc123xyz456
# Optional - Transport mode (stdio|http)
# - stdio: Local Claude Desktop (default)
# - http: HTTP server for remote connections
MCP_TRANSPORT=stdio
# Optional - HTTP server configuration (http mode only)
PORT=3000
HOST=127.0.0.1
# Optional - API key authentication (http mode)
# Comma-separated list for multiple keys
MCP_API_KEYS=secret-key-1,secret-key-2-
RUNWARE_API_KEY(required): Get from Runware Dashboard → API Keys. Used to authenticate with Runware's image generation API. -
MCP_TRANSPORT: Controls how the server communicates with clients:stdio- Standard input/output for local Claude Desktop (default)http- HTTP server with/mcpendpoint for remote access
-
PORT/HOST: HTTP server binding (default:3000/127.0.0.1). Only used whenMCP_TRANSPORT=http. -
MCP_API_KEYS: Security for HTTP/Vercel modes. Without this, the server accepts all requests (dev mode). With keys, clients must sendx-api-keyheader. Health checks (/health) bypass authentication.
Add to your configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"runware": {
"command": "node",
"args": ["/absolute/path/to/mcp-runware/dist/index.js"]
}
}
}Restart Claude Desktop. The server loads environment variables from .env automatically.
# Start HTTP server
npm run start:http
# Test endpoints
curl http://127.0.0.1:3000/health
curl -X POST http://127.0.0.1:3000/mcp \
-H "x-api-key: your-key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",...}'Connect from MCP client:
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("http://127.0.0.1:3000/mcp"),
{ headers: { "x-api-key": "your-key" } },
);✨ Fully compatible with Vercel Fluid compute for streaming MCP responses.
- Connect repo to Vercel - Import your Git repository
- Set environment variables in Vercel dashboard:
RUNWARE_API_KEY- Your Runware API key (required)MCP_API_KEYS- Authentication keys, comma-separated (recommended)
- Deploy - Vercel auto-detects configuration from
vercel.jsonwith Fluid enabled
Your MCP server: https://your-project.vercel.app/mcp
Connect with same client code as HTTP mode using your Vercel URL. The server leverages Vercel's experimental Fluid compute to support streaming responses required by MCP.
Important Notes:
- Session Management: Vercel's serverless functions are stateless. Each session creates its own MCP server instance. If a client receives a "Session not found" error, it should reinitialize by sending a new
initializerequest with the samemcp-session-idheader to recreate the session. - Model Data: The build process automatically copies model data from
src/data/todist/data/. After updating models withnpm run fetch-models, rebuild before deploying. - Cold Starts: Initial requests may be slower due to serverless cold starts. Subsequent requests within the same instance are faster.
Visual testing with MCP Inspector:
npm run build
npx @modelcontextprotocol/inspector node dist/index.jsOR using HTTP+Streamable
npm run build
npm run start:http
npm run inspectOpens browser UI at http://localhost:6274 to test tools interactively. If you see SSE errors, check .env has valid RUNWARE_API_KEY.
# List tools
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | node dist/index.js
# Generate image
cat <<EOF | node dist/index.js
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"generate_image","arguments":{"prompt":"Mountain sunset","width":1024,"height":768}}}
EOFGenerate an image from a text prompt.
Parameters:
prompt(required): Text description of the image (2-3000 characters)model(optional): Model ID (default:runware:101@1- FLUX.1 Dev)negativePrompt(optional): What to avoid in the imagewidth(optional): Width in pixels, divisible by 64 (128-2048, default: 1024)height(optional): Height in pixels, divisible by 64 (128-2048, default: 1024)steps(optional): Generation steps (1-100, default: 20)cfgScale(optional): Guidance scale (0-50, default: 7)scheduler(optional): Sampling scheduler (e.g., "DPM++ 2M Karras", "Euler A")seed(optional): Seed for reproducible resultsnumberResults(optional): Number of images to generate (default: 1)includeCost(optional): Include cost in response (default: true)
Example:
{
"prompt": "A futuristic city at sunset with flying cars and neon lights",
"model": "runware:101@1",
"width": 1024,
"height": 768,
"steps": 30,
"cfgScale": 7
}Get a comprehensive list of AI models available on Runware with their AIR identifiers, pricing, and descriptions. Models are automatically sorted by price (cheapest first).
No parameters required
Returns: A merged, deduplicated list of 44+ models from popular and curated collections.
Features:
- Pricing information (USD per image/generation)
- Model configurations and discounts
- AIR identifiers for direct usage with
generate_imagetool - Combines manually curated popular models and "Best for Text on Images" collection
- Sorted by price with cheapest models first
Example Response:
[
{
"name": "Stable Diffusion XL Lightning",
"air": "civitai:133005@782002",
"description": "Fast SDXL with 4-step generation",
"price_usd": 0.001,
"configuration": "4-step",
"discount": "80% cheaper"
},
{
"name": "FLUX.1 Schnell",
"air": "runware:100@1",
"description": "Ultra-fast FLUX variant",
"price_usd": 0.003,
"configuration": "4-step",
"discount": "70% cheaper"
}
// ... more models
]Model Data Management:
- Model information stored in
src/data/popular_models.jsonandsrc/data/best_models.json - Pricing data in
src/data/pricing.json - Update models:
npm run fetch-models(requiresRUNWARE_API_KEYin.env) - Build process automatically copies data from
src/data/todist/data/ - Rebuild and redeploy after updating model data
Returns:
A formatted list of all available models including:
- Model name and AIR identifier
- Pricing information (USD per generation)
- Configuration details (resolution, steps, etc.)
- Discount information where applicable
- Model category and tags
The tool merges data from both popular models and specialized collections, providing up to 44+ unique models sorted by cost-effectiveness.
Example output:
- FLUX.2 [klein] 4B (
runware:400@4) - $0.0006 (1024x1024) [Save 40%] - Z-Image-Turbo (
runware:z-image@turbo) - $0.0006 (1024x1024 · 4 steps) - FLUX.2 [klein] 9B (
runware:400@2) - $0.00078 (1024x1024 · 4 steps) [Save 87%] - Qwen-Image-2512 (
alibaba:qwen-image@2512) - $0.0051 (1024x1024) [Save 74%]
All pricing and model data is automatically updated when running npm run fetch-models.
mcp-runware/
├── src/
│ ├── index.ts # Main entry point
│ ├── transports.ts # Transport setup (stdio, HTTP)
│ ├── utils.ts # Shared utilities (server factory, auth, transport factory)
│ ├── tools.ts # MCP tool definitions
│ ├── runware-client.ts # Runware SDK wrapper
│ └── data/ # Model and pricing data
│ ├── popular_models.json # Popular models with AIR & pricing
│ ├── best_models.json # Best text-on-images models
│ └── pricing.json # Pricing data source
├── scripts/
│ └── fetch_curated_models.py # Model data fetcher/enricher
├── api/
│ └── index.ts # Vercel serverless function
├── dist/ # Compiled JavaScript (generated)
├── vercel.json # Vercel deployment configuration
├── .env # Environment variables (create from .env.example)
├── .env.example # Environment variables template
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
└── README.md # This file
For active development with auto-recompilation:
npm run watchIn another terminal, run the server:
node dist/index.jsCompile TypeScript to JavaScript:
npm run buildStart the MCP server:
npm startOr build and run in one command:with pricing information, automatically scraped and enriched from Runware. To refresh these lists:
-
Install Python dependencies (one-time setup):
pip3 install requests python-dotenv
-
Run the fetch script:
npm run fetch-models
This will:
- Scrape model IDs and names from Runware collection pages
- Fetch AIR identifiers and metadata from the Runware API
- Merge pricing data from
src/data/pricing.json - Filter out models without AIR identifiers
- Save enriched data to JSON files in
src/data/
Data sources:
- Popular Models →
src/data/popular_models.json(manually curated from https://runware.ai/models) - Best Models →
src/data/best_models.json(scraped from https://runware.ai/collections/best-for-text-on-images) - Pricing Data →
src/data/pricing.json(extracted from https://runware.ai/pricing)
The get_models tool automatically merges these sources and sorts by price.
To modify the model collections, edit the POPULAR_MODELS and SCRAPE_COLLECTIONS arrays API
- Save enriched data to JSON files in
src/data/
Collections fetched:
- Popular Models →
src/data/popular_models.json(from https://runware.ai/models) - Best Models →
src/data/best_models.json(from https://runware.ai/collections/best-for-text-on-images)
To add more collections, edit the COLLECTIONS array in scripts/fetch_curated_models.py.