Add ncmcp.mjs CLI wrapper
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// ncmcp.mjs - CLI wrapper for nextcloud-mcp (read .env automatically)
|
||||||
|
// Usage: ncmcp <tool> [key=value ...]
|
||||||
|
|
||||||
|
import { spawn } from "child_process";
|
||||||
|
import { dirname, join } from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import { readFileSync, existsSync } from "fs";
|
||||||
|
import { createInterface } from "readline";
|
||||||
|
|
||||||
|
const __dir = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const serverPath = join(__dir, "build/index.js");
|
||||||
|
|
||||||
|
// Load .env
|
||||||
|
const envFile = join(__dir, ".env");
|
||||||
|
const env = { ...process.env };
|
||||||
|
if (existsSync(envFile)) {
|
||||||
|
for (const line of readFileSync(envFile, "utf8").split("\n")) {
|
||||||
|
const m = line.match(/^([^#=]+)=(.*)$/);
|
||||||
|
if (m) env[m[1].trim()] = m[2].trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [,, tool, ...rawArgs] = process.argv;
|
||||||
|
|
||||||
|
if (!tool) {
|
||||||
|
console.log("Usage: ncmcp <tool> [key=value ...]");
|
||||||
|
console.log("Tools: list_calendars, get_calendar_events, create_calendar_event,");
|
||||||
|
console.log(" get_tasks, create_task, update_task,");
|
||||||
|
console.log(" get_notes, create_note, get_note_content, get_emails");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse key=value args; values that look like JSON arrays/objects get parsed
|
||||||
|
const args = {};
|
||||||
|
for (const a of rawArgs) {
|
||||||
|
const sep = a.indexOf("=");
|
||||||
|
if (sep > 0) {
|
||||||
|
const k = a.slice(0, sep);
|
||||||
|
const v = a.slice(sep + 1);
|
||||||
|
try { args[k] = JSON.parse(v); } catch { args[k] = v; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const child = spawn("node", [serverPath], { env, stdio: ["pipe", "pipe", "inherit"] });
|
||||||
|
const rl = createInterface({ input: child.stdout });
|
||||||
|
|
||||||
|
const send = (msg) => child.stdin.write(JSON.stringify(msg) + "\n");
|
||||||
|
|
||||||
|
rl.on("line", (line) => {
|
||||||
|
try {
|
||||||
|
const msg = JSON.parse(line);
|
||||||
|
if (msg.id === 1) {
|
||||||
|
send({ jsonrpc: "2.0", id: 2, method: "tools/call", params: { name: tool, arguments: args } });
|
||||||
|
} else if (msg.id === 2) {
|
||||||
|
const content = msg.result?.content?.[0]?.text;
|
||||||
|
if (content) {
|
||||||
|
try { console.log(JSON.stringify(JSON.parse(content), null, 2)); }
|
||||||
|
catch { console.log(content); }
|
||||||
|
} else if (msg.error) {
|
||||||
|
console.error("Error:", msg.error.message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
child.stdin.end();
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
});
|
||||||
|
|
||||||
|
send({ jsonrpc: "2.0", id: 1, method: "initialize", params: { protocolVersion: "2024-11-05", capabilities: {}, clientInfo: { name: "ncmcp", version: "1.0" } } });
|
||||||
|
setTimeout(() => { console.error("Timeout"); process.exit(1); }, 15000);
|
||||||
Reference in New Issue
Block a user