synology_docker_logs
Retrieve logs from a specific Docker container on Synology NAS. Provide container name or ID and optionally set the number of recent lines to display.
Instructions
Get logs for a specific docker container
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| container_name | Yes | Name or ID of the container | |
| tail | No | Number of lines to show from the end of the logs |
Implementation Reference
- src/index.ts:122-132 (schema)Tool registration and schema definition for synology_docker_logs in the ListToolsRequestSchema handler. Defines the tool name, description, and input schema requiring container_name (string) and optional tail (number, default 100).
{ name: "synology_docker_logs", description: "Get logs for a specific docker container", inputSchema: { type: "object", properties: { container_name: { type: "string", description: "Name or ID of the container" }, tail: { type: "number", description: "Number of lines to show from the end of the logs", default: 100 }, }, required: ["container_name"], }, - src/index.ts:202-209 (handler)Handler for synology_docker_logs in the CallToolRequestSchema handler. Extracts container_name and optional tail, validates with validateContainerName, clamps tail between 1-10000 (default 100), and runs 'docker logs --tail N <container>' via SSH, returning stdout or stderr as text.
else if (name === "synology_docker_logs") { const { container_name } = args as { container_name: string; tail?: number }; validateContainerName(container_name); const tailRaw = (args as any)?.tail; const tail = Number.isInteger(tailRaw) && tailRaw > 0 ? Math.min(tailRaw, 10000) : 100; const res = await execSshCommand(`docker logs --tail ${tail} ${shQuote(container_name)} 2>&1`); return { content: [{ type: "text", text: res.stdout || res.stderr }] }; } - src/index.ts:33-37 (helper)Validation helper that ensures container names contain only alphanumeric characters, underscores, dots, and hyphens, throwing an error if invalid.
function validateContainerName(name: string): void { if (!/^[a-zA-Z0-9][a-zA-Z0-9_.\-]*$/.test(name)) { throw new Error(`Invalid container name: ${name}`); } } - src/index.ts:28-30 (helper)Shell quoting helper that wraps a string in single quotes and escapes any internal single quotes, used to safely pass container names to SSH commands.
function shQuote(s: string): string { return "'" + s.replace(/'/g, "'\\''") + "'"; } - src/index.ts:72-108 (helper)SSH execution helper that connects to the NAS, runs a command via sudo with password piped via printf, and returns stdout, stderr, and exit code.
async function execSshCommand(command: string): Promise<{ stdout: string; stderr: string; code: number }> { return new Promise((resolve, reject) => { const conn = new Client(); conn.on("ready", () => { // Use printf to avoid shell expansion of password contents. const fullCommand = `export PATH=$PATH:/usr/local/bin:/opt/bin:/bin:/usr/bin && printf '%s\\n' ${shQuote(NAS_PASSWORD!)} | sudo -S sh -c ${shQuote(command)}`; conn.exec(fullCommand, (err, stream) => { if (err) { conn.end(); return reject(err); } let stdout = ""; let stderr = ""; stream .on("close", (code: number) => { conn.end(); resolve({ stdout, stderr, code }); }) .on("data", (data: any) => { stdout += data; }) .stderr.on("data", (data: any) => { stderr += data; }); }); }).on("error", (err) => { reject(err); }).connect({ host: NAS_HOST, port: NAS_PORT, username: NAS_USER, password: NAS_PASSWORD, readyTimeout: 30000, }); });