Skip to main content
Glama
index.ts50.5 kB
/** * Dokploy MCP Server * * An MCP server that provides comprehensive integration with Dokploy, * allowing you to create, manage, deploy, and monitor applications * through Dokploy's powerful platform. * * Features: * - Project management (create, list, update, delete) * - Application deployment (create, deploy, update, stop, start) * - Database management (PostgreSQL, MySQL, MongoDB, Redis) * - Domain and SSL management * - Backup and restore operations * - Service monitoring and logs * - Documentation search */ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" import { z } from "zod" // Configuration schema for Dokploy connection export const configSchema = z.object({ dokployUrl: z.string() .url() .default(process.env.DOKPLOY_URL || "https://dok.bish.one") .describe("Your Dokploy instance URL (e.g., https://dok.bish.one)"), apiToken: z.string() .default(process.env.DOKPLOY_API_TOKEN || "") .describe("Your Dokploy API authentication token"), debug: z.boolean() .default(process.env.DEBUG === "true" || false) .describe("Enable debug logging for troubleshooting"), }) // Helper function to make API requests async function dokployRequest( config: z.infer<typeof configSchema>, endpoint: string, method: string = "GET", body?: any ): Promise<any> { const url = `${config.dokployUrl}/api${endpoint}` if (config.debug) { console.log(`[Dokploy API] ${method} ${url}`) } try { const response = await fetch(url, { method, headers: { "Content-Type": "application/json", "Accept": "application/json", "x-api-key": config.apiToken, }, body: body ? JSON.stringify(body) : undefined, }) if (!response.ok) { const errorText = await response.text() throw new Error(`Dokploy API error (${response.status}): ${errorText}`) } const data = await response.json() return data } catch (error) { if (config.debug) { console.error(`[Dokploy API Error]`, error) } throw error } } export default function createServer({ config, }: { config: z.infer<typeof configSchema> }) { // Validate API token is provided if (!config.apiToken) { console.error("❌ DOKPLOY_API_TOKEN environment variable is not set!") console.error("Please set your Dokploy API token in the environment variables.") console.error("Example: DOKPLOY_API_TOKEN=your-token-here") } const server = new McpServer({ name: "Dokploy MCP Server", version: "1.0.0", }) // ==================== PROJECT MANAGEMENT ==================== server.registerTool( "list-projects", { title: "List Projects", description: "List all projects in your Dokploy instance", inputSchema: {}, }, async () => { const projects = await dokployRequest(config, "/project.all", "GET") return { content: [{ type: "text", text: JSON.stringify(projects, null, 2), }], } } ) server.registerTool( "create-project", { title: "Create Project", description: "Create a new project in Dokploy", inputSchema: { name: z.string().describe("Project name"), description: z.string().optional().describe("Project description"), }, }, async ({ name, description }) => { const result = await dokployRequest(config, "/project.create", "POST", { name, description: description || "", }) return { content: [{ type: "text", text: `✅ Project created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "delete-project", { title: "Delete Project", description: "Delete a project from Dokploy", inputSchema: { projectId: z.string().describe("The ID of the project to delete"), }, }, async ({ projectId }) => { const result = await dokployRequest(config, `/project.remove`, "POST", { projectId, }) return { content: [{ type: "text", text: `✅ Project deleted successfully!`, }], } } ) // ==================== APPLICATION MANAGEMENT ==================== server.registerTool( "list-applications", { title: "List Applications", description: "List all applications in a project", inputSchema: { projectId: z.string().describe("The project ID to list applications from"), }, }, async ({ projectId }) => { const apps = await dokployRequest(config, `/application.all?projectId=${projectId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(apps, null, 2), }], } } ) server.registerTool( "create-application", { title: "Create Application", description: "Create a new application in Dokploy", inputSchema: { projectId: z.string().describe("The project ID to create the application in"), name: z.string().describe("Application name"), appType: z.enum(["docker", "git", "github"]).default("github").describe("Application type"), repository: z.string().optional().describe("Git repository URL (for git/github types)"), branch: z.string().default("main").describe("Git branch to deploy"), buildPath: z.string().default("/").describe("Build path in repository"), dockerfile: z.string().optional().describe("Path to Dockerfile (for docker type)"), env: z.record(z.string()).optional().describe("Environment variables as key-value pairs"), }, }, async ({ projectId, name, appType, repository, branch, buildPath, dockerfile, env }) => { const result = await dokployRequest(config, "/application.create", "POST", { projectId, name, appType, repository, branch, buildPath, dockerfile, env: env || {}, }) return { content: [{ type: "text", text: `✅ Application created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "deploy-application", { title: "Deploy Application", description: "Deploy an application in Dokploy", inputSchema: { applicationId: z.string().describe("The ID of the application to deploy"), }, }, async ({ applicationId }) => { const result = await dokployRequest(config, "/application.deploy", "POST", { applicationId, }) return { content: [{ type: "text", text: `🚀 Deployment started!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "stop-application", { title: "Stop Application", description: "Stop a running application", inputSchema: { applicationId: z.string().describe("The ID of the application to stop"), }, }, async ({ applicationId }) => { const result = await dokployRequest(config, "/application.stop", "POST", { applicationId, }) return { content: [{ type: "text", text: `⏸️ Application stopped successfully!`, }], } } ) server.registerTool( "start-application", { title: "Start Application", description: "Start a stopped application", inputSchema: { applicationId: z.string().describe("The ID of the application to start"), }, }, async ({ applicationId }) => { const result = await dokployRequest(config, "/application.start", "POST", { applicationId, }) return { content: [{ type: "text", text: `▶️ Application started successfully!`, }], } } ) server.registerTool( "restart-application", { title: "Restart Application", description: "Restart an application", inputSchema: { applicationId: z.string().describe("The ID of the application to restart"), }, }, async ({ applicationId }) => { const result = await dokployRequest(config, "/application.restart", "POST", { applicationId, }) return { content: [{ type: "text", text: `🔄 Application restarted successfully!`, }], } } ) server.registerTool( "delete-application", { title: "Delete Application", description: "Delete an application from Dokploy", inputSchema: { applicationId: z.string().describe("The ID of the application to delete"), }, }, async ({ applicationId }) => { const result = await dokployRequest(config, "/application.remove", "POST", { applicationId, }) return { content: [{ type: "text", text: `✅ Application deleted successfully!`, }], } } ) // ==================== DATABASE MANAGEMENT ==================== server.registerTool( "create-database", { title: "Create Database", description: "Create a new database (PostgreSQL, MySQL, MongoDB, Redis, or MariaDB)", inputSchema: { projectId: z.string().describe("The project ID to create the database in"), name: z.string().describe("Database name"), type: z.enum(["postgres", "mysql", "mongodb", "redis", "mariadb"]).describe("Database type"), databaseName: z.string().optional().describe("Database name (for SQL databases)"), username: z.string().optional().describe("Database username"), password: z.string().optional().describe("Database password"), }, }, async ({ projectId, name, type, databaseName, username, password }) => { const result = await dokployRequest(config, "/database.create", "POST", { projectId, name, type, databaseName, username, password, }) return { content: [{ type: "text", text: `✅ Database created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "list-databases", { title: "List Databases", description: "List all databases in a project", inputSchema: { projectId: z.string().describe("The project ID to list databases from"), }, }, async ({ projectId }) => { const databases = await dokployRequest(config, `/database.all?projectId=${projectId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(databases, null, 2), }], } } ) // ==================== DOCKER COMPOSE MANAGEMENT ==================== server.registerTool( "list-composes", { title: "List Docker Compose Applications", description: "List all Docker Compose applications in a project", inputSchema: { projectId: z.string().describe("The project ID to list compose applications from"), }, }, async ({ projectId }) => { const composes = await dokployRequest(config, `/compose.all?projectId=${projectId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(composes, null, 2), }], } } ) server.registerTool( "create-compose", { title: "Create Docker Compose Application", description: "Create a new Docker Compose application", inputSchema: { projectId: z.string().describe("The project ID to create the compose application in"), name: z.string().describe("Compose application name"), appName: z.string().optional().describe("Application name override"), description: z.string().optional().describe("Compose application description"), dockerComposeFile: z.string().optional().describe("Docker Compose file content"), dockerComposeFilePath: z.string().optional().describe("Path to Docker Compose file in repository"), repository: z.string().optional().describe("Git repository URL"), branch: z.string().default("main").describe("Git branch to deploy"), buildPath: z.string().default("/").describe("Build path in repository"), env: z.record(z.string()).optional().describe("Environment variables as key-value pairs"), }, }, async ({ projectId, name, appName, description, dockerComposeFile, dockerComposeFilePath, repository, branch, buildPath, env }) => { const result = await dokployRequest(config, "/compose.create", "POST", { projectId, name, appName, description: description || "", dockerComposeFile, dockerComposeFilePath, repository, branch, buildPath, env: env || {}, }) return { content: [{ type: "text", text: `✅ Docker Compose application created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "deploy-compose", { title: "Deploy Docker Compose Application", description: "Deploy a Docker Compose application", inputSchema: { composeId: z.string().describe("The ID of the compose application to deploy"), }, }, async ({ composeId }) => { const result = await dokployRequest(config, "/compose.deploy", "POST", { composeId, }) return { content: [{ type: "text", text: `🚀 Docker Compose deployment started!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "stop-compose", { title: "Stop Docker Compose Application", description: "Stop a running Docker Compose application", inputSchema: { composeId: z.string().describe("The ID of the compose application to stop"), }, }, async ({ composeId }) => { const result = await dokployRequest(config, "/compose.stop", "POST", { composeId, }) return { content: [{ type: "text", text: `⏸️ Docker Compose application stopped successfully!`, }], } } ) server.registerTool( "start-compose", { title: "Start Docker Compose Application", description: "Start a stopped Docker Compose application", inputSchema: { composeId: z.string().describe("The ID of the compose application to start"), }, }, async ({ composeId }) => { const result = await dokployRequest(config, "/compose.start", "POST", { composeId, }) return { content: [{ type: "text", text: `▶️ Docker Compose application started successfully!`, }], } } ) server.registerTool( "restart-compose", { title: "Restart Docker Compose Application", description: "Restart a Docker Compose application", inputSchema: { composeId: z.string().describe("The ID of the compose application to restart"), }, }, async ({ composeId }) => { const result = await dokployRequest(config, "/compose.restart", "POST", { composeId, }) return { content: [{ type: "text", text: `🔄 Docker Compose application restarted successfully!`, }], } } ) server.registerTool( "delete-compose", { title: "Delete Docker Compose Application", description: "Delete a Docker Compose application", inputSchema: { composeId: z.string().describe("The ID of the compose application to delete"), }, }, async ({ composeId }) => { const result = await dokployRequest(config, "/compose.remove", "POST", { composeId, }) return { content: [{ type: "text", text: `✅ Docker Compose application deleted successfully!`, }], } } ) server.registerTool( "get-compose-logs", { title: "Get Docker Compose Application Logs", description: "Get recent logs for a Docker Compose application", inputSchema: { composeId: z.string().describe("The compose application ID"), lines: z.number().default(100).describe("Number of log lines to retrieve"), }, }, async ({ composeId, lines }) => { const logs = await dokployRequest(config, `/compose.logs?composeId=${composeId}&lines=${lines}`, "GET") return { content: [{ type: "text", text: typeof logs === 'string' ? logs : JSON.stringify(logs, null, 2), }], } } ) server.registerTool( "get-compose-status", { title: "Get Docker Compose Application Status", description: "Get the current status and health of a Docker Compose application", inputSchema: { composeId: z.string().describe("The compose application ID"), }, }, async ({ composeId }) => { const status = await dokployRequest(config, `/compose.status?composeId=${composeId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(status, null, 2), }], } } ) // ==================== GIT PROVIDER MANAGEMENT ==================== server.registerTool( "list-git-providers", { title: "List Git Providers", description: "List all configured Git providers", inputSchema: {}, }, async () => { const providers = await dokployRequest(config, "/git-provider.all", "GET") return { content: [{ type: "text", text: JSON.stringify(providers, null, 2), }], } } ) server.registerTool( "create-github-provider", { title: "Create GitHub Provider", description: "Create a new GitHub provider configuration", inputSchema: { name: z.string().describe("Provider name"), githubAppName: z.string().optional().describe("GitHub App name"), githubAppId: z.string().optional().describe("GitHub App ID"), githubClientId: z.string().optional().describe("GitHub OAuth App Client ID"), githubClientSecret: z.string().optional().describe("GitHub OAuth App Client Secret"), githubInstallationId: z.string().optional().describe("GitHub App Installation ID"), githubPrivateKey: z.string().optional().describe("GitHub App Private Key"), }, }, async ({ name, githubAppName, githubAppId, githubClientId, githubClientSecret, githubInstallationId, githubPrivateKey }) => { const result = await dokployRequest(config, "/github.create", "POST", { name, githubAppName, githubAppId, githubClientId, githubClientSecret, githubInstallationId, githubPrivateKey, }) return { content: [{ type: "text", text: `✅ GitHub provider created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "create-gitlab-provider", { title: "Create GitLab Provider", description: "Create a new GitLab provider configuration", inputSchema: { name: z.string().describe("Provider name"), gitlabUrl: z.string().optional().describe("GitLab instance URL"), applicationId: z.string().optional().describe("GitLab Application ID"), secret: z.string().optional().describe("GitLab Application Secret"), redirectUrl: z.string().optional().describe("OAuth redirect URL"), groupName: z.string().optional().describe("GitLab group name"), }, }, async ({ name, gitlabUrl, applicationId, secret, redirectUrl, groupName }) => { const result = await dokployRequest(config, "/gitlab.create", "POST", { name, gitlabUrl, applicationId, secret, redirectUrl, groupName, }) return { content: [{ type: "text", text: `✅ GitLab provider created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "create-gitea-provider", { title: "Create Gitea Provider", description: "Create a new Gitea provider configuration", inputSchema: { name: z.string().describe("Provider name"), giteaUrl: z.string().optional().describe("Gitea instance URL"), applicationId: z.string().optional().describe("Gitea Application ID"), secret: z.string().optional().describe("Gitea Application Secret"), redirectUrl: z.string().optional().describe("OAuth redirect URL"), }, }, async ({ name, giteaUrl, applicationId, secret, redirectUrl }) => { const result = await dokployRequest(config, "/gitea.create", "POST", { name, giteaUrl, applicationId, secret, redirectUrl, }) return { content: [{ type: "text", text: `✅ Gitea provider created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "create-bitbucket-provider", { title: "Create Bitbucket Provider", description: "Create a new Bitbucket provider configuration", inputSchema: { name: z.string().describe("Provider name"), bitbucketUsername: z.string().optional().describe("Bitbucket username"), bitbucketAppPassword: z.string().optional().describe("Bitbucket App Password"), bitbucketWorkspaceName: z.string().optional().describe("Bitbucket workspace name"), }, }, async ({ name, bitbucketUsername, bitbucketAppPassword, bitbucketWorkspaceName }) => { const result = await dokployRequest(config, "/bitbucket.create", "POST", { name, bitbucketUsername, bitbucketAppPassword, bitbucketWorkspaceName, }) return { content: [{ type: "text", text: `✅ Bitbucket provider created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== SERVER MANAGEMENT ==================== server.registerTool( "list-servers", { title: "List Servers", description: "List all configured servers", inputSchema: {}, }, async () => { const servers = await dokployRequest(config, "/server.all", "GET") return { content: [{ type: "text", text: JSON.stringify(servers, null, 2), }], } } ) server.registerTool( "create-server", { title: "Create Server", description: "Create a new server configuration", inputSchema: { name: z.string().describe("Server name"), ipAddress: z.string().describe("Server IP address"), port: z.number().default(22).describe("SSH port"), username: z.string().default("root").describe("SSH username"), description: z.string().optional().describe("Server description"), }, }, async ({ name, ipAddress, port, username, description }) => { const result = await dokployRequest(config, "/server.create", "POST", { name, ipAddress, port, username, description: description || "", }) return { content: [{ type: "text", text: `✅ Server created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "get-server-status", { title: "Get Server Status", description: "Get the current status and health of a server", inputSchema: { serverId: z.string().describe("The server ID"), }, }, async ({ serverId }) => { const status = await dokployRequest(config, `/server.status?serverId=${serverId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(status, null, 2), }], } } ) // ==================== USER MANAGEMENT ==================== server.registerTool( "list-users", { title: "List Users", description: "List all users in the Dokploy instance", inputSchema: {}, }, async () => { const users = await dokployRequest(config, "/user.all", "GET") return { content: [{ type: "text", text: JSON.stringify(users, null, 2), }], } } ) server.registerTool( "create-user", { title: "Create User", description: "Create a new user account", inputSchema: { email: z.string().email().describe("User email address"), password: z.string().describe("User password"), name: z.string().optional().describe("User display name"), isAdmin: z.boolean().default(false).describe("Whether the user should have admin privileges"), }, }, async ({ email, password, name, isAdmin }) => { const result = await dokployRequest(config, "/user.create", "POST", { email, password, name, isAdmin, }) return { content: [{ type: "text", text: `✅ User created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== CERTIFICATE MANAGEMENT ==================== server.registerTool( "list-certificates", { title: "List SSL Certificates", description: "List all SSL certificates", inputSchema: {}, }, async () => { const certificates = await dokployRequest(config, "/certificate.all", "GET") return { content: [{ type: "text", text: JSON.stringify(certificates, null, 2), }], } } ) server.registerTool( "create-certificate", { title: "Create SSL Certificate", description: "Create a new SSL certificate", inputSchema: { name: z.string().describe("Certificate name"), certificate: z.string().describe("SSL certificate content"), privateKey: z.string().describe("Private key content"), }, }, async ({ name, certificate, privateKey }) => { const result = await dokployRequest(config, "/certificate.create", "POST", { name, certificate, privateKey, }) return { content: [{ type: "text", text: `✅ SSL certificate created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== NOTIFICATION MANAGEMENT ==================== server.registerTool( "list-notifications", { title: "List Notifications", description: "List all notification configurations", inputSchema: {}, }, async () => { const notifications = await dokployRequest(config, "/notification.all", "GET") return { content: [{ type: "text", text: JSON.stringify(notifications, null, 2), }], } } ) server.registerTool( "create-notification", { title: "Create Notification", description: "Create a new notification configuration", inputSchema: { name: z.string().describe("Notification name"), type: z.enum(["discord", "slack", "telegram", "email"]).describe("Notification type"), webhookUrl: z.string().optional().describe("Webhook URL for Discord/Slack"), botToken: z.string().optional().describe("Bot token for Telegram"), chatId: z.string().optional().describe("Chat ID for Telegram"), smtpUrl: z.string().optional().describe("SMTP URL for email notifications"), to: z.string().optional().describe("Email recipient"), }, }, async ({ name, type, webhookUrl, botToken, chatId, smtpUrl, to }) => { const result = await dokployRequest(config, "/notification.create", "POST", { name, type, webhookUrl, botToken, chatId, smtpUrl, to, }) return { content: [{ type: "text", text: `✅ Notification created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== SSH KEY MANAGEMENT ==================== server.registerTool( "list-ssh-keys", { title: "List SSH Keys", description: "List all SSH keys", inputSchema: {}, }, async () => { const sshKeys = await dokployRequest(config, "/ssh-key.all", "GET") return { content: [{ type: "text", text: JSON.stringify(sshKeys, null, 2), }], } } ) server.registerTool( "create-ssh-key", { title: "Create SSH Key", description: "Create a new SSH key", inputSchema: { name: z.string().describe("SSH key name"), description: z.string().optional().describe("SSH key description"), privateKey: z.string().describe("Private key content"), publicKey: z.string().optional().describe("Public key content"), }, }, async ({ name, description, privateKey, publicKey }) => { const result = await dokployRequest(config, "/ssh-key.create", "POST", { name, description: description || "", privateKey, publicKey, }) return { content: [{ type: "text", text: `✅ SSH key created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== SETTINGS MANAGEMENT ==================== server.registerTool( "get-settings", { title: "Get System Settings", description: "Get current system settings", inputSchema: {}, }, async () => { const settings = await dokployRequest(config, "/settings.all", "GET") return { content: [{ type: "text", text: JSON.stringify(settings, null, 2), }], } } ) server.registerTool( "update-settings", { title: "Update System Settings", description: "Update system settings", inputSchema: { enableDockerCleanup: z.boolean().optional().describe("Enable automatic Docker cleanup"), enableDockerPrune: z.boolean().optional().describe("Enable Docker prune on cleanup"), dockerCleanupInterval: z.string().optional().describe("Docker cleanup interval (cron format)"), enableStats: z.boolean().optional().describe("Enable system statistics collection"), serverTimezone: z.string().optional().describe("Server timezone"), }, }, async ({ enableDockerCleanup, enableDockerPrune, dockerCleanupInterval, enableStats, serverTimezone }) => { const result = await dokployRequest(config, "/settings.update", "POST", { enableDockerCleanup, enableDockerPrune, dockerCleanupInterval, enableStats, serverTimezone, }) return { content: [{ type: "text", text: `✅ System settings updated successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== DOMAIN & SSL MANAGEMENT ==================== server.registerTool( "add-domain", { title: "Add Domain", description: "Add a custom domain to an application", inputSchema: { applicationId: z.string().describe("The application ID"), domain: z.string().describe("Domain name (e.g., example.com)"), enableSSL: z.boolean().default(true).describe("Enable automatic SSL with Let's Encrypt"), }, }, async ({ applicationId, domain, enableSSL }) => { const result = await dokployRequest(config, "/domain.create", "POST", { applicationId, domain, enableSSL, }) return { content: [{ type: "text", text: `✅ Domain added successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "list-domains", { title: "List Domains", description: "List all domains for an application", inputSchema: { applicationId: z.string().describe("The application ID"), }, }, async ({ applicationId }) => { const domains = await dokployRequest(config, `/domain.all?applicationId=${applicationId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(domains, null, 2), }], } } ) // ==================== BACKUP & RESTORE ==================== server.registerTool( "create-backup", { title: "Create Backup", description: "Create a backup of a database", inputSchema: { databaseId: z.string().describe("The database ID to backup"), }, }, async ({ databaseId }) => { const result = await dokployRequest(config, "/backup.create", "POST", { databaseId, }) return { content: [{ type: "text", text: `✅ Backup created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) server.registerTool( "list-backups", { title: "List Backups", description: "List all backups for a database", inputSchema: { databaseId: z.string().describe("The database ID"), }, }, async ({ databaseId }) => { const backups = await dokployRequest(config, `/backup.all?databaseId=${databaseId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(backups, null, 2), }], } } ) server.registerTool( "restore-backup", { title: "Restore Backup", description: "Restore a database from a backup", inputSchema: { backupId: z.string().describe("The backup ID to restore"), }, }, async ({ backupId }) => { const result = await dokployRequest(config, "/backup.restore", "POST", { backupId, }) return { content: [{ type: "text", text: `✅ Backup restored successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== MONITORING & LOGS ==================== server.registerTool( "get-logs", { title: "Get Application Logs", description: "Get recent logs for an application", inputSchema: { applicationId: z.string().describe("The application ID"), lines: z.number().default(100).describe("Number of log lines to retrieve"), }, }, async ({ applicationId, lines }) => { const logs = await dokployRequest(config, `/application.logs?applicationId=${applicationId}&lines=${lines}`, "GET") return { content: [{ type: "text", text: typeof logs === 'string' ? logs : JSON.stringify(logs, null, 2), }], } } ) server.registerTool( "get-application-status", { title: "Get Application Status", description: "Get the current status and health of an application", inputSchema: { applicationId: z.string().describe("The application ID"), }, }, async ({ applicationId }) => { const status = await dokployRequest(config, `/application.status?applicationId=${applicationId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(status, null, 2), }], } } ) // ==================== ENVIRONMENT VARIABLES ==================== server.registerTool( "update-env-vars", { title: "Update Environment Variables", description: "Update environment variables for an application", inputSchema: { applicationId: z.string().describe("The application ID"), env: z.record(z.string()).describe("Environment variables as key-value pairs"), }, }, async ({ applicationId, env }) => { const result = await dokployRequest(config, "/application.updateEnv", "POST", { applicationId, env, }) return { content: [{ type: "text", text: `✅ Environment variables updated successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== DEPLOYMENT MANAGEMENT ==================== server.registerTool( "list-deployments", { title: "List Deployments", description: "List all deployments for an application", inputSchema: { applicationId: z.string().optional().describe("Application ID to filter deployments"), composeId: z.string().optional().describe("Compose ID to filter deployments"), }, }, async ({ applicationId, composeId }) => { let endpoint = "/deployment.all" const params = new URLSearchParams() if (applicationId) params.append("applicationId", applicationId) if (composeId) params.append("composeId", composeId) if (params.toString()) endpoint += `?${params.toString()}` const deployments = await dokployRequest(config, endpoint, "GET") return { content: [{ type: "text", text: JSON.stringify(deployments, null, 2), }], } } ) server.registerTool( "cancel-deployment", { title: "Cancel Deployment", description: "Cancel a running deployment", inputSchema: { applicationId: z.string().optional().describe("Application ID"), composeId: z.string().optional().describe("Compose ID"), }, }, async ({ applicationId, composeId }) => { const result = await dokployRequest(config, "/deployment.cancel", "POST", { applicationId, composeId, }) return { content: [{ type: "text", text: `✅ Deployment cancelled successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== REGISTRY MANAGEMENT ==================== server.registerTool( "list-registries", { title: "List Docker Registries", description: "List all configured Docker registries", inputSchema: {}, }, async () => { const registries = await dokployRequest(config, "/registry.all", "GET") return { content: [{ type: "text", text: JSON.stringify(registries, null, 2), }], } } ) server.registerTool( "create-registry", { title: "Create Docker Registry", description: "Create a new Docker registry configuration", inputSchema: { name: z.string().describe("Registry name"), registryUrl: z.string().describe("Registry URL"), username: z.string().optional().describe("Registry username"), password: z.string().optional().describe("Registry password"), }, }, async ({ name, registryUrl, username, password }) => { const result = await dokployRequest(config, "/registry.create", "POST", { name, registryUrl, username, password, }) return { content: [{ type: "text", text: `✅ Docker registry created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== REDIRECT MANAGEMENT ==================== server.registerTool( "list-redirects", { title: "List Redirects", description: "List all redirect rules", inputSchema: {}, }, async () => { const redirects = await dokployRequest(config, "/redirect.all", "GET") return { content: [{ type: "text", text: JSON.stringify(redirects, null, 2), }], } } ) server.registerTool( "create-redirect", { title: "Create Redirect", description: "Create a new redirect rule", inputSchema: { domain: z.string().describe("Source domain"), redirect: z.string().describe("Target URL"), redirectType: z.enum(["temporary", "permanent"]).default("permanent").describe("Redirect type"), }, }, async ({ domain, redirect, redirectType }) => { const result = await dokployRequest(config, "/redirect.create", "POST", { domain, redirect, redirectType, }) return { content: [{ type: "text", text: `✅ Redirect rule created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== SCHEDULE MANAGEMENT ==================== server.registerTool( "list-schedules", { title: "List Schedules", description: "List all scheduled tasks", inputSchema: {}, }, async () => { const schedules = await dokployRequest(config, "/schedule.all", "GET") return { content: [{ type: "text", text: JSON.stringify(schedules, null, 2), }], } } ) server.registerTool( "create-schedule", { title: "Create Schedule", description: "Create a new scheduled task", inputSchema: { name: z.string().describe("Schedule name"), cronExpression: z.string().describe("Cron expression (e.g., '0 0 * * *' for daily)"), applicationId: z.string().optional().describe("Application ID to redeploy"), composeId: z.string().optional().describe("Compose ID to redeploy"), databaseId: z.string().optional().describe("Database ID to backup"), enabled: z.boolean().default(true).describe("Whether the schedule is enabled"), }, }, async ({ name, cronExpression, applicationId, composeId, databaseId, enabled }) => { const result = await dokployRequest(config, "/schedule.create", "POST", { name, cronExpression, applicationId, composeId, databaseId, enabled, }) return { content: [{ type: "text", text: `✅ Schedule created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== ROLLBACK MANAGEMENT ==================== server.registerTool( "list-rollbacks", { title: "List Rollbacks", description: "List available rollback points for an application", inputSchema: { applicationId: z.string().describe("Application ID"), }, }, async ({ applicationId }) => { const rollbacks = await dokployRequest(config, `/rollbacks.all?applicationId=${applicationId}`, "GET") return { content: [{ type: "text", text: JSON.stringify(rollbacks, null, 2), }], } } ) server.registerTool( "rollback-application", { title: "Rollback Application", description: "Rollback an application to a previous deployment", inputSchema: { applicationId: z.string().describe("Application ID"), rollbackId: z.string().describe("Rollback point ID"), }, }, async ({ applicationId, rollbackId }) => { const result = await dokployRequest(config, "/rollbacks.rollback", "POST", { applicationId, rollbackId, }) return { content: [{ type: "text", text: `⏪ Application rolled back successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== VOLUME BACKUPS MANAGEMENT ==================== server.registerTool( "list-volume-backups", { title: "List Volume Backups", description: "List all volume backups", inputSchema: {}, }, async () => { const backups = await dokployRequest(config, "/volume-backups.all", "GET") return { content: [{ type: "text", text: JSON.stringify(backups, null, 2), }], } } ) server.registerTool( "create-volume-backup", { title: "Create Volume Backup", description: "Create a backup of a Docker volume", inputSchema: { name: z.string().describe("Backup name"), volumeName: z.string().describe("Docker volume name"), destinationPath: z.string().optional().describe("Destination path for the backup"), }, }, async ({ name, volumeName, destinationPath }) => { const result = await dokployRequest(config, "/volume-backups.create", "POST", { name, volumeName, destinationPath, }) return { content: [{ type: "text", text: `💾 Volume backup created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== MOUNT MANAGEMENT ==================== server.registerTool( "list-mounts", { title: "List Mounts", description: "List all volume mounts", inputSchema: {}, }, async () => { const mounts = await dokployRequest(config, "/mount.all", "GET") return { content: [{ type: "text", text: JSON.stringify(mounts, null, 2), }], } } ) server.registerTool( "create-mount", { title: "Create Mount", description: "Create a new volume mount", inputSchema: { name: z.string().describe("Mount name"), volumeName: z.string().describe("Docker volume name"), containerPath: z.string().describe("Path inside the container"), applicationId: z.string().optional().describe("Application ID to attach mount to"), composeId: z.string().optional().describe("Compose ID to attach mount to"), }, }, async ({ name, volumeName, containerPath, applicationId, composeId }) => { const result = await dokployRequest(config, "/mount.create", "POST", { name, volumeName, containerPath, applicationId, composeId, }) return { content: [{ type: "text", text: `📁 Mount created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== PORT MANAGEMENT ==================== server.registerTool( "list-ports", { title: "List Ports", description: "List all configured ports", inputSchema: {}, }, async () => { const ports = await dokployRequest(config, "/port.all", "GET") return { content: [{ type: "text", text: JSON.stringify(ports, null, 2), }], } } ) server.registerTool( "create-port", { title: "Create Port", description: "Create a new port configuration", inputSchema: { publishedPort: z.number().describe("Published port on host"), targetPort: z.number().describe("Target port in container"), protocol: z.enum(["tcp", "udp"]).default("tcp").describe("Port protocol"), applicationId: z.string().optional().describe("Application ID"), composeId: z.string().optional().describe("Compose ID"), }, }, async ({ publishedPort, targetPort, protocol, applicationId, composeId }) => { const result = await dokployRequest(config, "/port.create", "POST", { publishedPort, targetPort, protocol, applicationId, composeId, }) return { content: [{ type: "text", text: `🔌 Port configuration created successfully!\n\n${JSON.stringify(result, null, 2)}`, }], } } ) // ==================== RESOURCES (Documentation) ==================== server.registerResource( "dokploy-docs", "dokploy://docs", { title: "Dokploy Documentation", description: "Official Dokploy documentation and guides", }, async (uri) => ({ contents: [{ uri: uri.href, text: `# Dokploy Documentation Dokploy is an open-source alternative to Netlify, Vercel, and Heroku. It allows you to deploy your applications easily using Docker and provides a simple API for management. ## Key Features - **Easy Deployment**: Deploy applications from Git repositories with automatic builds - **Multiple Languages**: Support for Node.js, Python, Go, PHP, and more - **Database Support**: Built-in support for PostgreSQL, MySQL, MongoDB, Redis, and MariaDB - **Custom Domains**: Add custom domains with automatic SSL via Let's Encrypt - **Backups**: Automatic and manual database backups - **Monitoring**: Real-time logs and application status monitoring - **Environment Variables**: Secure environment variable management - **Docker Support**: Native Docker and Docker Compose support ## Getting Started 1. Create a new project using the \`create-project\` tool 2. Create an application within the project using \`create-application\` 3. Deploy your application using \`deploy-application\` 4. (Optional) Add a custom domain using \`add-domain\` ## API Reference Visit your Dokploy instance's Swagger documentation at: ${config.dokployUrl}/swagger ## Support - Documentation: https://docs.dokploy.com - GitHub: https://github.com/dokploy/dokploy - Discord: Join the Dokploy community ## Best Practices - Always use environment variables for sensitive data - Enable SSL for production domains - Set up regular database backups - Monitor application logs regularly - Use health checks for critical applications `, mimeType: "text/markdown", }], }) ) server.registerResource( "dokploy-quickstart", "dokploy://quickstart", { title: "Dokploy Quick Start Guide", description: "Quick start guide for deploying your first application", }, async (uri) => ({ contents: [{ uri: uri.href, text: `# Dokploy Quick Start ## Deploy Your First Application Follow these steps to deploy your first application on Dokploy: ### Step 1: Create a Project \`\`\` Use the 'create-project' tool: - Name: my-first-project - Description: My first Dokploy project \`\`\` ### Step 2: Create an Application \`\`\` Use the 'create-application' tool: - Project ID: (from step 1) - Name: my-app - App Type: github - Repository: https://github.com/yourusername/your-repo - Branch: main \`\`\` ### Step 3: Deploy \`\`\` Use the 'deploy-application' tool with the application ID from step 2 \`\`\` ### Step 4: Monitor \`\`\` Check deployment status with 'get-application-status' View logs with 'get-logs' \`\`\` ### Step 5: Add a Domain (Optional) \`\`\` Use the 'add-domain' tool to add your custom domain \`\`\` ## Example: Deploy a Node.js App 1. Create project: "my-node-app" 2. Create application from your GitHub repository 3. Set environment variables (if needed) 4. Deploy! That's it! Your application will be live in minutes. `, mimeType: "text/markdown", }], }) ) server.registerResource( "dokploy-api-reference", "dokploy://api-reference", { title: "Dokploy API Reference", description: "Complete API reference for Dokploy REST API", }, async (uri) => ({ contents: [{ uri: uri.href, text: `# Dokploy API Reference Base URL: ${config.dokployUrl}/api ## Authentication All API requests require authentication using a Bearer token: \`\`\` Authorization: Bearer YOUR_API_TOKEN \`\`\` ## Endpoints ### Projects - \`GET /api/project.all\` - List all projects - \`POST /api/project.create\` - Create a new project - \`POST /api/project.remove\` - Delete a project ### Applications - \`GET /api/application.all\` - List all applications - \`POST /api/application.create\` - Create a new application - \`POST /api/application.deploy\` - Deploy an application - \`POST /api/application.start\` - Start an application - \`POST /api/application.stop\` - Stop an application - \`POST /api/application.restart\` - Restart an application - \`POST /api/application.remove\` - Delete an application - \`GET /api/application.logs\` - Get application logs - \`GET /api/application.status\` - Get application status - \`POST /api/application.updateEnv\` - Update environment variables ### Databases - \`GET /api/database.all\` - List all databases - \`POST /api/database.create\` - Create a new database ### Domains - \`GET /api/domain.all\` - List all domains - \`POST /api/domain.create\` - Add a new domain ### Backups - \`GET /api/backup.all\` - List all backups - \`POST /api/backup.create\` - Create a backup - \`POST /api/backup.restore\` - Restore from backup For full API documentation, visit: ${config.dokployUrl}/swagger `, mimeType: "text/markdown", }], }) ) // ==================== PROMPTS ==================== server.registerPrompt( "deploy-app", { title: "Deploy Application Workflow", description: "Interactive prompt to guide through application deployment", argsSchema: { projectName: z.string().describe("Name for the new project"), appName: z.string().describe("Name for the application"), repository: z.string().describe("Git repository URL"), }, }, async ({ projectName, appName, repository }) => ({ messages: [{ role: "user", content: { type: "text", text: `I want to deploy a new application on Dokploy. Here are the details: - Project Name: ${projectName} - Application Name: ${appName} - Repository: ${repository} Please help me: 1. Create a new project 2. Create an application in that project 3. Deploy the application 4. Check the deployment status Guide me through each step.`, }, }], }) ) server.registerPrompt( "setup-database", { title: "Database Setup Workflow", description: "Interactive prompt to guide through database creation and configuration", argsSchema: { projectId: z.string().describe("Project ID to create the database in"), dbType: z.enum(["postgres", "mysql", "mongodb", "redis", "mariadb"]).describe("Database type"), dbName: z.string().describe("Database name"), }, }, async ({ projectId, dbType, dbName }) => ({ messages: [{ role: "user", content: { type: "text", text: `I want to set up a ${dbType} database named "${dbName}" in project ${projectId}. Please help me: 1. Create the database 2. Show me the connection details 3. Set up automatic backups Guide me through the process.`, }, }], }) ) server.registerPrompt( "troubleshoot", { title: "Troubleshoot Application", description: "Interactive prompt to help troubleshoot application issues", argsSchema: { applicationId: z.string().describe("Application ID to troubleshoot"), }, }, async ({ applicationId }) => ({ messages: [{ role: "user", content: { type: "text", text: `My application (ID: ${applicationId}) is having issues. Please help me troubleshoot by: 1. Checking the application status 2. Reviewing recent logs 3. Suggesting potential fixes Start the diagnostic process.`, }, }], }) ) return server.server }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/huuthangntk/dokploy-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server