OpenRouter Custom Image Generation MCP Server
Generates images using OpenRouter models and retrieves user-uploaded images from LibreChat database, enabling image generation and editing with reference images.
README
š¼ļø MCP Image Generation Server for LibreChat
A custom Model Context Protocol (MCP) server that provides AI image generation capabilities to LibreChat via OpenRouter.
Model: Locked to
google/gemini-2.5-flash-imagefor all requests. To change the model, modify the source code intools.js.
š Project Structure
mcp-image-gen-custom/
āāā index.js # Express app, SSE transport, MCP server + tool registration
āāā tools.js # Tool handlers: get_user_images, generate_image, rate limiting
āāā openrouter.js # OpenRouter API communication (chat completions with image modality)
āāā files.js # MongoDB file record lookup + local file stream reader
āāā db.js # MongoDB connection pool manager
āāā Dockerfile # Container build definition
āāā package.json
āāā example/
āāā docker-compose.override.example.yml # Docker service config example
āāā librechat.example.yaml # librechat.yaml MCP config example
āāā system_instructions.example.md # Agent system prompt template
š ļø Tools Provided
1. get_user_images
Retrieves images uploaded by the current user in LibreChat, returning index aliases and file_ids for use as reference images.
| Argument | Type | Required | Description |
|---|---|---|---|
limit |
number | No | Max images to return. Default: 10 |
Example response:
Found 2 uploaded image(s):
1. [INDEX_1] file_id: "cab88c4e-aecb-4812-9fff-6c85aede6362" ā mycar.png
2. [INDEX_2] file_id: "f6752381-3a6d-4b69-a92b-5555a9521069" ā cat.png
Use EITHER the file_id OR the index number (e.g., '1', '2' or 'INDEX_1', 'INDEX_2') as the reference_image_url when calling generate_image.
2. generate_image
Generates an image from a text prompt. Supports Text-to-Image and Image-to-Image (editing) via reference images.
| Argument | Type | Required | Description |
|---|---|---|---|
prompt |
string | ā | Text description of the image to generate |
reference_image_url |
string | No | Index alias ("1", "INDEX_1") or local file_id of a single reference image |
reference_image_urls |
string[] | No | List of index aliases or file_ids for multiple reference images |
aspect_ratio |
string | No | Output image dimensions. See options below |
Aspect ratio options:
| Value | Shape | Common use |
|---|---|---|
1:1 |
Square | Profile pictures, feed posts |
16:9 |
Wide landscape | Banners, cover photos |
9:16 |
Tall portrait | Stories, Reels, TikTok |
4:5 |
Portrait | Feed posts (portrait) |
Note:
aspect_ratioonly controls image dimensions ā it does not affect image style or content.
Note: Do NOT pass Google/OpenAI temporary
file-xxxxIDs intoreference_image_url. These are not stored in the local database. Always useget_user_imagesfirst to get valid index aliases or localfile_ids.
š Per-User Rate Limiting
The server enforces configurable usage limits per user to prevent spam. Limits are tracked in MongoDB (mcp_image_gen_usage collection).
| Env Variable | Default | Description |
|---|---|---|
IMAGE_GEN_DAILY_LIMIT |
3 |
Max images per user per day (reset at midnight local time) |
IMAGE_GEN_COOLDOWN_SEC |
30 |
Min seconds between generations per user |
To reset limits manually (all users):
docker exec chat-mongodb mongosh LibreChat --eval "db.mcp_image_gen_usage.deleteMany({})"
To reset limits for a specific user:
docker exec chat-mongodb mongosh LibreChat --eval "db.mcp_image_gen_usage.deleteMany({ userId: ObjectId('<userId>') })"
To view current usage:
docker exec chat-mongodb mongosh LibreChat --eval "db.mcp_image_gen_usage.aggregate([{ \$group: { _id: '\$userId', count: { \$sum: 1 } } }]).forEach(r => print(r._id, '->', r.count))"
āļø How Index Resolution Works
The LLM agent only sees image bytes in chat history ā it does not know the database file_id. This server resolves short index aliases (e.g., "1" or "INDEX_1") to the correct local file_id automatically.
sequenceDiagram
actor User
participant Agent as LLM Agent
participant MCP as MCP Server
participant DB as MongoDB
User->>Agent: "Edit this image" (uploads car.png)
Agent->>MCP: get_user_images()
MCP->>DB: Query user's latest images
DB-->>MCP: [car.png ā file_id: "abc-123"]
MCP-->>Agent: "1. [INDEX_1] file_id: 'abc-123' ā car.png"
Agent->>MCP: generate_image(prompt="make it red", reference_image_url="INDEX_1")
Note over MCP: Resolves "INDEX_1" ā "abc-123"
MCP->>DB: Fetch file "abc-123" from disk
MCP-->>User: Returns edited image ā
š Installation & Deployment
Prerequisites
- LibreChat running via Docker Compose
- An OpenRouter API key
Step 1: Place this folder
Clone or copy this mcp-image-gen-custom/ directory into the root of your LibreChat repository:
LibreChat/
āāā mcp-image-gen-custom/ ā here
āāā api/
āāā docker-compose.yml
āāā ...
Step 2: Configure Environment Variables
Add the following to your .env file at the LibreChat root:
# Required
OPENROUTER_KEY=your_openrouter_api_key_here
# Optional ā image generation rate limits
IMAGE_GEN_DAILY_LIMIT=3
IMAGE_GEN_COOLDOWN_SEC=30
Step 3: Add the MCP service to Docker Compose
Add the following to your docker-compose.override.yml (create it if it doesn't exist):
services:
api:
volumes:
- type: bind
source: ./librechat.yaml
target: /app/librechat.yaml
mcp-image-gen:
build: ./mcp-image-gen-custom
restart: always
environment:
NODE_ENV: ${NODE_ENV:-production}
PORT: 3013
OPENROUTER_KEY: ${OPENROUTER_KEY}
OPENROUTER_API_KEY: ${OPENROUTER_KEY}
MONGO_URI: mongodb://mongodb:27017/LibreChat
IMAGE_GEN_DAILY_LIMIT: ${IMAGE_GEN_DAILY_LIMIT:-3}
IMAGE_GEN_COOLDOWN_SEC: ${IMAGE_GEN_COOLDOWN_SEC:-30}
volumes:
- ./uploads:/app/uploads # shared with LibreChat api container
- ./images:/app/images # shared with LibreChat api container
expose:
- "3013"
networks:
- default
See
example/docker-compose.override.example.ymlfor a complete example.
Step 4: Register the MCP server in librechat.yaml
Append the following to your librechat.yaml:
mcpSettings:
allowedDomains:
- 'mcp-image-gen'
allowedAddresses:
- 'mcp-image-gen:3013'
mcpServers:
openrouter-imager:
type: sse
url: http://mcp-image-gen:3013/sse
headers:
x-user-id: '{{LIBRECHAT_USER_ID}}'
See
example/librechat.example.yamlfor a complete example.
Step 5: Build and start
# Build and start all services
docker compose up -d --build
# Restart the LibreChat API to reload librechat.yaml
docker compose restart api
Step 6: Configure the Agent in LibreChat UI
- Go to LibreChat ā Agents and create a new agent (or edit an existing one).
- Enable the
openrouter-imagerMCP tool. - Paste the system prompt from
example/system_instructions.example.mdinto the Instructions field.
š§ Changing the Model
The model is hardcoded to google/gemini-2.5-flash-image in tools.js:
const selectedModel = "google/gemini-2.5-flash-image";
To use a different model, edit this line directly and rebuild the container:
docker compose up -d --build mcp-image-gen
š Useful Commands
# View live MCP server logs
docker logs librechat-mcp-image-gen-1 -f
# Rebuild and restart MCP server only
docker compose up -d --build mcp-image-gen
# Reset all image generation usage limits
docker exec chat-mongodb mongosh LibreChat --eval "db.mcp_image_gen_usage.deleteMany({})"
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.