r006: Add unraid_system_shell tool (direct terminal access)
- New helper runShell(): executes /bin/sh -c, returns {exit_code, stdout, stderr} as JSON
- New tool unraid_system_shell: direct shell access on Unraid host (root)
- params: command (required), timeout_seconds (1-300, default 60)
- output size-limited via sanitizeLogOutput
- Version bump r005 -> r006
This commit is contained in:
1 parent
c29fc00886
commit
38463190ee
3 files changed
+58
-5
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mua",
|
"name": "mua",
|
||||||
"version": "2026.08.18.r005",
|
"version": "2026.08.18.r006",
|
||||||
"description": "Mikes Unraid Agent - MCP over HTTP (Streamable HTTP) for Unraid",
|
"description": "Mikes Unraid Agent - MCP over HTTP (Streamable HTTP) for Unraid",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
|
|||||||
+29
-1
@@ -13,7 +13,7 @@ import { createConnection, type Socket } from "net";
|
|||||||
|
|
||||||
// ── Konstanten ──────────────────────────────────────────────────────────
|
// ── Konstanten ──────────────────────────────────────────────────────────
|
||||||
export const MUA_SERVER_NAME = "mua";
|
export const MUA_SERVER_NAME = "mua";
|
||||||
export const MUA_VERSION = "2026.08.18.r005";
|
export const MUA_VERSION = "2026.08.18.r006";
|
||||||
export const MUA_PROTOCOL_VERSION = "2025-03-26";
|
export const MUA_PROTOCOL_VERSION = "2025-03-26";
|
||||||
export const PHP_HELPER = "/usr/local/bin/unraid-docker-mcp-helper.php";
|
export const PHP_HELPER = "/usr/local/bin/unraid-docker-mcp-helper.php";
|
||||||
|
|
||||||
@@ -53,6 +53,34 @@ export async function runLocal(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shell-Befehl ausführen und strukturiertes Ergebnis liefern
|
||||||
|
* (exit_code + stdout + stderr). Für das unraid_system_shell-Tool.
|
||||||
|
* Liefert JSON, damit der Agent Exit-Code und beides Streams sieht.
|
||||||
|
*/
|
||||||
|
export async function runShell(cmd: string, timeoutSec = 60): Promise<string> {
|
||||||
|
try {
|
||||||
|
const proc = spawn(["/bin/sh", "-c", cmd], {
|
||||||
|
stdout: "pipe",
|
||||||
|
stderr: "pipe",
|
||||||
|
});
|
||||||
|
const timeout = setTimeout(() => proc.kill(), timeoutSec * 1000);
|
||||||
|
const [stdout, stderr, code] = await Promise.all([
|
||||||
|
new Response(proc.stdout).text(),
|
||||||
|
new Response(proc.stderr).text(),
|
||||||
|
proc.exited,
|
||||||
|
]);
|
||||||
|
clearTimeout(timeout);
|
||||||
|
return JSON.stringify({
|
||||||
|
exit_code: code,
|
||||||
|
stdout: sanitizeLogOutput(stdout.trim(), 100000),
|
||||||
|
stderr: sanitizeLogOutput(stderr.trim(), 20000),
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error(`run_shell failed: ${String(e)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Docker-Befehl ausführen (kompakt).
|
* Docker-Befehl ausführen (kompakt).
|
||||||
*/
|
*/
|
||||||
|
|||||||
+28
-3
@@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* MUA — Mikes Unraid Agent
|
* MUA — Mikes Unraid Agent
|
||||||
* tools.ts — MCP Tool-Definitionen (21 Tools)
|
* tools.ts — MCP Tool-Definitionen (22 Tools)
|
||||||
*
|
*
|
||||||
* Portiert von mcp/tools.php. Schema: unraid_<kategorie>_<aktion>
|
* Portiert von mcp/tools.php. Schema: unraid_<kategorie>_<aktion>
|
||||||
* Kategorien: docker (14), network (6), system (1).
|
* Kategorien: docker (14), network (6), system (2).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
probeDualstack,
|
probeDualstack,
|
||||||
connectionTest,
|
connectionTest,
|
||||||
validateName,
|
validateName,
|
||||||
|
runShell,
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
|
|
||||||
export interface ToolDef {
|
export interface ToolDef {
|
||||||
@@ -294,7 +295,7 @@ export const TOOLS: ToolDef[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// ── System (1) ────────────────────────────────────────────────────────
|
// ── System (2) ────────────────────────────────────────────────────────
|
||||||
{
|
{
|
||||||
name: "unraid_system_connection_test",
|
name: "unraid_system_connection_test",
|
||||||
description:
|
description:
|
||||||
@@ -302,6 +303,30 @@ export const TOOLS: ToolDef[] = [
|
|||||||
inputSchema: empty,
|
inputSchema: empty,
|
||||||
handler: () => connectionTest(),
|
handler: () => connectionTest(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "unraid_system_shell",
|
||||||
|
description:
|
||||||
|
"Execute a shell command on the Unraid host (as root, via /bin/sh -c) and return exit code, stdout, and stderr. Use for direct terminal access: file inspection, system commands, package info, log reading, etc. Commands run with a timeout and output is size-limited.",
|
||||||
|
inputSchema: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
command: str(
|
||||||
|
"Shell command to execute on the Unraid host (run via /bin/sh -c)",
|
||||||
|
),
|
||||||
|
timeout_seconds: int("Timeout in seconds (1-300, default 60)"),
|
||||||
|
},
|
||||||
|
required: ["command"],
|
||||||
|
},
|
||||||
|
handler: (a) => {
|
||||||
|
const command = (a["command"] as string) ?? "";
|
||||||
|
if (command.trim() === "") throw new Error("command is required");
|
||||||
|
const timeout = Number(a["timeout_seconds"] ?? 60);
|
||||||
|
if (timeout < 1 || timeout > 300) {
|
||||||
|
throw new Error("timeout_seconds must be between 1 and 300");
|
||||||
|
}
|
||||||
|
return runShell(command, timeout);
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function toolByName(name: string): ToolDef | undefined {
|
export function toolByName(name: string): ToolDef | undefined {
|
||||||
|
|||||||
Reference in new issue
Block a user