Skip to main content
Glama
index.ts6.44 kB
import { z } from "zod"; import { ResponseFormat } from "../types.js"; import { DEFAULT_LIMIT, MAX_LIMIT, DEFAULT_LOG_LINES, MAX_LOG_LINES } from "../constants.js"; // Common pagination schema const paginationSchema = { limit: z.number() .int() .min(1) .max(MAX_LIMIT) .default(DEFAULT_LIMIT) .describe(`Maximum results to return (1-${MAX_LIMIT})`), offset: z.number() .int() .min(0) .default(0) .describe("Number of results to skip for pagination") }; // Common response format schema const responseFormatSchema = { response_format: z.nativeEnum(ResponseFormat) .default(ResponseFormat.MARKDOWN) .describe("Output format: 'markdown' for human-readable or 'json' for structured data") }; // Host filter schema const hostFilterSchema = { host: z.string() .optional() .describe("Filter by specific host name (e.g., 'unraid', 'proxmox-vm1'). Omit for all hosts.") }; // List containers schema export const ListContainersSchema = z.object({ ...hostFilterSchema, state: z.enum(["all", "running", "stopped", "paused"]) .default("all") .describe("Filter by container state"), name_filter: z.string() .optional() .describe("Filter containers by name (partial match)"), image_filter: z.string() .optional() .describe("Filter by image name (partial match)"), label_filter: z.string() .optional() .describe("Filter by label (format: 'key=value' or just 'key')"), ...paginationSchema, ...responseFormatSchema }).strict(); export type ListContainersInput = z.infer<typeof ListContainersSchema>; // Container action schema export const ContainerActionSchema = z.object({ container_id: z.string() .min(1) .describe("Container ID or name"), host: z.string() .optional() .describe("Host where container is running (auto-detected if omitted)"), action: z.enum(["start", "stop", "restart", "pause", "unpause"]) .describe("Action to perform on the container") }).strict(); export type ContainerActionInput = z.infer<typeof ContainerActionSchema>; // Get logs schema export const GetLogsSchema = z.object({ container_id: z.string() .min(1) .describe("Container ID or name"), host: z.string() .optional() .describe("Host where container is running (auto-detected if omitted)"), lines: z.number() .int() .min(1) .max(MAX_LOG_LINES) .default(DEFAULT_LOG_LINES) .describe(`Number of log lines to retrieve (1-${MAX_LOG_LINES})`), since: z.string() .optional() .describe("Show logs since timestamp (e.g., '2024-01-01T00:00:00Z' or '1h' for relative)"), until: z.string() .optional() .describe("Show logs until timestamp"), grep: z.string() .optional() .describe("Filter logs containing this string (case-insensitive)"), stream: z.enum(["all", "stdout", "stderr"]) .default("all") .describe("Which output stream to retrieve"), ...responseFormatSchema }).strict(); export type GetLogsInput = z.infer<typeof GetLogsSchema>; // Container stats schema export const ContainerStatsSchema = z.object({ container_id: z.string() .optional() .describe("Container ID or name (omit for all running containers)"), host: z.string() .optional() .describe("Host to get stats from"), ...responseFormatSchema }).strict(); export type ContainerStatsInput = z.infer<typeof ContainerStatsSchema>; // Inspect container schema export const InspectContainerSchema = z.object({ container_id: z.string() .min(1) .describe("Container ID or name"), host: z.string() .optional() .describe("Host where container is running (auto-detected if omitted)"), ...responseFormatSchema }).strict(); export type InspectContainerInput = z.infer<typeof InspectContainerSchema>; // Host status schema export const HostStatusSchema = z.object({ host: z.string() .optional() .describe("Specific host to check (omit for all hosts)"), ...responseFormatSchema }).strict(); export type HostStatusInput = z.infer<typeof HostStatusSchema>; // Search containers schema export const SearchContainersSchema = z.object({ query: z.string() .min(1) .describe("Search query to match against container names, images, and labels"), ...hostFilterSchema, ...paginationSchema, ...responseFormatSchema }).strict(); export type SearchContainersInput = z.infer<typeof SearchContainersSchema>; // Compose project schema export const ComposeProjectSchema = z.object({ project: z.string() .min(1) .describe("Docker Compose project name"), host: z.string() .optional() .describe("Host where project is running"), action: z.enum(["status", "up", "down", "restart", "logs"]) .describe("Action to perform on the compose project") }).strict(); export type ComposeProjectInput = z.infer<typeof ComposeProjectSchema>; // List images schema export const ListImagesSchema = z.object({ ...hostFilterSchema, dangling_only: z.boolean() .default(false) .describe("Only show dangling (untagged) images"), ...paginationSchema, ...responseFormatSchema }).strict(); export type ListImagesInput = z.infer<typeof ListImagesSchema>; // Prune schema export const PruneSchema = z.object({ host: z.string() .optional() .describe("Host to prune (omit for all hosts)"), target: z.enum(["containers", "images", "volumes", "networks", "buildcache", "all"]) .describe("What to prune"), force: z.boolean() .default(false) .describe("Confirm destructive operation (required)") }).strict(); export type PruneInput = z.infer<typeof PruneSchema>; // Docker info schema export const DockerInfoSchema = z.object({ host: z.string() .optional() .describe("Host to get Docker info from (omit for all hosts)"), ...responseFormatSchema }).strict(); export type DockerInfoInput = z.infer<typeof DockerInfoSchema>; // Docker disk usage schema export const DockerDiskUsageSchema = z.object({ host: z.string() .optional() .describe("Host to get disk usage from (omit for all hosts)"), ...responseFormatSchema }).strict(); export type DockerDiskUsageInput = z.infer<typeof DockerDiskUsageSchema>; // Host resources schema (SSH-based) export const HostResourcesSchema = z.object({ host: z.string() .optional() .describe("Host to get resources from (omit for all hosts)"), ...responseFormatSchema }).strict(); export type HostResourcesInput = z.infer<typeof HostResourcesSchema>;

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/jmagar/homelab-mcp'

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