Skip to main content
Glama
index.ts4.03 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { PortainerClient } from './portainer-client.js'; import { config } from './config.js'; import { createContainerTools } from './tools/container-tools.js'; import { createImageTools } from './tools/image-tools.js'; import { createNetworkTools } from './tools/network-tools.js'; import { createVolumeTools } from './tools/volume-tools.js'; import { createConfigTools } from './tools/config-tools.js'; import { createEndpointTools } from './tools/endpoint-tools.js'; // Config tools are always available (to allow setting up credentials) const configTools = createConfigTools(); // Function to get all tools dynamically (recreates client if config changed) function getAllTools() { const tools: Record<string, any> = { ...configTools }; // Only add Portainer tools if configured if (config.isConfigured) { try { const client = new PortainerClient(); Object.assign(tools, createEndpointTools(client)); Object.assign(tools, createContainerTools(client)); Object.assign(tools, createImageTools(client)); Object.assign(tools, createNetworkTools(client)); Object.assign(tools, createVolumeTools(client)); } catch (error) { console.error('Warning: Could not create Portainer client:', error); } } return tools; } // Create MCP server const server = new Server( { name: 'portainer-mcp-server', version: '1.0.0', }, { capabilities: { tools: {}, }, } ); // Handle list tools request server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = getAllTools(); return { tools: Object.entries(tools).map(([name, tool]) => ({ name, description: tool.description, inputSchema: tool.inputSchema, })), }; }); // Handle tool call request server.setRequestHandler(CallToolRequestSchema, async (request) => { const toolName = request.params.name; const tools = getAllTools(); const tool = tools[toolName]; if (!tool) { // Check if it's a Portainer tool that requires configuration if (['list_containers', 'get_container', 'start_container', 'stop_container', 'restart_container', 'remove_container', 'create_container', 'list_images', 'get_image', 'pull_image', 'remove_image', 'list_networks', 'create_network', 'remove_network', 'list_volumes', 'create_volume', 'remove_volume'].includes(toolName)) { return { content: [ { type: 'text', text: `⚠️ Portainer not configured!\n\nUse the "set_portainer_config" tool first to configure your Portainer connection:\n\nExample:\n- URL: https://portainer.onlitec.com.br\n- API Key: ptr_your_key_here\n- Endpoint ID: 1`, }, ], isError: true, }; } throw new Error(`Unknown tool: ${toolName}`); } try { const result = await tool.handler(request.params.arguments ?? {}); return result; } catch (error) { return { content: [ { type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }); // Start server async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error('Portainer MCP Server running on stdio'); } main().catch((error) => { console.error('Fatal error:', error); process.exit(1); });

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/onlitec/VPS-MCP-SERVER'

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