This repository contains Model Context Protocol (MCP) servers that provide various tools and capabilities for AI models. It was mainly done to have small examples to show for LocalAI, but works as well with any MCP client.
A web search server that provides search capabilities using DuckDuckGo.
Features:
- Web search functionality
- Configurable maximum results (default: 5)
- JSON schema validation for inputs/outputs
Tool:
search- Search the web for information
Configuration:
MAX_RESULTS- Environment variable to set maximum number of search results (default: 5)
Docker Image:
docker run -e MAX_RESULTS=10 ghcr.io/mudler/mcps/duckduckgo:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"ddg": {
"command": "docker",
"env": {
"MAX_RESULTS": "10"
},
"args": [
"run", "-i", "--rm", "-e", "MAX_RESULTS",
"ghcr.io/mudler/mcps/duckduckgo:master"
]
}
}
}A codemogger MCP server that provides code analysis and indexing capabilities.
Features:
- Code search functionality
- Code indexing capabilities
- Reindex functionality
- JSON schema validation for inputs/outputs
Tools:
codemogger_search- Search code using codemoggercodemogger_index- Index code using codemoggercodemogger_reindex- Reindex code using codemogger
Docker Image:
docker run ghcr.io/mudler/mcps/codemogger:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"codemogger": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/codemogger:master"
]
}
}
}A weather information server that provides current weather and forecast data for cities worldwide.
Features:
- Current weather conditions (temperature, wind, description)
- Multi-day weather forecast
- URL encoding for city names with special characters
- JSON schema validation for inputs/outputs
- HTTP timeout handling
Tool:
get_weather- Get current weather and forecast for a city
API Response Format:
{
"temperature": "29 Β°C",
"wind": "20 km/h",
"description": "Partly cloudy",
"forecast": [
{
"day": "1",
"temperature": "27 Β°C",
"wind": "12 km/h"
},
{
"day": "2",
"temperature": "22 Β°C",
"wind": "8 km/h"
}
]
}Docker Image:
docker run ghcr.io/mudler/mcps/weather:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"weather": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/weather:master"
]
}
}
}An OpenWeatherMap-based weather server that provides current conditions and a 5-day forecast for cities worldwide.
Features:
- OpenWeatherMap geocoding lookup for city names
- Current weather conditions (temperature, wind, description)
- 5-day forecast derived from the OpenWeatherMap forecast API
- Retry logic for common city formats such as
City, TX - JSON schema validation for inputs/outputs
- HTTP timeout and upstream error handling
Tool:
get_weather- Get current weather and a 5-day forecast for a city using OpenWeatherMap
Configuration:
OWM_API_KEY- OpenWeatherMap API key
API Response Format:
{
"temperature": "80.1 F",
"wind": "17.3 mph",
"description": "broken clouds",
"forecast": [
{
"day": "2026-04-03",
"temperature": "80.1 F",
"wind": "17.3 mph"
},
{
"day": "2026-04-04",
"temperature": "76.2 F",
"wind": "11.4 mph"
}
]
}Docker Image:
docker run -e OWM_API_KEY=your-api-key ghcr.io/mudler/mcps/openweathermap:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"openweathermap": {
"command": "docker",
"env": {
"OWM_API_KEY": "your-api-key"
},
"args": [
"run", "-i", "--rm", "--init",
"-e", "OWM_API_KEY",
"ghcr.io/mudler/mcps/openweathermap:master"
]
}
}
}A no-op tool that forces the model to think about a message. Useful for debugging or forcing explicit reasoning steps in the model.
Features:
- Simple message input that gets echoed back
- Forces the model to explicitly process and think about the message
- Input validation (non-empty message)
- JSON schema validation for inputs/outputs
Tool:
think- Think about a given message
Input Format:
{
"message": "What is the capital of France?"
}Output Format:
{
"result": "Thinking about: What is the capital of France?"
}Docker Image:
docker run ghcr.io/mudler/mcps/think:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"think": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/think:master"
]
}
}
}A simple wait/sleep server that allows AI models to autonomously wait for a specified duration. Useful for waiting for asynchronous operations to complete.
Features:
- Wait for a specified duration in seconds (supports fractional seconds)
- Context cancellation support for interruption
- Input validation (positive duration, maximum 1 hour)
- JSON schema validation for inputs/outputs
Tool:
wait- Wait for a specified duration in seconds
Input Format:
{
"duration": 5.5
}Output Format:
{
"message": "Waited for 5.50 seconds"
}Docker Image:
docker run ghcr.io/mudler/mcps/wait:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"wait": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/wait:master"
]
}
}
}A persistent memory storage server that allows AI models to store, retrieve, and manage information across sessions using disk-based full-text search.
Features:
- Disk-based bleve index storage (no full memory load)
- Efficient full-text search across name and content fields
- Add, list, and remove memory entries
- Unique ID generation for each entry
- Timestamp tracking for entries
- Configurable storage location
- JSON schema validation for inputs/outputs
- Scalable to large numbers of entries
Tools:
add_memory- Add a new entry to memory storage (requires both name and content)list_memory- List all memory entry names (returns only names, not full entries)remove_memory- Remove a memory entry by IDsearch_memory- Search memory entries by name and content using full-text search
Configuration:
MEMORY_INDEX_PATH- Environment variable to set the bleve index path (default:/data/memory.bleve)MEMORY_ADD_TOOL_NAME- Environment variable to override the name of the add memory tool (default:add_memory)MEMORY_LIST_TOOL_NAME- Environment variable to override the name of the list memory tool (default:list_memory)MEMORY_REMOVE_TOOL_NAME- Environment variable to override the name of the remove memory tool (default:remove_memory)MEMORY_SEARCH_TOOL_NAME- Environment variable to override the name of the search memory tool (default:search_memory)
Add Memory Input Format:
{
"name": "User Preferences",
"content": "User prefers coffee over tea"
}Memory Entry Format:
{
"id": "1703123456789000000",
"name": "User Preferences",
"content": "User prefers coffee over tea",
"created_at": "2023-12-21T10:30:56.789Z"
}List Memory Output Format:
{
"names": [
"User Preferences",
"Meeting Notes",
"Project Ideas"
],
"count": 3
}Search Response Format:
{
"query": "coffee",
"results": [
{
"id": "1703123456789000000",
"name": "User Preferences",
"content": "User prefers coffee over tea",
"created_at": "2023-12-21T10:30:56.789Z"
}
],
"count": 1
}Docker Image:
# Basic usage with default tool names
docker run -e MEMORY_INDEX_PATH=/custom/path/memory.bleve ghcr.io/mudler/mcps/memory:latest
# Usage with custom tool names
docker run -e MEMORY_INDEX_PATH=/custom/path/memory.bleve \
-e MEMORY_ADD_TOOL_NAME=store \
-e MEMORY_LIST_TOOL_NAME=list \
-e MEMORY_REMOVE_TOOL_NAME=delete \
-e MEMORY_SEARCH_TOOL_NAME=find \
ghcr.io/mudler/mcps/memory:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"memory": {
"command": "docker",
"env": {
"MEMORY_INDEX_PATH": "/data/memory.bleve",
"MEMORY_ADD_TOOL_NAME": "store",
"MEMORY_LIST_TOOL_NAME": "list",
"MEMORY_REMOVE_TOOL_NAME": "delete",
"MEMORY_SEARCH_TOOL_NAME": "find"
},
"args": [
"run", "-i", "--rm", "-v", "/host/data:/data",
"-e", "MEMORY_INDEX_PATH",
"-e", "MEMORY_ADD_TOOL_NAME",
"-e", "MEMORY_LIST_TOOL_NAME",
"-e", "MEMORY_REMOVE_TOOL_NAME",
"-e", "MEMORY_SEARCH_TOOL_NAME",
"ghcr.io/mudler/mcps/memory:master"
]
}
}
}A Home Assistant integration server that allows AI models to interact with and control Home Assistant entities and services.
Features:
- List all entities and their current states
- Get all available services with detailed information
- Call services to control devices (turn_on, turn_off, toggle, etc.)
Tools:
list_entities- List all entities in Home Assistantget_services- Get all available services in Home Assistantcall_service- Call a service in Home Assistant (e.g., turn_on, turn_off, toggle)search_entities- Search for entities by keyword (searches across entity ID, domain, state, and friendly name)search_services- Search for services by keyword (searches across service domain and name)
Configuration:
HA_TOKEN- Home Assistant API token (required)HA_HOST- Home Assistant host URL (default:http://localhost:8123)
Entity Response Format:
{
"entities": [
{
"entity_id": "light.living_room",
"state": "on",
"friendly_name": "Living Room Light",
"attributes": {
"friendly_name": "Living Room Light",
"brightness": 255
},
"domain": "light"
}
],
"count": 1
}Service Call Example:
{
"domain": "light",
"service": "turn_on",
"entity_id": "light.living_room"
}Search Entities Example:
{
"keyword": "living room light"
}Search Services Example:
{
"keyword": "turn_on"
}Docker Image:
docker run -e HA_TOKEN="your-token-here" -e HA_HOST="http://IP:PORT" ghcr.io/mudler/mcps/homeassistant:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"homeassistant": {
"command": "docker",
"env": {
"HA_TOKEN": "your-home-assistant-token",
"HA_HOST": "http://"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/homeassistant:master"
]
}
}
}An MCP server for interacting with Twitter/X: read tweets and profiles, search, timelines, trends, and perform actions (like, retweet, post, thread, follow) with optional media upload.
Features:
- Get tweets from users (with media), user profiles, search by keyword/hashtag (latest/top), rate-limited (max 50 tweets per request)
- Like/unlike, retweet/undo retweet, post tweets (text, media, reply, quote), create threads
- Home/user/mentions timelines, list tweets, trending topics (WOEID), followers/following, follow/unfollow
- Get unanswered mentions (tweets that mention you and you have not replied to, last 24 hours)
- Image upload (JPEG/PNG/GIF) for use in post_tweet/create_thread
Tools:
get_tweets- Fetch recent tweets from a user (with media)get_profile- Get a user's profile informationsearch_tweets- Search for tweets by hashtag or keywordlike_tweet- Like or unlike a tweetretweet- Retweet or undo retweetpost_tweet- Post a new tweet with optional media, reply, or quotecreate_thread- Create a Twitter threadget_timeline- Get tweets from home, user, or mentions timelineget_unanswered_mentions- Get tweets that mention you and you have not replied to (last 24 hours)get_list_tweets- Get tweets from a Twitter listget_trends- Get current trending topics by place (WOEID)get_user_relationships- Get followers or following listfollow_user- Follow or unfollow a userupload_media- Upload an image and get media_id for post_tweet
Configuration:
TWITTER_BEARER_TOKEN- App-only (read-only where allowed); or use OAuth 1.0a for full access- OAuth 1.0a (required for write, home timeline, trends, media upload):
TWITTER_API_KEY,TWITTER_API_SECRET,TWITTER_ACCESS_TOKEN,TWITTER_ACCESS_SECRET - Optional:
TWITTER_MAX_TWEETS(default 50) to cap tweets per request
Acceptance tests: Run with env credentials set and TWITTER_ACCEPTANCE=true:
TWITTER_ACCEPTANCE=true TWITTER_BEARER_TOKEN=xxx go test ./twitter/...
# Or with OAuth 1.0a for full tests:
TWITTER_ACCEPTANCE=true TWITTER_API_KEY=... TWITTER_API_SECRET=... TWITTER_ACCESS_TOKEN=... TWITTER_ACCESS_SECRET=... go test ./twitter/...Docker Image:
docker run -e TWITTER_BEARER_TOKEN=xxx ghcr.io/mudler/mcps/twitter:latest
# Or OAuth 1.0a:
docker run -e TWITTER_API_KEY=... -e TWITTER_API_SECRET=... -e TWITTER_ACCESS_TOKEN=... -e TWITTER_ACCESS_SECRET=... ghcr.io/mudler/mcps/twitter:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"twitter": {
"command": "docker",
"env": {
"TWITTER_BEARER_TOKEN": "your-bearer-token"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/twitter:master"
]
}
}
}Note: Twitter API access level (Free/Basic/Pro) affects rate limits and some endpoints (e.g. search). Trends and media upload use v1.1 API and require OAuth 1.0a.
A shell script execution server that allows AI models to execute shell scripts and commands.
Features:
- Execute shell scripts with full shell capabilities
- Configurable shell command (default:
sh -c) - Separate stdout and stderr capture
- Exit code reporting
- Configurable timeout (default: 30 seconds)
- JSON schema validation for inputs/outputs
Tool:
execute_command- Execute a shell script and return the output, exit code, and any errors
Configuration:
SHELL_CMD- Environment variable to set the shell command to use (default:sh -c). Can include arguments, e.g.,bash -xorzshSHELL_TIMEOUT_DISABLED- Set totrueto disable the timeout completely (default: timeout is 30 seconds)SHELL_TIMEOUT- Environment variable to set the timeout in seconds (default: 30 seconds)SHELL_WORKING_DIR- Environment variable to set the working directory for script execution (default: current directory)
Input Format:
{
"script": "ls -la /tmp",
"timeout": 30
}Output Format:
{
"script": "ls -la /tmp",
"stdout": "total 1234\ndrwxrwxrwt...",
"stderr": "",
"exit_code": 0,
"success": true,
"error": ""
**Docker Image:**
```bash
docker run -e SHELL_CMD=bash ghcr.io/mudler/mcps/shell:latestWith timeout disabled:
docker run -e SHELL_CMD=bash -e SHELL_TIMEOUT_DISABLED=true ghcr.io/mudler/mcps/shell:latestWith custom working directory:
docker run -e SHELL_CMD=bash -e SHELL_WORKING_DIR=/workspace ghcr.io/mudler/mcps/shell:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"shell": {
"command": "docker",
"env": {
"SHELL_CMD": "bash",
"SHELL_WORKING_DIR": "/workspace"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/shell:master"
]
}
}
}An SSH server that allows AI models to connect to remote SSH hosts and execute shell scripts.
Features:
- Connect to remote SSH hosts
- Execute shell scripts on remote hosts
- Support for password and key-based authentication
- Configurable remote shell command (default:
sh -c) - Separate stdout and stderr capture
- Exit code reporting
- Configurable timeout (default: 30 seconds)
- JSON schema validation for inputs/outputs
Tool:
execute_script- Execute a shell script on a remote SSH host and return the output, exit code, and any errors
Configuration:
SSH_HOST- Default SSH host (can be overridden per request)SSH_PORT- Default SSH port (default: 22)SSH_USER- Default SSH username (can be overridden per request)SSH_PASSWORD- Default SSH password (can be overridden per request, or use SSH_KEY_PATH)SSH_KEY_PATH- Path to SSH private key file (alternative to password authentication)SSH_KEY_PASSPHRASE- Passphrase for encrypted SSH private key (if needed)SSH_SHELL_CMD- Remote shell command to use (default:sh -c)
Input Format:
{
"host": "example.com",
"port": 22,
"user": "username",
"password": "password",
"script": "ls -la /tmp",
"timeout": 30
}Or using key-based authentication:
{
"host": "example.com",
"user": "username",
"key_path": "/path/to/private/key",
"script": "ls -la /tmp",
"timeout": 30
}Output Format:
{
"host": "example.com",
"script": "ls -la /tmp",
"stdout": "total 1234\ndrwxrwxrwt...",
"stderr": "",
"exit_code": 0,
"success": true,
"error": ""
}Docker Image:
docker run -e SSH_HOST=example.com -e SSH_USER=user -e SSH_PASSWORD=pass ghcr.io/mudler/mcps/ssh:latestOr with key-based authentication:
docker run -e SSH_HOST=example.com -e SSH_USER=user -e SSH_KEY_PATH=/path/to/key -v /host/keys:/path/to/key ghcr.io/mudler/mcps/ssh:latestLocalAI configuration ( to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"ssh": {
"command": "docker",
"env": {
"SSH_HOST": "example.com",
"SSH_USER": "username",
"SSH_PASSWORD": "password",
"SSH_SHELL_CMD": "bash -c"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/ssh:master"
]
}
}
}A flexible script and program execution server that allows AI models to run pre-defined scripts and programs as tools. Scripts can be defined inline or via file paths, and programs can be executed directly.
Features:
- Execute scripts from file paths or inline content
- Run arbitrary programs/commands
- Automatic interpreter detection (shebang or file extension)
- Configurable timeouts per script/program
- Custom working directories and environment variables
- Comprehensive output capture (stdout, stderr, exit code, duration)
Configuration:
SCRIPTS- JSON string defining scripts/programs (required)
Script Configuration Format:
[
{
"name": "hello_world",
"description": "A simple hello world script",
"content": "#!/bin/bash\necho 'Hello, World!'",
"timeout": 10
},
{
"name": "run_python",
"description": "Run a Python script from file",
"path": "/scripts/process_data.py",
"interpreter": "python3",
"timeout": 30,
"working_dir": "/data"
},
{
"name": "list_files",
"description": "List files in a directory",
"command": "ls",
"timeout": 5
}
]Executor Object Fields:
name(string, required): Tool name (must be valid identifier)description(string, required): Tool descriptioncontent(string, optional): Inline script content (mutually exclusive withpathandcommand)path(string, optional): Path to script file (mutually exclusive withcontentandcommand)command(string, optional): Command/program to execute (mutually exclusive withcontentandpath)interpreter(string, optional): Interpreter to use (default: auto-detect from shebang or file extension)timeout(int, optional): Timeout in seconds (default: 30)working_dir(string, optional): Working directory for executionenv(map[string]string, optional): Additional environment variables
Execution Input:
{
"args": ["arg1", "arg2"]
}Execution Output:
{
"stdout": "Hello, World!\n",
"stderr": "",
"exit_code": 0,
"duration_ms": 15
}Docker Image:
docker run -e SCRIPTS='[{"name":"hello","description":"Hello script","content":"#!/bin/bash\necho hello"}]' ghcr.io/mudler/mcps/scripts:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"scripts": {
"command": "docker",
"env": {
"SCRIPTS": "[{\"name\":\"hello\",\"description\":\"Hello script\",\"content\":\"#!/bin/bash\\necho hello\"},{\"name\":\"list_files\",\"description\":\"List files\",\"command\":\"ls\"}]"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/scripts:master"
]
}
}
}A knowledge base management server that provides tools to interact with LocalRecall's REST API for managing collections, searching content, and managing documents.
Features:
- Search content in collections
- Create and reset collections
- Add documents to collections
- List collections and files
- Delete entries from collections
- Configurable tool enablement for security
Tools:
search- Search content in a LocalRecall collectioncreate_collection- Create a new collectionreset_collection- Reset (clear) a collectionadd_document- Add a document to a collectionlist_collections- List all collectionslist_files- List files in a collectiondelete_entry- Delete an entry from a collection
Configuration:
LOCALRECALL_URL- Base URL for LocalRecall API (default:http://localhost:8080)LOCALRECALL_API_KEY- Optional API key for authentication (sent asAuthorization: Bearer <key>)LOCALRECALL_COLLECTION- Default collection name (if set, tools are registered withoutcollection_nameparameter - the collection is automatically used from the environment variable)LOCALRECALL_ENABLED_TOOLS- Comma-separated list of tools to enable (default: all tools enabled). Valid values:search,create_collection,reset_collection,add_document,list_collections,list_files,delete_entry
Note: When LOCALRECALL_COLLECTION is set, the tools search, add_document, list_files, and delete_entry are registered with different input schemas that do not include the collection_name parameter. The collection name is automatically taken from the environment variable.
Search Input Format:
When LOCALRECALL_COLLECTION is not set:
{
"collection_name": "myCollection",
"query": "search term",
"max_results": 5
}When LOCALRECALL_COLLECTION is set (e.g., LOCALRECALL_COLLECTION=myCollection), the tool schema does not include collection_name:
{
"query": "search term",
"max_results": 5
}Search Output Format:
{
"query": "search term",
"max_results": 5,
"results": [
{
"content": "...",
"metadata": {...}
}
],
"count": 1
}Add Document Input Format:
When LOCALRECALL_COLLECTION is not set:
{
"collection_name": "myCollection",
"file_path": "/path/to/file.txt",
"filename": "file.txt"
}Or with inline content:
{
"collection_name": "myCollection",
"file_content": "Document content here",
"filename": "document.txt"
}When LOCALRECALL_COLLECTION is set, the tool schema does not include collection_name:
{
"file_path": "/path/to/file.txt",
"filename": "file.txt"
}List Files Input Format:
When LOCALRECALL_COLLECTION is not set:
{
"collection_name": "myCollection"
}When LOCALRECALL_COLLECTION is set, the tool schema has no parameters (empty object):
{}Delete Entry Input Format:
When LOCALRECALL_COLLECTION is not set:
{
"collection_name": "myCollection",
"entry": "filename.txt"
}When LOCALRECALL_COLLECTION is set, the tool schema does not include collection_name:
{
"entry": "filename.txt"
}Docker Image:
docker run -e LOCALRECALL_URL=http://localhost:8080 -e LOCALRECALL_API_KEY=your-key-here ghcr.io/mudler/mcps/localrecall:latestWith default collection (tools will not require collection_name parameter):
docker run -e LOCALRECALL_URL=http://localhost:8080 -e LOCALRECALL_COLLECTION=myCollection ghcr.io/mudler/mcps/localrecall:latestWhen LOCALRECALL_COLLECTION is set, the collection-specific tools (search, add_document, list_files, delete_entry) are automatically configured to use that collection, and the collection_name parameter is removed from their input schemas.
Enable specific tools only:
docker run -e LOCALRECALL_URL=http://localhost:8080 -e LOCALRECALL_ENABLED_TOOLS="search,list_collections,list_files" ghcr.io/mudler/mcps/localrecall:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"localrecall": {
"command": "docker",
"env": {
"LOCALRECALL_URL": "http://localhost:8080",
"LOCALRECALL_API_KEY": "your-api-key",
"LOCALRECALL_COLLECTION": "myCollection",
"LOCALRECALL_ENABLED_TOOLS": "search,list_collections,add_document"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/localrecall:master"
]
}
}
}A shared TODO list management server that allows multiple agents to coordinate tasks with states, assignees, and dependencies. Perfect for agent team coordination with dependency management and role-based access control.
Features:
- Shared TODO list accessible by multiple agents/processes
- File-based persistence with atomic writes
- File locking for concurrent access safety
- Task states: pending, in_progress, done
- Assignee tracking for task ownership
- Dependency management - TODOs can depend on other TODOs
- Circular dependency detection - Prevents invalid dependency chains
- Status validation - Prevents starting/completing TODOs until dependencies are satisfied
- Role-based access control - Admin mode for leader actions, agent mode for self-service
- Full CRUD operations (add, update, remove, list)
- Status summary with counts by state and assignee
- Query ready and blocked TODOs
Tools:
Always Available (Agent & Admin):
list_todos- List all TODO itemsget_todo_status- Get a summary of the TODO list with counts by status and assigneeget_ready_todos- Get all TODO items that are ready to start (pending with all dependencies satisfied)get_blocked_todos- Get all TODO items that are blocked by dependenciesget_todo_dependencies- Get dependencies for a TODO item (direct and optionally transitive)update_todo_status- Update the status of a TODO item (pending, in_progress, or done)- In agent mode: Only allows updating TODOs assigned to the agent (requires
agent_nameparameter) - In admin mode: Allows updating any TODO (no
agent_namerequired)
- In agent mode: Only allows updating TODOs assigned to the agent (requires
Admin Only (requires TODO_ADMIN_MODE=true):
add_todo- Add a new TODO item to the shared listremove_todo- Remove a TODO item by IDupdate_todo_assignee- Update the assignee of a TODO itemadd_todo_dependency- Add a dependency to a TODO itemremove_todo_dependency- Remove a dependency from a TODO item
Configuration:
TODO_FILE_PATH- Environment variable to set the TODO file path (default:/data/todos.json)TODO_ADMIN_MODE- Set totrueto enable admin-only tools (add, remove, assign, manage dependencies). When not set, only read operations and self-service status updates are available.
TODO Item Format:
{
"id": "task-1",
"title": "Implement feature X",
"status": "in_progress",
"assignee": "agent1",
"depends_on": ["task-0"]
}Add TODO Input Format:
{
"id": "task-1",
"title": "Implement feature X",
"assignee": "agent1",
"depends_on": ["task-0"]
}Note: The id field is required and must be unique. IDs are not auto-generated for predictability.
Update Status Input Format:
In admin mode:
{
"id": "task-1",
"status": "done"
}In agent mode (requires agent_name):
{
"id": "task-1",
"status": "done",
"agent_name": "agent1"
}Dependency Management:
TODOs can depend on other TODOs. A TODO cannot transition to in_progress or done until all its dependencies are done. The system prevents:
- Circular dependencies (A β B β A)
- Starting/completing TODOs with unsatisfied dependencies
- Removing TODOs that other TODOs depend on
Get Ready TODOs Output Format:
{
"items": [
{
"id": "task-2",
"title": "Task 2",
"status": "pending",
"assignee": "agent1",
"depends_on": ["task-1"]
}
],
"count": 1
}Get Blocked TODOs Output Format:
{
"items": [
{
"id": "task-3",
"title": "Task 3",
"status": "pending",
"assignee": "agent2",
"blocked_by": [
{
"id": "task-1",
"title": "Task 1",
"status": "pending"
}
]
}
],
"count": 1
}Get TODO Dependencies Output Format:
{
"direct": [
{
"id": "task-1",
"title": "Task 1",
"status": "done"
}
],
"direct_count": 1
}List TODOs Output Format:
{
"items": [
{
"id": "task-1",
"title": "Implement feature X",
"status": "in_progress",
"assignee": "agent1",
"depends_on": ["task-0"]
}
],
"count": 1
}Status Summary Output Format:
{
"total": 10,
"pending": 3,
"in_progress": 5,
"done": 2,
"blocked": 2,
"ready": 1,
"by_assignee": {
"agent1": 4,
"agent2": 6
}
}Docker Image:
Agent mode (read-only + self-service):
docker run -e TODO_FILE_PATH=/custom/path/todos.json -v /host/data:/data ghcr.io/mudler/mcps/todo:latestAdmin mode (full access):
docker run -e TODO_FILE_PATH=/custom/path/todos.json -e TODO_ADMIN_MODE=true -v /host/data:/data ghcr.io/mudler/mcps/todo:latestLocalAI configuration (to add to the model config):
Agent mode:
mcp:
stdio: |
{
"mcpServers": {
"todo": {
"command": "docker",
"env": {
"TODO_FILE_PATH": "/data/todos.json"
},
"args": [
"run", "-i", "--rm", "-v", "/host/data:/data",
"ghcr.io/mudler/mcps/todo:master"
]
}
}
}Admin mode:
mcp:
stdio: |
{
"mcpServers": {
"todo": {
"command": "docker",
"env": {
"TODO_FILE_PATH": "/data/todos.json",
"TODO_ADMIN_MODE": "true"
},
"args": [
"run", "-i", "--rm", "-v", "/host/data:/data",
"ghcr.io/mudler/mcps/todo:master"
]
}
}
}Note: When TODO_ADMIN_MODE is not set or set to false, only read operations and self-service status updates are available. Agents can only update TODOs assigned to them by providing their agent_name in the update_todo_status request. Admin mode enables all tools including adding/removing TODOs, managing dependencies, and assigning tasks.
A shared mailbox server that enables message exchange between different agents in a team. Each agent instance reads only its own messages while being able to send messages to any agent.
Features:
- Shared mailbox accessible by multiple agents/processes
- File-based persistence with atomic writes
- File locking for concurrent access safety
- Agent-specific message filtering
- Read/unread status tracking
- Message deletion (only by recipient)
- Timestamp tracking for all messages
Tools:
send_message- Send a message to a recipient agentread_messages- Read all messages for this agentmark_message_read- Mark a message as read by IDmark_message_unread- Mark a message as unread by IDdelete_message- Delete a message by ID (only if recipient matches this agent)
Configuration:
MAILBOX_FILE_PATH- Environment variable to set the mailbox file path (default:/data/mailbox.json)MAILBOX_AGENT_NAME- Environment variable for this agent's name (required)
Message Format:
{
"id": "1703123456789000000",
"sender": "agent1",
"recipient": "agent2",
"content": "Please review the changes",
"timestamp": "2023-12-21T10:30:56.789Z",
"read": false
}Send Message Input Format:
{
"recipient": "agent2",
"content": "Please review the changes"
}Send Message Output Format:
{
"id": "1703123456789000000",
"sender": "agent1",
"recipient": "agent2",
"content": "Please review the changes",
"timestamp": "2023-12-21T10:30:56.789Z"
}Read Messages Output Format:
{
"messages": [
{
"id": "1703123456789000000",
"sender": "agent1",
"recipient": "agent2",
"content": "Please review the changes",
"timestamp": "2023-12-21T10:30:56.789Z",
"read": false
}
],
"count": 1,
"unread": 1
}Docker Image:
docker run -e MAILBOX_FILE_PATH=/custom/path/mailbox.json -e MAILBOX_AGENT_NAME=agent1 -v /host/data:/data ghcr.io/mudler/mcps/mailbox:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"mailbox": {
"command": "docker",
"env": {
"MAILBOX_FILE_PATH": "/data/mailbox.json",
"MAILBOX_AGENT_NAME": "agent1"
},
"args": [
"run", "-i", "--rm", "-v", "/host/data:/data",
"ghcr.io/mudler/mcps/mailbox:master"
]
}
}
}Note: Each agent instance must have a unique MAILBOX_AGENT_NAME to properly filter and manage its own messages. The mailbox file is shared across all agents, but each agent only sees messages where it is the recipient.
A filesystem operations server that provides tools to read, write, edit, and search files and directories.
Features:
- Read files with line numbers and optional offset/limit
- Write files with automatic parent directory creation
- Edit files with string replacement (single or all occurrences)
- Find files by glob patterns (sorted by modification time)
- Search file contents with regex patterns
- JSON schema validation for inputs/outputs
Tools:
read- Read file with line numbers, supports optional offset and limit for reading specific line rangeswrite- Write content to a file, creates parent directories if needed, overwrites existing filesedit- Replace old string with new string in a file, old string must be unique unless all=trueglob- Find files by glob pattern, sorted by modification time (newest first)grep- Search files for regex pattern, returns up to 50 matches
Read File Input Format:
{
"path": "/path/to/file.txt",
"offset": 0,
"limit": 50
}Read File Output Format:
{
"content": " 1| line one\n 2| line two",
"total_lines": 100,
"success": true
}Write File Input Format:
{
"path": "/path/to/file.txt",
"content": "file content here"
}Edit File Input Format:
{
"path": "/path/to/file.txt",
"old": "old text",
"new": "new text",
"all": false
}Glob Files Input Format:
{
"pat": "**/*.go",
"path": "."
}Grep Files Input Format:
{
"pat": "func main",
"path": "."
}Docker Image:
docker run -v /host/workspace:/workspace ghcr.io/mudler/mcps/filesystem:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"filesystem": {
"command": "docker",
"args": [
"run", "-i", "--rm", "-v", "/host/workspace:/workspace",
"ghcr.io/mudler/mcps/filesystem:master"
]
}
}
}An MCP server for controlling Claude Code CLI sessions asynchronously. Start sessions, monitor progress, retrieve logs, and manage multiple concurrent Claude Code processes. It follows the same pattern as the opencode MCP server but is specifically designed for Claude Code.
Features:
- Background task delegation to Claude Code
- Async session management with unique session IDs
- Start Claude Code sessions with full command-line option support
- Monitor session status (starting, running, completed, failed, stopped)
- Retrieve stdout/stderr logs from sessions
- Stop running sessions gracefully
- List all sessions with filtering by status
- Tool restrictions via
--allowedToolsand--toolsflags - Environment passthrough to Claude subprocesses
- Configurable concurrent session limits
- Automatic log cleanup based on retention policy
Tools:
start_session- Start a new Claude session with a prompt and optionsget_session_status- Get the current status of a session by IDget_session_logs- Retrieve stdout and stderr logs from a sessionstop_session- Stop a running sessionlist_sessions- List all sessions with optional status filtering
Configuration:
CLAUDE_SESSION_DIR- Directory for session state and logs (default:/tmp/claude-sessions)CLAUDE_BINARY- Path to Claude binary (default:claude)CLAUDE_MAX_SESSIONS- Maximum number of concurrent sessions (default:10)CLAUDE_LOG_RETENTION_HOURS- Hours to retain session logs before cleanup (default:24)CLAUDE_WORK_DIR- Working directory for Claude processes (default:/root)CLAUDE_MODEL- Default model to use (e.g.,sonnet,opus)CLAUDE_AGENT- Specify an agent for sessionsCLAUDE_FORMAT- Output format (default:json)CLAUDE_SHARE- Whether to share sessions (true/false)CLAUDE_ATTACH- Files to attach to sessionsCLAUDE_PORT- Port for remote controlCLAUDE_VARIANT- Model variantCLAUDE_ALLOWED_TOOLS- Tools allowed without prompting (e.g.,"Bash,Read,Edit")CLAUDE_TOOLS- Restrict which tools Claude can use (e.g.,"Bash,Read,Edit")CLAUDE_TOOL_START_SESSION_NAME- Override the start_session tool nameCLAUDE_TOOL_GET_SESSION_STATUS_NAME- Override the get_session_status tool nameCLAUDE_TOOL_GET_SESSION_LOGS_NAME- Override the get_session_logs tool nameCLAUDE_TOOL_STOP_SESSION_NAME- Override the stop_session tool nameCLAUDE_TOOL_LIST_SESSIONS_NAME- Override the list_sessions tool name
Start Session Example:
{
"message": "Find and fix the bug in auth.py",
"allowed_tools": "Bash,Read,Edit",
"title": "Bug Fix Task"
}Start Session Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "starting",
"message": "Session started successfully"
}Get Session Status Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"pid": "12345",
"exit_code": "0",
"created_at": "2025-01-15T10:30:00Z",
"started_at": "2025-01-15T10:30:01Z",
"stopped_at": "2025-01-15T10:30:15Z",
"duration": "14s"
}Get Session Logs Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"stdout": "Working on the bug fix...",
"stderr": "",
"line_count": 50
}Adding the Server:
claude mcp add claude-mcp -- npx -y mudler/MCPs/claudeDocker Image:
docker run -e CLAUDE_MAX_SESSIONS=5 -e CLAUDE_LOG_RETENTION_HOURS=48 ghcr.io/mudler/mcps/claude:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"claude": {
"command": "docker",
"env": {
"CLAUDE_MAX_SESSIONS": "5",
"CLAUDE_LOG_RETENTION_HOURS": "48"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/claude:master"
]
}
}
}An MCP server for controlling opencode AI sessions asynchronously. Start sessions, monitor progress, retrieve logs, and manage multiple concurrent opencode processes.
Features:
- Async session management with unique session IDs
- Start opencode sessions with full command-line option support
- Monitor session status (running, completed, failed, stopped)
- Retrieve stdout/stderr logs from sessions
- Stop running sessions gracefully
- List all sessions with filtering by status
- Configurable concurrent session limits
- Automatic log cleanup based on retention policy
- Ephemeral sessions (do not survive server restarts)
Tools:
start_session- Start a new opencode session with a message and optionsget_session_status- Get the current status of a session by IDget_session_logs- Retrieve stdout and stderr logs from a sessionstop_session- Stop a running sessionlist_sessions- List all sessions with optional status filtering
Configuration:
OPENCODE_SESSION_DIR- Directory for session state and logs (default:/tmp/opencode-sessions)OPENCODE_BINARY- Path to opencode binary (default:/usr/local/bin/opencode)OPENCODE_MAX_SESSIONS- Maximum number of concurrent sessions (default:10)OPENCODE_LOG_RETENTION_HOURS- Hours to retain session logs before cleanup (default:24)OPENCODE_CONFIG- Path to opencode config fileOPENCODE_CONFIG_CONTENT- Inline config as JSON stringOPENCODE_MODEL- Model to use in provider/model format (e.g.,openai/gpt-4)OPENCODE_FORMAT- Output format:default(formatted) orjson(raw JSON events) (default:json)OPENCODE_AGENT- Agent to use for sessionsOPENCODE_SHARE- Share sessions:trueorfalse(default:false)OPENCODE_VARIANT- Model variant for provider-specific reasoning effortOPENCODE_WORKDIR- Directory where opencode starts (default:/root)
Start Session Example:
{
"message": "Explain quantum computing",
"title": "Quantum Computing Explanation"
}Start Session Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "starting",
"message": "Session started successfully"
}Get Session Status Example:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000"
}Get Session Status Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"pid": "12345",
"exit_code": "0",
"created_at": "2025-01-15T10:30:00Z",
"started_at": "2025-01-15T10:30:01Z",
"stopped_at": "2025-01-15T10:30:15Z",
"duration": "14s"
}Get Session Logs Example:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"lines": 50
}Get Session Logs Output:
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"stdout": "Quantum computing is a form of computing that takes advantage...",
"stderr": "",
"line_count": 50
}Docker Image:
docker run -e OPENCODE_MAX_SESSIONS=5 -e OPENCODE_LOG_RETENTION_HOURS=48 ghcr.io/mudler/mcps/opencode:latestWith model configuration:
docker run -e OPENCODE_MODEL=openai/gpt-4 -e OPENCODE_FORMAT=json ghcr.io/mudler/mcps/opencode:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"opencode": {
"command": "docker",
"env": {
"OPENCODE_MAX_SESSIONS": "5",
"OPENCODE_LOG_RETENTION_HOURS": "48"
},
"args": [
"run", "-i", "--rm",
"ghcr.io/mudler/mcps/opencode:master"
]
}
}
}A Jellyfin media server MCP that provides tools for searching, browsing, and controlling your Jellyfin media library.
Features:
- Search and browse media (movies, series, episodes) with filtering and pagination
- Get detailed item metadata (cast, media quality, external IDs)
- TV show navigation (seasons, episodes, next up)
- Playback control on active sessions (pause, stop, seek, next/prev)
- User data management (favorites, played status)
- Similar item recommendations
- Configurable tool registration (enable only the tools you need)
Tools:
search- Full-text search across all media typesbrowse_library- Browse/filter items with sorting and paginationget_item- Get full metadata for a specific itemlist_libraries- List all media librariesget_similar- Find similar items for recommendationsget_latest- Get recently added items (requires user ID)get_seasons- List seasons for a TV seriesget_episodes- List episodes, optionally by seasonget_next_up- Get next unwatched episodes (requires user ID)get_sessions- List active playback sessionsplayback_control- Control playback (Pause, Unpause, Stop, NextTrack, PreviousTrack, Seek)set_favorite- Mark/unmark items as favorites (requires user ID)set_played- Mark/unmark items as played (requires user ID)
Configuration:
JELLYFIN_URL- Jellyfin server URL (required, e.g.http://jellyfin:8096)JELLYFIN_API_KEY- API key for authentication (required, create in Dashboard > Admin > API Keys)JELLYFIN_USERNAME- Username to resolve for user-scoped operations (optional, easier alternative to user ID)JELLYFIN_USER_ID- User ID for user-scoped operations like favorites, played, next-up (optional, use JELLYFIN_USERNAME instead)JELLYFIN_TOOLS- Comma-separated list of tools to register, or "all" (default: all)
Docker Image:
docker run -e JELLYFIN_URL=http://jellyfin:8096 -e JELLYFIN_API_KEY=your-key ghcr.io/mudler/mcps/jellyfin:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"jellyfin": {
"command": "docker",
"env": {
"JELLYFIN_URL": "http://your-jellyfin:8096",
"JELLYFIN_API_KEY": "your-api-key",
"JELLYFIN_USERNAME": "your-username"
},
"args": [
"run", "-i", "--rm",
"-e", "JELLYFIN_URL",
"-e", "JELLYFIN_API_KEY",
"-e", "JELLYFIN_USERNAME",
"ghcr.io/mudler/mcps/jellyfin:master"
]
}
}
}A read-only GitHub MCP for reading issues and pull requests β their description, metadata, and discussion comments, plus the unified diff for PRs on request.
Features:
- Read issues (title, body, labels, state, comments)
- Read pull requests (title, body, base/head refs, draft/merged flags, comments)
- Optionally fetch the unified diff of a pull request
- Accepts either
owner/repo/numberor a full GitHub URL - Works anonymously on public repos (rate-limited) or authenticated via
GITHUB_TOKEN - Comment truncation to protect context size
Tools:
get_issue- Fetch an issue with its body and commentsget_pull_request- Fetch a PR with its body, comments, and (optionally) its unified diff
Configuration:
GITHUB_TOKEN- Personal access token (optional; required for private repos and higher rate limits)GITHUB_API_URL- API base URL (default:https://api.github.com; set for GitHub Enterprise)GITHUB_MAX_COMMENT_LENGTH- Max characters per comment/body before truncation (default: 4000)GITHUB_TOOLS- Comma-separated list of tools to register, orall(default: all)
Docker Image:
docker run -e GITHUB_TOKEN=your-token ghcr.io/mudler/mcps/github:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"github": {
"command": "docker",
"env": {
"GITHUB_TOKEN": "your-token"
},
"args": [
"run", "-i", "--rm",
"-e", "GITHUB_TOKEN",
"ghcr.io/mudler/mcps/github:master"
]
}
}
}A computer-use server that gives a model a real XFCE desktop and a real Chrome browser inside a container, viewable live over noVNC. It implements no tools of its own: it starts the computer and browser MCP servers from nib on in-memory transports and re-exposes their merged tool list on a single stdio server.
Unlike every other server in this repository, this one is container-only. The binary alone is not useful: it needs the XFCE desktop, the session D-Bus, and the cua-driver serve daemon that the image starts inside the desktop session.
Features:
- Desktop control addressed by accessibility element index, not just pixel coordinates (AT-SPI via
cua-driver) - Browser control over an accessibility snapshot with
@eNelement refs - Chrome runs on the same desktop, so the browser and desktop tools compose
- Live view of what the model is doing at
http://localhost:6901 - Screenshots are returned as image content, so a vision-capable model is required
Tools:
computer_use- Desktop control. Actions:capture,click,double_click,right_click,middle_click,drag,scroll,type,key,set_value,wait,list_apps,open_app,close_app,focus_app. Capture modes:som(numbered elements, default),vision,axbrowser_navigate- Open a URL and return a snapshot of the page's interactive elementsbrowser_snapshot- Re-read the current page's accessibility tree for fresh refsbrowser_click- Click the element identified by an@eNrefbrowser_type- Focus an element, clear it, and type into itbrowser_press- Send a single named key (Enter,Tab,Escape, β¦) to whatever has focusbrowser_scroll- Scroll the viewport up or downbrowser_vision- Screenshot the current page for visual inspection
Configuration:
CUA_ENABLE_COMPUTER- Registercomputer_use(default:true)CUA_ENABLE_BROWSER- Register thebrowser_*tools (default:true). Setting both this andCUA_ENABLE_COMPUTERtofalseis a fatal errorCUA_TOOLS- Comma-separated list of tools to register, orall(default: all)CUA_DRIVER_CMD- Path to thecua-driverbinary (default:cua-driver)CUA_CHROME_PATH- Chrome binary override (default: nib auto-discovers/usr/bin/google-chrome, then/usr/bin/chromium)CUA_BROWSER_PROFILE_DIR- Chrome profile directory (default:dante-browser-profileunder the user cache dir, i.e./home/cua/.cache/in this image β it lives and dies with the container unless you mount a volume)CUA_ALLOW_PRIVATE_URLS- Allow the browser to navigate to localhost and RFC1918 addresses (default:false)CUA_READY_TIMEOUT- Budget for the startup readiness gate: X display wait, driver probe, and each upstream handshake (default:60s). Values that do not parse, or that are zero or negative, fall back to the defaultCOGITO_LOG_LEVEL/LOG_FORMAT- nib's log level and format (jsonfor JSON). Logs always go to stderr; stdout carries only JSON-RPC
Inherited from the base image, and useful:
VNC_RESOLUTION- Desktop resolution (default:1024x768). Raising it raises the token cost of every screenshot proportionallyVNC_COL_DEPTH- Colour depth (default:24)VNC_PW- VNC password. If unset, the VNC server runs with no authentication at allVNC_PORT/NOVNC_PORT- Ports for TigerVNC and noVNC (defaults:5901,6901)
Docker Image:
docker run -i --rm -p 6901:6901 ghcr.io/mudler/mcps/cua:latestThen open http://localhost:6901 in a browser to watch the desktop live. Port 5901 is also exposed for a native VNC client; publish it only if you need it, and set VNC_PW when you do.
The image is built with make build MCP_SERVER=cua, which uses cua/Dockerfile rather than the shared one.
LocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"cua": {
"command": "docker",
"args": [
"run", "-i", "--rm", "-p", "6901:6901",
"ghcr.io/mudler/mcps/cua:master"
]
}
}
}Security posture:
This container is the security boundary, and it is a soft one. Treat it as disposable and keep it isolated.
- Chrome runs as root with
--no-sandbox. The whole container runs as root because supervisord needs it to drop privileges per program, and Chrome refuses to sandbox itself as root, so a wrapper on/usr/bin/google-chromeand/usr/bin/chromiumpasses--no-sandbox. A renderer compromise therefore yields root inside the container. This is a deliberate, accepted trade-off β dropping Chrome to an unprivileged user costs the shared X session and the AT-SPI tree thatcomputer_usedepends on. - Do not run this container with
--network hostor host path mounts. Given the point above, either one turns a browser compromise into a host compromise. - The container is a real interactive desktop. Anything reachable on its network is reachable by whatever the model drives β which is why
CUA_ALLOW_PRIVATE_URLSdefaults tofalseand why placing this container on a network with internal services deserves thought. - noVNC and VNC are unauthenticated unless
VNC_PWis set. Anyone who can reach the published port has full keyboard and mouse control of the desktop. Bind them to localhost or leave them unpublished on shared hosts. - nib hard-blocks a small set of key combos (e.g.
cmd+ctrl+q,win+l) and typed-text patterns (curl β¦ | bash,sudo rm -rf, fork bombs). This is a guardrail against accidents, not a sandbox β there is no interactive approval prompt in this server.
Notes and limitations:
- The image is large: roughly 6.4 GB, of which about 5.7 GB is the
trycua/cua-xfcebase. Budget disk and pull time accordingly. - The base image is
trycua/cua-xfce:latest, unpinned, as is Google's Chrome apt repository. A rebuild can therefore pick up a different desktop or a different Chrome than the last one did. The Chrome version actually shipped is recorded in the image at/etc/cua-chrome-version, and the build fails loudly if the base'sxstartup.shchanges shape under the daemon injection. /dev/uinputis not available in a container, socua-driverinjects input viaXSendEvent. Right, middle, and double clicks may not register on some GTK and Qt applications. Clicks addressed by element index go through AT-SPI and are unaffected, which is why element-based addressing is preferred.- Startup takes tens of seconds: the desktop, then the accessibility bus, then the
cua-driver servedaemon must all come up before the first tool call. The entrypoint waits up to 120s for the driver socket. - Only
linux/amd64is built.trycuapublishes the base for amd64 only, and Google ships no arm64 Chrome.deb; an arm64 build fails at the Chrome install step.
- Go 1.24.7 or later
- Docker (for containerized builds)
- Make (for using the Makefile)
Use the provided Makefile for easy development:
# Show all available commands
make help
# Development workflow
make dev
# Build specific server
make MCP_SERVER=duckduckgo build
make MCP_SERVER=weather build
make MCP_SERVER=openweathermap build
make MCP_SERVER=wait build
make MCP_SERVER=memory build
make MCP_SERVER=shell build
make MCP_SERVER=ssh build
make MCP_SERVER=scripts build
make MCP_SERVER=localrecall build
make MCP_SERVER=todo build
make MCP_SERVER=mailbox build
make MCP_SERVER=filesystem build
make MCP_SERVER=claude build
make MCP_SERVER=jellyfin build
make MCP_SERVER=github build
# Run tests and checks
make ci-local
# Build multi-architecture images
make build-multiarchTo add a new MCP server:
- Create a new directory under the project root
- Implement the server following the MCP SDK patterns
- Update the GitHub Actions workflow matrix in
.github/workflows/image.yml - Update this README with the new server information
Example server structure:
package main
import (
"context"
"log"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
func main() {
server := mcp.NewServer(&mcp.Implementation{
Name: "your-server",
Version: "v1.0.0"
}, nil)
// Add your tools here
mcp.AddTool(server, &mcp.Tool{
Name: "your-tool",
Description: "your tool description"
}, YourToolFunction)
if err := server.Run(context.Background(), &mcp.StdioTransport{}); err != nil {
log.Fatal(err)
}
}Docker images are automatically built and pushed to GitHub Container Registry:
ghcr.io/mudler/mcps/<component>:latest- Latest component tagged versionghcr.io/mudler/mcps/<component>:v<version>- Specific tagged versionsghcr.io/mudler/mcps/<component>:master- Development versions
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Run
make ci-localto ensure all checks pass - Submit a pull request
This project is licensed under the terms specified in the LICENSE file.
This project implements servers for the Model Context Protocol (MCP), a standard for connecting AI models to external data sources and tools.
For more information about MCP, visit the official documentation.
A Model Context Protocol (MCP) server that allows sending chat completion messages to any OpenAI-compatible endpoint, with support for background job tracking using goroutines and in-memory storage with TTL.
Features:
- Send chat completion requests to OpenAI-compatible endpoints
- Background job tracking with asynchronous execution
- In-memory storage with configurable TTL for results
- Three MCP tools for managing sub-agent calls
Tools:
sub_agent_send- Send a chat completion message to an OpenAI-compatible endpointsub_agent_list- List all active sub-agent calls with their statussub_agent_get_result- Get the result of a completed sub-agent call by task ID
Configuration:
OPENAI_BASE_URL- The base URL for the OpenAI API endpoint (default:https://api.openai.com/v1)OPENAI_MODEL- The model to use for chat completions (default:gpt-3.5-turbo)OPENAI_API_KEY- The API key for authentication (required)TTL- Time-to-live for stored results in Go duration format (default:1h)
Docker Image:
docker run -e OPENAI_API_KEY=your-key ghcr.io/mudler/mcps/sub-agent:latestLocalAI configuration (to add to the model config):
mcp:
stdio: |
{
"mcpServers": {
"sub-agent": {
"command": "docker",
"env": {
"OPENAI_BASE_URL": "https://your-openai-compatible-endpoint/v1",
"OPENAI_MODEL": "your-model",
"OPENAI_API_KEY": "your-api-key",
"TTL": "2h"
},
"args": [
"run", "-i", "--rm",
"-e", "OPENAI_BASE_URL",
"-e", "OPENAI_MODEL",
"-e", "OPENAI_API_KEY",
"-e", "TTL",
"ghcr.io/mudler/mcps/sub-agent:master"
]
}
}
}For more details, see the sub-agent README.