Skip to main content
Glama
portainer-client.ts8.44 kB
import axios, { AxiosInstance, AxiosError } from 'axios'; import { config, Config } from './config.js'; export interface PortainerContainer { Id: string; Names: string[]; Image: string; State: string; Status: string; Ports?: any[]; } export interface PortainerImage { Id: string; RepoTags?: string[]; Size: number; Created: number; } export interface PortainerNetwork { Id: string; Name: string; Driver: string; Scope: string; } export interface PortainerEndpoint { Id: number; Name: string; URL: string; Type: number; } export interface PortainerVolume { Name: string; Driver: string; Mountpoint: string; } export class PortainerClient { private client: AxiosInstance; private endpointId: number; constructor(customConfig?: Partial<Config>) { const cfg = customConfig ? { ...config, ...customConfig } : config; if (!cfg.portainerUrl || !cfg.portainerApiKey) { throw new Error( 'Portainer not configured. Use the "set_portainer_config" tool to set the URL and API key:\n\n' + 'Example: set_portainer_config(url="https://portainer.onlitec.com.br", api_key="ptr_your_key")' ); } this.endpointId = cfg.portainerEndpointId; this.client = axios.create({ baseURL: cfg.portainerUrl, headers: { 'X-API-Key': cfg.portainerApiKey, }, }); } private handleError(error: unknown): never { if (axios.isAxiosError(error)) { const axiosError = error as AxiosError; if (axiosError.response) { // If it's a 404 for a specific endpoint, it might still return valuable info for other calls, // but for listEndpoints it shouldn't happen unless the base URL is wrong. throw new Error( `Portainer API error: ${axiosError.response.status} - ${JSON.stringify(axiosError.response.data)}` ); } else if (axiosError.request) { throw new Error('No response from Portainer API. Check if Portainer is running.'); } } throw new Error(`Unexpected error: ${error}`); } // System operations async listEndpoints(): Promise<PortainerEndpoint[]> { try { const response = await this.client.get('/api/endpoints'); return response.data; } catch (error) { this.handleError(error); } } // Container operations async listContainers(all = false): Promise<PortainerContainer[]> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/containers/json`, { params: { all } } ); return response.data; } catch (error) { this.handleError(error); } } async getContainer(id: string): Promise<any> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/containers/${id}/json` ); return response.data; } catch (error) { this.handleError(error); } } async startContainer(id: string): Promise<void> { try { await this.client.post( `/api/endpoints/${this.endpointId}/docker/containers/${id}/start` ); } catch (error) { this.handleError(error); } } async stopContainer(id: string, timeout = 10): Promise<void> { try { await this.client.post( `/api/endpoints/${this.endpointId}/docker/containers/${id}/stop`, null, { params: { t: timeout } } ); } catch (error) { this.handleError(error); } } async restartContainer(id: string, timeout = 10): Promise<void> { try { await this.client.post( `/api/endpoints/${this.endpointId}/docker/containers/${id}/restart`, null, { params: { t: timeout } } ); } catch (error) { this.handleError(error); } } async removeContainer(id: string, force = false, volumes = false): Promise<void> { try { await this.client.delete( `/api/endpoints/${this.endpointId}/docker/containers/${id}`, { params: { force, v: volumes } } ); } catch (error) { this.handleError(error); } } async createContainer(config: any): Promise<any> { try { const response = await this.client.post( `/api/endpoints/${this.endpointId}/docker/containers/create`, config ); return response.data; } catch (error) { this.handleError(error); } } // Image operations async listImages(all = false): Promise<PortainerImage[]> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/images/json`, { params: { all } } ); return response.data; } catch (error) { this.handleError(error); } } async getImage(id: string): Promise<any> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/images/${id}/json` ); return response.data; } catch (error) { this.handleError(error); } } async pullImage(image: string): Promise<any> { try { const response = await this.client.post( `/api/endpoints/${this.endpointId}/docker/images/create`, null, { params: { fromImage: image } } ); return response.data; } catch (error) { this.handleError(error); } } async removeImage(id: string, force = false): Promise<void> { try { await this.client.delete( `/api/endpoints/${this.endpointId}/docker/images/${id}`, { params: { force } } ); } catch (error) { this.handleError(error); } } // Network operations async listNetworks(): Promise<PortainerNetwork[]> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/networks` ); return response.data; } catch (error) { this.handleError(error); } } async createNetwork(networkConfig: any): Promise<any> { try { const response = await this.client.post( `/api/endpoints/${this.endpointId}/docker/networks/create`, networkConfig ); return response.data; } catch (error) { this.handleError(error); } } async removeNetwork(id: string): Promise<void> { try { await this.client.delete( `/api/endpoints/${this.endpointId}/docker/networks/${id}` ); } catch (error) { this.handleError(error); } } // Volume operations async listVolumes(): Promise<any> { try { const response = await this.client.get( `/api/endpoints/${this.endpointId}/docker/volumes` ); return response.data; } catch (error) { this.handleError(error); } } async createVolume(volumeConfig: any): Promise<any> { try { const response = await this.client.post( `/api/endpoints/${this.endpointId}/docker/volumes/create`, volumeConfig ); return response.data; } catch (error) { this.handleError(error); } } async removeVolume(name: string, force = false): Promise<void> { try { await this.client.delete( `/api/endpoints/${this.endpointId}/docker/volumes/${name}`, { params: { force } } ); } catch (error) { this.handleError(error); } } }

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