MCP Server Implementation
Relevant source files
The following files were used as context for generating this wiki page:The Dokku MCP Server is a Go application that exposes Dokku's management capabilities through the standardized Model Context Protocol (MCP). This allows AI agents and Large Language Models (LLMs) to interact with and manage a Dokku instance programmatically. The server is designed with a modular, plugin-based architecture to encapsulate different sets of Dokku features.
The server supports multiple transport modes for client communication and provides a standardized JSON envelope for tool responses, ensuring predictable interactions with MCP clients. Configuration is flexible, supporting both YAML files and environment variables.
Sources: README.md
Architecture
The server's architecture is built on Domain-Driven Design (DDD) principles and heavily utilizes a plugin-based system to organize features. Dependency injection is managed by the Uber Fx framework, which wires together components at startup.
Sources: README.md, internal/server/module.go
Core Components
The server is composed of several key components that work together to handle MCP requests and interact with Dokku.
server.MCPServer: The core MCP server instance from themcp-golibrary. It handles the low-level MCP communication and is configured with capabilities like tools, resources, and prompts.MCPAdapter: Acts as a bridge between themcp-goserver and the application's plugin system. It fetches active tools and resources from the plugin registry and registers them with theMCPServer.DynamicServerPluginRegistry: Manages the lifecycle of all server plugins. It discovers which Dokku plugins are installed and activates the corresponding server plugins, making their features available.dokkuApi.DokkuClient: An infrastructure component responsible for executing commands on the Dokku host via SSH. It includes security features like command blacklisting.ServerPlugin: The interface that all feature plugins (e.g.,app,core,domain) must implement.
Sources: internal/server/module.go:19-27,34-40, internal/dokku-api/client_blacklist_test.go:13, internal/server-plugin/domain/server-plugin.go:9-15
The following diagram illustrates the relationships between these core components.
Sources: internal/server/module.go:29-53
Server Initialization and Lifecycle
The application uses Uber Fx to manage the startup and shutdown lifecycle. The main server module defines all the necessary providers for the core components.
- Instantiation: The
NewMCPServerInstancefunction creates theserver.MCPServerfrom themcp-golibrary, enabling tool, resource, and prompt capabilities. - Dependency Injection: Fx injects the server configuration (
ServerConfig), logger (slog.Logger), and other dependencies into the component constructors. - Plugin Registration: An Fx
Invokehook callsregisterServerHooks, which in turn uses theMCPAdapterto register routes (tools, resources, prompts) from active plugins with theMCPServer. - Plugin Sync: Another
Invokehook registers theDynamicServerPluginRegistry'sRegisterHooksmethod with the Fx lifecycle. OnStart, this triggers an initial synchronization of plugins.
Sources: internal/server/module.go:19-27,55-57
The startup sequence is visualized below.
Plugin System
The server's functionality is extended through plugins. Each plugin encapsulates a specific set of Dokku features, such as application management (apps) or core functionality (core).
Plugin Interfaces
A unified ServerPlugin interface defines the basic metadata for any plugin. Functionality is exposed by implementing provider interfaces.
ServerPlugin: Base interface with methods likeID(),Name(),Description(), andDokkuPluginName(). TheDokkuPluginNameis used by the registry to determine if the plugin should be active. If it's an empty string, the plugin is always active.ResourceProvider: For plugins that expose MCP resources (e.g.,dokku://apps/list).ToolProvider: For plugins that expose MCP tools (e.g.,create_app).PromptProvider: For plugins that expose MCP prompts (e.g.,app_doctor).
Sources: internal/server-plugin/domain/server-plugin.go:9-31, internal/server-plugins/core/plugin.go:61, internal/server-plugins/app/plugin.go:65
The diagram below shows the interface hierarchy.
Transport Modes
The server supports two transport modes for clients, configured via the transport.type setting.
| Mode | Description | Configuration (transport.type) |
|---|---|---|
stdio | Standard input/output for direct process communication. This is the default. | stdio |
sse | Server-Sent Events over HTTP for web-based or remote clients. | sse |
Sources: README.md, pkg/config/config.go:10,80
CORS Configuration
When using the sse transport, Cross-Origin Resource Sharing (CORS) can be configured. If transport.cors.enabled is false (the default), the underlying mcp-go library handles CORS by allowing all origins (*). If enabled, specific origins, methods, and headers can be configured.
| Setting | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enables the custom CORS middleware. |
allowed_origins | []string | [] | List of allowed origins. Supports wildcards (*.example.com). |
allowed_methods | []string | ["GET", "POST", "OPTIONS"] | List of allowed HTTP methods. |
allowed_headers | []string | ["Content-Type", "Authorization"] | List of allowed HTTP headers. |
max_age | int | 300 | Access-Control-Max-Age in seconds. |
Sources: pkg/config/config.go:15-22,83-87, CHANGELOG.md:9-14
MCP Communication Protocol
To ensure consistent and machine-readable responses, all tools return a standardized JSON object, defined by the ToolResponse struct. This envelope provides status, codes, messages, and optional data payloads.
Sources: internal/server/mcp_envelope.go:18-30
ToolResponse Structure
The ToolResponse struct is the canonical envelope for all tool call results.
| Field | Type | Description |
|---|---|---|
status | ToolStatus | High-level status: ok, error, or partial. |
code | string | A machine-readable code for the result (e.g., APP_CREATED). |
message | string | A human-readable message describing the result. |
data | ToolResponseData | A map containing arbitrary JSON data as the payload. |
links | []ToolLink | Provides follow-up actions for LLMs to chain commands safely. |
hint | string | A hint for the user or LLM on how to resolve an error. |
Sources: internal/server/mcp_envelope.go:18-30
Helper functions like OK(), Error(), and Partial() are provided to easily construct an mcp.CallToolResult containing a marshaled ToolResponse.
// internal/server/mcp_envelope.go:61-63
func OK(message string, data ToolResponseData) *mcp.CallToolResult {
return NewResult(ToolResponse{Status: ToolStatusOK, Message: message, Data: data})
}
Configuration
The server can be configured via a config.yaml file or through environment variables. Environment variables take precedence and must be prefixed with DOKKU_MCP_.
Sources: README.md, pkg/config/config.go:101-104
Key Configuration Options
YAML Key (ssh.*) | Environment Variable (DOKKU_MCP_SSH_*) | Description | Default |
|---|---|---|---|
host | DOKKU_MCP_SSH_HOST | The hostname or IP of the Dokku server. | localhost |
port | DOKKU_MCP_SSH_PORT | The SSH port on the Dokku server. | 3022 |
user | DOKKU_MCP_SSH_USER | The SSH user for Dokku commands. | dokku |
key_path | DOKKU_MCP_SSH_KEY_PATH | Path to the SSH private key. | dokku_mcp_test |
log_level | DOKKU_MCP_LOG_LEVEL | Logging level (debug, info, warn, error). | info |
security.blacklist | DOKKU_MCP_SECURITY_BLACKLIST | A comma-separated list of disabled commands. | [] |
expose_server_logs | DOKKU_MCP_EXPOSE_SERVER_LOGS | Exposes a get_server_logs tool for debugging. | false |
Sources: pkg/config/config.go:24-29,51,60,77-98
Client Configuration Generation
The project includes a helper utility to generate a .mcp.json file, which is used by MCP clients to discover and connect to the server. The go run ./cmd/gen-mcp-json command reads the server's configuration (from config.yaml or environment variables) and outputs a valid .mcp.json file with the correct command path and environment settings.
Sources: cmd/gen-mcp-json/main.go:30-61
Summary
The Dokku MCP Server provides a robust, extensible, and standardized interface for managing Dokku via the Model Context Protocol. Its plugin-based architecture allows for clear separation of concerns and easy addition of new features. With support for multiple transport modes, flexible configuration, and a well-defined communication protocol, it serves as a powerful bridge between modern AI agents and the Dokku PaaS.