remote-access-mcp 3.0.2 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.fa.md +18 -0
- package/README.md +22 -2
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +7 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/core/approvals.d.ts +17 -0
- package/dist/core/approvals.d.ts.map +1 -0
- package/dist/core/approvals.js +113 -0
- package/dist/core/approvals.js.map +1 -0
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +3 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/jobs.d.ts +41 -0
- package/dist/core/jobs.d.ts.map +1 -0
- package/dist/core/jobs.js +234 -0
- package/dist/core/jobs.js.map +1 -0
- package/dist/core/policy.d.ts +5 -0
- package/dist/core/policy.d.ts.map +1 -1
- package/dist/core/policy.js +78 -1
- package/dist/core/policy.js.map +1 -1
- package/dist/server/app.d.ts.map +1 -1
- package/dist/server/app.js +5 -2
- package/dist/server/app.js.map +1 -1
- package/dist/server/run.d.ts.map +1 -1
- package/dist/server/run.js +2 -0
- package/dist/server/run.js.map +1 -1
- package/dist/tools/changes.d.ts +25 -0
- package/dist/tools/changes.d.ts.map +1 -0
- package/dist/tools/changes.js +192 -0
- package/dist/tools/changes.js.map +1 -0
- package/dist/tools/database.d.ts +4 -0
- package/dist/tools/database.d.ts.map +1 -0
- package/dist/tools/database.js +29 -0
- package/dist/tools/database.js.map +1 -0
- package/dist/tools/diagnostics.d.ts +4 -0
- package/dist/tools/diagnostics.d.ts.map +1 -0
- package/dist/tools/diagnostics.js +23 -0
- package/dist/tools/diagnostics.js.map +1 -0
- package/dist/tools/filesystem.d.ts.map +1 -1
- package/dist/tools/filesystem.js +10 -4
- package/dist/tools/filesystem.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +17 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/jobs.d.ts +4 -0
- package/dist/tools/jobs.d.ts.map +1 -0
- package/dist/tools/jobs.js +42 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/monitoring.d.ts +4 -0
- package/dist/tools/monitoring.d.ts.map +1 -0
- package/dist/tools/monitoring.js +141 -0
- package/dist/tools/monitoring.js.map +1 -0
- package/dist/tools/plugins.d.ts +5 -0
- package/dist/tools/plugins.d.ts.map +1 -0
- package/dist/tools/plugins.js +53 -0
- package/dist/tools/plugins.js.map +1 -0
- package/dist/tools/resources-prompts.d.ts +4 -0
- package/dist/tools/resources-prompts.d.ts.map +1 -0
- package/dist/tools/resources-prompts.js +21 -0
- package/dist/tools/resources-prompts.js.map +1 -0
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +31 -2
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/transfer.d.ts +4 -0
- package/dist/tools/transfer.d.ts.map +1 -0
- package/dist/tools/transfer.js +14 -0
- package/dist/tools/transfer.js.map +1 -0
- package/docs/ai/security-model.md +7 -0
- package/docs/ai/tools-and-cli.md +32 -0
- package/package.json +4 -1
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { assertToolPermitted } from '../core/policy.js';
|
|
7
|
+
import { AuditLog } from '../core/audit.js';
|
|
8
|
+
import { dataDir } from '../core/platform.js';
|
|
9
|
+
import { notifyWebhooks } from '../core/webhooks.js';
|
|
10
|
+
const MAX_WATCHES = 500;
|
|
11
|
+
const LOCK_TIMEOUT_MS = 10_000;
|
|
12
|
+
const STALE_LOCK_MS = 30_000;
|
|
13
|
+
const timers = new Map();
|
|
14
|
+
let restored = false;
|
|
15
|
+
function storePath() { return path.join(dataDir(), 'health-watches.json'); }
|
|
16
|
+
function lockPath() { return path.join(dataDir(), 'health-watches.lock'); }
|
|
17
|
+
function isAlive(pid) {
|
|
18
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
19
|
+
return false;
|
|
20
|
+
try {
|
|
21
|
+
process.kill(pid, 0);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
return e?.code === 'EPERM';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function load() {
|
|
29
|
+
try {
|
|
30
|
+
const rows = JSON.parse(fs.readFileSync(storePath(), 'utf8'));
|
|
31
|
+
if (!Array.isArray(rows))
|
|
32
|
+
throw new Error('invalid health watcher store');
|
|
33
|
+
return rows.filter((r) => r && typeof r.id === 'string' && typeof r.tokenFingerprint === 'string' && Number.isInteger(r.intervalSeconds) && r.intervalSeconds >= 10 && r.intervalSeconds <= 3600 && typeof r.created === 'string');
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
if (e?.code === 'ENOENT')
|
|
37
|
+
return [];
|
|
38
|
+
throw new Error(`failed to read health watcher store: ${e?.message || e}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function withLock(fn) {
|
|
42
|
+
fs.mkdirSync(dataDir(), { recursive: true, mode: 0o700 });
|
|
43
|
+
const started = Date.now();
|
|
44
|
+
while (true) {
|
|
45
|
+
try {
|
|
46
|
+
fs.mkdirSync(lockPath(), { mode: 0o700 });
|
|
47
|
+
try {
|
|
48
|
+
return fn();
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
fs.rmSync(lockPath(), { recursive: true, force: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
if (e?.code !== 'EEXIST')
|
|
56
|
+
throw e;
|
|
57
|
+
try {
|
|
58
|
+
if (Date.now() - fs.statSync(lockPath()).mtimeMs > STALE_LOCK_MS)
|
|
59
|
+
fs.rmSync(lockPath(), { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
catch { /* retry */ }
|
|
62
|
+
if (Date.now() - started > LOCK_TIMEOUT_MS)
|
|
63
|
+
throw new Error('timed out waiting for health watcher persistence lock');
|
|
64
|
+
const until = Date.now() + 20;
|
|
65
|
+
while (Date.now() < until) { /* synchronous lock acquisition */ }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function saveUnlocked(rows) {
|
|
70
|
+
const target = storePath();
|
|
71
|
+
const tmp = `${target}.tmp-${process.pid}-${crypto.randomUUID()}`;
|
|
72
|
+
fs.writeFileSync(tmp, JSON.stringify([...rows].sort((a, b) => a.created.localeCompare(b.created)).slice(-MAX_WATCHES), null, 2), { mode: 0o600 });
|
|
73
|
+
fs.renameSync(tmp, target);
|
|
74
|
+
}
|
|
75
|
+
function persist(mutator) {
|
|
76
|
+
return withLock(() => { const rows = load(); mutator(rows); saveUnlocked(rows); return rows; });
|
|
77
|
+
}
|
|
78
|
+
function current(id, fingerprint) {
|
|
79
|
+
return load().find(w => w.id === id && w.tokenFingerprint === fingerprint);
|
|
80
|
+
}
|
|
81
|
+
function stopLocal(key) {
|
|
82
|
+
const timer = timers.get(key);
|
|
83
|
+
if (timer)
|
|
84
|
+
clearInterval(timer);
|
|
85
|
+
timers.delete(key);
|
|
86
|
+
}
|
|
87
|
+
function startLocal(w, cfg) {
|
|
88
|
+
const key = `${w.tokenFingerprint}:${w.id}`;
|
|
89
|
+
stopLocal(key);
|
|
90
|
+
const timer = setInterval(() => {
|
|
91
|
+
const live = current(w.id, w.tokenFingerprint);
|
|
92
|
+
if (!live || live.ownerPid !== process.pid) {
|
|
93
|
+
stopLocal(key);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const cpu = os.loadavg()[0] / Math.max(1, os.cpus().length) * 100;
|
|
97
|
+
const memory = (1 - os.freemem() / os.totalmem()) * 100;
|
|
98
|
+
if ((live.cpuPercent !== undefined && cpu >= live.cpuPercent) || (live.memoryPercent !== undefined && memory >= live.memoryPercent)) {
|
|
99
|
+
notifyWebhooks(cfg, { ts: Date.now(), token_fingerprint: w.tokenFingerprint, tool: 'health_watch', args_json: JSON.stringify({ cpu, memory }), ok: 0, is_error: 1, duration_ms: 0 });
|
|
100
|
+
}
|
|
101
|
+
}, w.intervalSeconds * 1000);
|
|
102
|
+
timers.set(key, timer);
|
|
103
|
+
}
|
|
104
|
+
function restoreForProcess(cfg) {
|
|
105
|
+
if (restored)
|
|
106
|
+
return;
|
|
107
|
+
restored = true;
|
|
108
|
+
persist(rows => {
|
|
109
|
+
for (const w of rows)
|
|
110
|
+
if (!isAlive(w.ownerPid))
|
|
111
|
+
w.ownerPid = process.pid;
|
|
112
|
+
}).filter(w => w.ownerPid === process.pid).forEach(w => startLocal(w, cfg));
|
|
113
|
+
}
|
|
114
|
+
export function registerMonitoringTools(server, ctx) {
|
|
115
|
+
restoreForProcess(ctx.cfg);
|
|
116
|
+
const tid = AuditLog.fingerprint(ctx.token.token);
|
|
117
|
+
server.registerTool('health_watch', { description: 'Start a persistent periodic health watcher for CPU/memory thresholds. Alerts are emitted through configured webhooks and survive gateway restart.', inputSchema: { interval_seconds: z.number().min(10).max(3600).default(60), cpu_percent: z.number().min(1).max(100).optional(), memory_percent: z.number().min(1).max(100).optional() } }, async ({ interval_seconds, cpu_percent, memory_percent }) => {
|
|
118
|
+
assertToolPermitted({ tool: 'health_watch', scopes: ctx.token.scopes, readOnly: ctx.readOnly });
|
|
119
|
+
const watcher = { id: crypto.randomUUID().slice(0, 12), tokenFingerprint: tid, intervalSeconds: interval_seconds, cpuPercent: cpu_percent, memoryPercent: memory_percent, created: new Date().toISOString(), ownerPid: process.pid };
|
|
120
|
+
persist(rows => rows.push(watcher));
|
|
121
|
+
startLocal(watcher, ctx.cfg);
|
|
122
|
+
return { content: [{ type: 'text', text: JSON.stringify({ id: watcher.id, interval_seconds }) }] };
|
|
123
|
+
});
|
|
124
|
+
server.registerTool('health_status', { description: 'List active persistent health watchers for the current token.', inputSchema: {} }, async () => {
|
|
125
|
+
assertToolPermitted({ tool: 'health_status', scopes: ctx.token.scopes, readOnly: ctx.readOnly });
|
|
126
|
+
const rows = load().filter(w => w.tokenFingerprint === tid && isAlive(w.ownerPid));
|
|
127
|
+
return { content: [{ type: 'text', text: JSON.stringify(rows.map(w => w.id)) }] };
|
|
128
|
+
});
|
|
129
|
+
server.registerTool('health_stop', { description: 'Stop a persistent health watcher.', inputSchema: { id: z.string() } }, async ({ id }) => {
|
|
130
|
+
assertToolPermitted({ tool: 'health_stop', scopes: ctx.token.scopes, readOnly: ctx.readOnly });
|
|
131
|
+
const key = `${tid}:${id}`;
|
|
132
|
+
const exists = current(id, tid);
|
|
133
|
+
if (!exists)
|
|
134
|
+
return { content: [{ type: 'text', text: 'Watcher not found.' }], isError: true };
|
|
135
|
+
persist(rows => { const i = rows.findIndex(w => w.id === id && w.tokenFingerprint === tid); if (i >= 0)
|
|
136
|
+
rows.splice(i, 1); });
|
|
137
|
+
stopLocal(key);
|
|
138
|
+
return { content: [{ type: 'text', text: `Stopped ${id}.` }] };
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=monitoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitoring.js","sourceRoot":"","sources":["../../src/tools/monitoring.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAYrD,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,aAAa,GAAG,MAAM,CAAC;AAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;AACjD,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,SAAS,SAAS,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACpF,SAAS,QAAQ,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;AACnF,SAAS,OAAO,CAAC,GAAY;IAC3B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAK,GAAc,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,GAAa,EAAE,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,IAAI,KAAK,OAAO,CAAC;IAAC,CAAC;AACrG,CAAC;AACD,SAAS,IAAI;IACX,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAoB,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,eAAe,IAAI,EAAE,IAAI,CAAC,CAAC,eAAe,IAAI,IAAI,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC;IACvP,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AACD,SAAS,QAAQ,CAAI,EAAW;IAC9B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC3B,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC;gBAAC,OAAO,EAAE,EAAE,CAAC;YAAC,CAAC;oBAAS,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;QAC3F,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC;YAClC,IAAI,CAAC;gBAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,GAAG,aAAa;oBAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACxJ,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,eAAe;gBAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACrH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,kCAAkC,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;AACH,CAAC;AACD,SAAS,YAAY,CAAC,IAAmB;IACvC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAG,GAAG,MAAM,QAAQ,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;IAClE,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClJ,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC;AACD,SAAS,OAAO,CAAC,OAAsC;IACrD,OAAO,QAAQ,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAClG,CAAC;AACD,SAAS,OAAO,CAAC,EAAU,EAAE,WAAmB;IAC9C,OAAO,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,gBAAgB,KAAK,WAAW,CAAC,CAAC;AAC7E,CAAC;AACD,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,KAAK;QAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AACD,SAAS,UAAU,CAAC,CAAc,EAAE,GAAuB;IACzD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;IAC5C,SAAS,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;YAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACvE,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QAClE,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,GAAG,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YACpI,cAAc,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QACvL,CAAC;IACH,CAAC,EAAE,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AACD,SAAS,iBAAiB,CAAC,GAAuB;IAChD,IAAI,QAAQ;QAAE,OAAO;IACrB,QAAQ,GAAG,IAAI,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,EAAE;QACb,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAC3E,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,GAAgB;IACzE,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE,EAAE,WAAW,EAAE,mJAAmJ,EAAE,WAAW,EAAE,EAAE,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,EAAE,EAAE;QAC5b,mBAAmB,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChG,MAAM,OAAO,GAAgB,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE,GAAG,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;QAClP,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACpC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACrG,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,EAAE,WAAW,EAAE,+DAA+D,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;QACjJ,mBAAmB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjG,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,WAAW,EAAE,mCAAmC,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE;QACzI,mBAAmB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/F,MAAM,GAAG,GAAG,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC/F,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,gBAAgB,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9H,SAAS,CAAC,GAAG,CAAC,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ToolContext } from '../core/context.js';
|
|
3
|
+
export declare function registerInstalledPlugins(server: McpServer, ctx: ToolContext): Promise<void>;
|
|
4
|
+
export declare function registerPluginTools(server: McpServer, ctx: ToolContext): void;
|
|
5
|
+
//# sourceMappingURL=plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/tools/plugins.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAetD,wBAAsB,wBAAwB,CAAC,MAAM,EAAC,SAAS,EAAC,GAAG,EAAC,WAAW,GAAE,OAAO,CAAC,IAAI,CAAC,CAS7F;AACD,wBAAgB,mBAAmB,CAAC,MAAM,EAAC,SAAS,EAAC,GAAG,EAAC,WAAW,GAAE,IAAI,CAIzE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { assertToolPermitted, assertAllowed } from '../core/policy.js';
|
|
6
|
+
import { dataDir } from '../core/platform.js';
|
|
7
|
+
const root = () => path.join(dataDir(), 'plugins');
|
|
8
|
+
function manifests() { if (!fs.existsSync(root()))
|
|
9
|
+
return []; return fs.readdirSync(root(), { withFileTypes: true }).flatMap(d => { if (!d.isDirectory())
|
|
10
|
+
return []; try {
|
|
11
|
+
return [JSON.parse(fs.readFileSync(path.join(root(), d.name, 'manifest.json'), 'utf8'))];
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return [];
|
|
15
|
+
} }); }
|
|
16
|
+
function pluginDir(name) { return path.join(root(), name.replace(/[^a-zA-Z0-9._-]/g, '_')); }
|
|
17
|
+
function pluginEntry(m) {
|
|
18
|
+
if (!m.entry || !m.trusted)
|
|
19
|
+
return null;
|
|
20
|
+
const dir = pluginDir(m.name);
|
|
21
|
+
const resolved = path.resolve(dir, m.entry);
|
|
22
|
+
const rel = path.relative(dir, resolved);
|
|
23
|
+
if (!rel || rel.startsWith('..' + path.sep) || path.isAbsolute(rel))
|
|
24
|
+
return null;
|
|
25
|
+
return resolved;
|
|
26
|
+
}
|
|
27
|
+
export async function registerInstalledPlugins(server, ctx) {
|
|
28
|
+
for (const m of manifests()) {
|
|
29
|
+
const entry = pluginEntry(m);
|
|
30
|
+
if (!entry)
|
|
31
|
+
continue;
|
|
32
|
+
const dir = pluginDir(m.name);
|
|
33
|
+
const allowed = (m.permissions || []).every(p => !ctx.token.scopes.length || ctx.token.scopes.includes(p));
|
|
34
|
+
if (!allowed)
|
|
35
|
+
continue;
|
|
36
|
+
try {
|
|
37
|
+
const mod = await import(pathToFileURL(entry).href);
|
|
38
|
+
if (typeof mod.register === 'function')
|
|
39
|
+
await mod.register(server, ctx);
|
|
40
|
+
}
|
|
41
|
+
catch { /* a broken plugin must not prevent gateway startup */ }
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function registerPluginTools(server, ctx) {
|
|
45
|
+
server.registerTool('plugin_list', { description: 'List installed local Remote Access MCP plugins and their declared permissions.', inputSchema: {} }, async () => { assertToolPermitted({ tool: 'plugin_list', scopes: ctx.token.scopes, readOnly: ctx.readOnly }); return { content: [{ type: 'text', text: JSON.stringify(manifests(), null, 2) }] }; });
|
|
46
|
+
server.registerTool('plugin_install', { description: 'Install a trusted local plugin directory containing manifest.json. The source must already exist on the machine.', inputSchema: { source: z.string() } }, async ({ source }) => { assertToolPermitted({ tool: 'plugin_install', scopes: ctx.token.scopes, readOnly: ctx.readOnly }); const src = path.resolve(source); assertAllowed({ allowed_paths: ctx.token.allowed_paths, denied_paths: ctx.token.denied_paths, shell_enabled: ctx.token.shell_enabled }, src); const mf = path.join(src, 'manifest.json'); if (!fs.existsSync(mf))
|
|
47
|
+
return { content: [{ type: 'text', text: 'manifest.json not found.' }], isError: true }; const m = JSON.parse(fs.readFileSync(mf, 'utf8')); if (!m.name || !m.version)
|
|
48
|
+
return { content: [{ type: 'text', text: 'Invalid plugin manifest.' }], isError: true }; if (m.trusted !== true)
|
|
49
|
+
return { content: [{ type: 'text', text: 'Plugin manifest must explicitly set trusted=true before installation.' }], isError: true }; const dest = pluginDir(m.name); fs.mkdirSync(root(), { recursive: true }); fs.cpSync(src, dest, { recursive: true }); return { content: [{ type: 'text', text: `Plugin ${m.name}@${m.version} installed. Declared permissions: ${(m.permissions || []).join(', ') || 'none'}.` }] }; });
|
|
50
|
+
server.registerTool('plugin_remove', { description: 'Remove an installed local plugin.', inputSchema: { name: z.string().regex(/^[a-zA-Z0-9._-]+$/) } }, async ({ name }) => { assertToolPermitted({ tool: 'plugin_remove', scopes: ctx.token.scopes, readOnly: ctx.readOnly }); const p = path.join(root(), name); if (!fs.existsSync(p))
|
|
51
|
+
return { content: [{ type: 'text', text: 'Plugin not found.' }], isError: true }; fs.rmSync(p, { recursive: true, force: true }); return { content: [{ type: 'text', text: `Plugin ${name} removed.` }] }; });
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/tools/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ToolContext } from '../core/context.js';
|
|
3
|
+
export declare function registerResourcesAndPrompts(server: McpServer, ctx: ToolContext): void;
|
|
4
|
+
//# sourceMappingURL=resources-prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources-prompts.d.ts","sourceRoot":"","sources":["../../src/tools/resources-prompts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,wBAAgB,2BAA2B,CAAC,MAAM,EAAC,SAAS,EAAC,GAAG,EAAC,WAAW,GAAE,IAAI,CAcjF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { assertToolPermitted } from '../core/policy.js';
|
|
4
|
+
import { dataDir } from '../core/platform.js';
|
|
5
|
+
export function registerResourcesAndPrompts(server, ctx) {
|
|
6
|
+
const gate = (tool) => assertToolPermitted({ tool, scopes: ctx.token.scopes, readOnly: ctx.readOnly });
|
|
7
|
+
const json = (x) => JSON.stringify(x, null, 2);
|
|
8
|
+
server.registerResource('system_resource', 'ramcp://system', { description: 'Current local system information', mimeType: 'application/json' }, async () => ({ contents: [{ uri: 'ramcp://system', mimeType: 'application/json', text: json({ hostname: os.hostname(), platform: process.platform, release: os.release(), arch: os.arch(), cpus: os.cpus().length, totalMemory: os.totalmem(), freeMemory: os.freemem(), uptime: os.uptime() }) }] }));
|
|
9
|
+
server.registerResource('services_resource', 'ramcp://services', { description: 'Configured service and runtime overview', mimeType: 'application/json' }, async () => ({ contents: [{ uri: 'ramcp://services', mimeType: 'application/json', text: json({ platform: process.platform, pid: process.pid, uptime: process.uptime() }) }] }));
|
|
10
|
+
server.registerResource('network_resource', 'ramcp://network', { description: 'Local network interface information', mimeType: 'application/json' }, async () => ({ contents: [{ uri: 'ramcp://network', mimeType: 'application/json', text: json(os.networkInterfaces()) }] }));
|
|
11
|
+
server.registerResource('projects_resource', 'ramcp://projects', { description: 'Local Remote Access MCP data directory overview', mimeType: 'application/json' }, async () => ({ contents: [{ uri: 'ramcp://projects', mimeType: 'application/json', text: json({ dataDir: dataDir(), entries: fs.existsSync(dataDir()) ? fs.readdirSync(dataDir()) : [] }) }] }));
|
|
12
|
+
server.registerResource('audit_resource', 'ramcp://audit', { description: 'Recent audit entries for the authenticated operator', mimeType: 'application/json' }, async () => { gate('audit_resource'); if (!ctx.cfg.audit.enabled)
|
|
13
|
+
return { contents: [{ uri: 'ramcp://audit', mimeType: 'application/json', text: json([]) }] }; const { AuditLog } = await import('../core/audit.js'); const audit = new AuditLog(ctx.cfg.audit.db_path); const fingerprint = AuditLog.fingerprint(ctx.token.token); const rows = audit.query({ fingerprint, limit: 100 }); return { contents: [{ uri: 'ramcp://audit', mimeType: 'application/json', text: json(rows) }] }; });
|
|
14
|
+
const prompt = (name, title, description, text) => server.registerPrompt(name, { title, description }, async () => ({ description, messages: [{ role: 'user', content: { type: 'text', text } }] }));
|
|
15
|
+
prompt('diagnose_prompt', 'Diagnose Server', 'Systematic server diagnosis', 'Inspect system health, failed services, processes, ports, logs, disk and network. Prefer read-only diagnostics first and summarize evidence before proposing mutations.');
|
|
16
|
+
prompt('deploy_prompt', 'Deploy Project', 'Safe project deployment', 'Inspect the project, run tests/build, create a change snapshot, apply the smallest safe deployment steps, verify service health, and report rollback instructions.');
|
|
17
|
+
prompt('security_audit_prompt', 'Security Audit', 'Local security review', 'Audit exposed ports, permissions, secrets, services and configuration. Do not reveal secrets; report masked findings and prioritize remediation.');
|
|
18
|
+
prompt('inspect_project_prompt', 'Inspect Project', 'Developer project inspection', 'Analyze the project structure, framework, dependencies, Git state, tests and health. Return actionable findings with file paths.');
|
|
19
|
+
server.registerTool('system_resource', { description: 'Return the current system resource as structured JSON.', inputSchema: {} }, async () => { gate('system_resource'); return { content: [{ type: 'text', text: json({ hostname: os.hostname(), platform: process.platform, release: os.release(), cpus: os.cpus().length, totalMemory: os.totalmem(), freeMemory: os.freemem(), uptime: os.uptime() }) }] }; });
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=resources-prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources-prompts.js","sourceRoot":"","sources":["../../src/tools/resources-prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOtD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAgI5E"}
|
package/dist/tools/shell.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { execFile } from 'node:child_process';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { assertToolPermitted } from '../core/policy.js';
|
|
4
|
+
import { assertToolPermitted, assertCommandPolicy } from '../core/policy.js';
|
|
5
|
+
import { AuditLog } from '../core/audit.js';
|
|
6
|
+
import { requestApproval, getApproval, decideApproval, consumeApproval } from '../core/approvals.js';
|
|
5
7
|
import { shellCommand, childEnv, isWindows } from '../core/platform.js';
|
|
6
8
|
const exec = promisify(execFile);
|
|
7
9
|
const MAX_OUTPUT = 60_000;
|
|
@@ -20,12 +22,25 @@ export function registerShellTools(server, ctx) {
|
|
|
20
22
|
command: z.string().describe('Command line to run'),
|
|
21
23
|
cwd: z.string().optional().describe('Working directory (policy-checked when local)'),
|
|
22
24
|
timeout_ms: z.number().optional().default(120_000).describe('Timeout in ms (max 600000)'),
|
|
25
|
+
approval_id: z.string().optional().describe('Approval id previously approved by an authorized operator'),
|
|
23
26
|
},
|
|
24
|
-
}, async ({ command, cwd, timeout_ms }) => {
|
|
27
|
+
}, async ({ command, cwd, timeout_ms, approval_id }) => {
|
|
25
28
|
if (!ctx.token.shell_enabled) {
|
|
26
29
|
return { content: [{ type: 'text', text: 'Shell execution is disabled for this token. Enable with `ramcp policy shell on`.' }], isError: true };
|
|
27
30
|
}
|
|
28
31
|
assertToolPermitted({ tool: 'run_command', scopes: ctx.token.scopes, readOnly: ctx.readOnly, policy: policy(), target: cwd });
|
|
32
|
+
const tokenId = AuditLog.fingerprint(ctx.token.token);
|
|
33
|
+
const approval = approval_id ? getApproval(approval_id, tokenId) : undefined;
|
|
34
|
+
if (ctx.token.approval_mode === 'approval-required') {
|
|
35
|
+
if (!approval || approval.status !== 'approved' || approval.command !== command || approval.cwd !== cwd) {
|
|
36
|
+
const pending = requestApproval(tokenId, command, cwd);
|
|
37
|
+
return { content: [{ type: 'text', text: `Approval required. Ask an authorized operator to approve approval_id=${pending.id}, then retry with approval_id.` }], isError: true };
|
|
38
|
+
}
|
|
39
|
+
if (!consumeApproval(approval.id, tokenId, command, cwd)) {
|
|
40
|
+
return { content: [{ type: 'text', text: 'Approval is invalid, already consumed, or does not match this exact command/cwd.' }], isError: true };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
assertCommandPolicy({ command_allowlist: ctx.token.command_allowlist, approval_mode: 'auto' }, command, true);
|
|
29
44
|
const timeout = Math.min(timeout_ms, 600_000);
|
|
30
45
|
const { file, args } = shellCommand(command);
|
|
31
46
|
try {
|
|
@@ -54,6 +69,20 @@ export function registerShellTools(server, ctx) {
|
|
|
54
69
|
return { content: [{ type: 'text', text: msg.slice(0, MAX_OUTPUT) }], isError: true };
|
|
55
70
|
}
|
|
56
71
|
});
|
|
72
|
+
server.registerTool('approval_decide', {
|
|
73
|
+
description: 'Approve or reject a pending shell command approval request.',
|
|
74
|
+
inputSchema: { id: z.string(), approved: z.boolean() },
|
|
75
|
+
}, async ({ id, approved }) => {
|
|
76
|
+
assertToolPermitted({ tool: 'approval_decide', scopes: ctx.token.scopes, readOnly: ctx.readOnly });
|
|
77
|
+
const actorId = AuditLog.fingerprint(ctx.token.token);
|
|
78
|
+
const privileged = ctx.token.role === 'admin' || ctx.token.role === 'deployer';
|
|
79
|
+
const requesterId = privileged ? undefined : actorId;
|
|
80
|
+
const a = getApproval(id, requesterId);
|
|
81
|
+
if (!a)
|
|
82
|
+
return { content: [{ type: 'text', text: 'Approval not found or not authorized.' }], isError: true };
|
|
83
|
+
decideApproval(id, requesterId, approved, actorId);
|
|
84
|
+
return { content: [{ type: 'text', text: `Approval ${id}: ${approved ? 'approved' : 'rejected'}.` }] };
|
|
85
|
+
});
|
|
57
86
|
// ---- process_list ---------------------------------------------------------
|
|
58
87
|
server.registerTool('process_list', {
|
|
59
88
|
description: 'List running processes with CPU/memory. Uses ps on POSIX, Get-Process on Windows.',
|
package/dist/tools/shell.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/tools/shell.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../../src/tools/transfer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,wBAAgB,qBAAqB,CAAC,MAAM,EAAC,SAAS,EAAC,GAAG,EAAC,WAAW,GAAE,IAAI,CAI3E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import crypto from 'node:crypto';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { assertToolPermitted } from '../core/policy.js';
|
|
5
|
+
const MAX = 32 * 1024 * 1024;
|
|
6
|
+
export function registerTransferTools(server, ctx) {
|
|
7
|
+
const policy = () => ({ allowed_paths: ctx.token.allowed_paths, denied_paths: ctx.token.denied_paths, shell_enabled: ctx.token.shell_enabled });
|
|
8
|
+
server.registerTool('download_file', { description: 'Download a local file as base64 with size and SHA-256 metadata. Binary-safe and path-policy checked.', inputSchema: { path: z.string() } }, async ({ path }) => { assertToolPermitted({ tool: 'download_file', scopes: ctx.token.scopes, readOnly: ctx.readOnly, policy: policy(), target: path }); const st = await fs.stat(path); if (st.size > MAX)
|
|
9
|
+
return { content: [{ type: 'text', text: `File exceeds ${MAX} bytes.` }], isError: true }; const b = await fs.readFile(path); return { content: [{ type: 'text', text: JSON.stringify({ path, size: b.length, sha256: crypto.createHash('sha256').update(b).digest('hex'), encoding: 'base64', data: b.toString('base64') }) }] }; });
|
|
10
|
+
server.registerTool('upload_file', { description: 'Upload base64 data to a local file. Binary-safe, size-limited and path-policy checked.', inputSchema: { path: z.string(), data: z.string().describe('Base64-encoded file content'), sha256: z.string().optional() } }, async ({ path, data, sha256 }) => { assertToolPermitted({ tool: 'upload_file', scopes: ctx.token.scopes, readOnly: ctx.readOnly, policy: policy(), target: path }); const b = Buffer.from(data, 'base64'); if (b.length > MAX)
|
|
11
|
+
return { content: [{ type: 'text', text: `Payload exceeds ${MAX} bytes.` }], isError: true }; const actual = crypto.createHash('sha256').update(b).digest('hex'); if (sha256 && sha256 !== actual)
|
|
12
|
+
return { content: [{ type: 'text', text: 'SHA-256 mismatch; file was not written.' }], isError: true }; await fs.writeFile(path, b, { mode: 0o600 }); return { content: [{ type: 'text', text: JSON.stringify({ path, size: b.length, sha256: actual }) }] }; });
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=transfer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../src/tools/transfer.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,3 +112,10 @@ pass them as `target:` to the gate; (4) think about injection (quotes,
|
|
|
112
112
|
metacharacters, second-order effects) and add a guard, not a regex hope;
|
|
113
113
|
(5) never log secrets; the audit wrapper redacts args but your *output* is
|
|
114
114
|
on you.
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
## Approval security
|
|
118
|
+
|
|
119
|
+
Approval records are durable and protected by a filesystem lock. A granted approval is cryptographically unrelated to the shell command, so the implementation binds the approval to the exact command and working directory and atomically marks it consumed before execution. This prevents approval replay and command substitution.
|
|
120
|
+
|
|
121
|
+
Plugins are a trusted in-process extension mechanism. Entrypoints cannot escape their plugin directory, but JavaScript executed by an installed trusted plugin has the gateway process privileges; plugin installation is therefore an administrative trust boundary, not a sandbox.
|
package/docs/ai/tools-and-cli.md
CHANGED
|
@@ -105,6 +105,29 @@ Snapshot/rollback are in `MUTATING_TOOLS`.
|
|
|
105
105
|
`list_allowed_paths` · `allow_path` · `deny_path` · `shell_enabled`. Mutations
|
|
106
106
|
persist via `saveConfig` and hot-reload; they cannot touch other tokens.
|
|
107
107
|
|
|
108
|
+
## New operational tools
|
|
109
|
+
|
|
110
|
+
### Jobs / workers
|
|
111
|
+
- `run_background` — asynchronous shell execution through a bounded worker pool
|
|
112
|
+
- `run_parallel` — queue multiple commands for bounded parallel execution
|
|
113
|
+
- `job_status` / `job_output` / `job_list` / `job_cancel` — inspect and control jobs
|
|
114
|
+
|
|
115
|
+
### Transfers / safety
|
|
116
|
+
- `upload_file` / `download_file` — binary-safe transfer with SHA-256
|
|
117
|
+
- `approval_decide` — approve or reject sensitive shell operations
|
|
118
|
+
- `change_set_begin` / `change_set_add` / `change_set_status` / `change_set_commit` / `change_set_rollback` — managed filesystem change sets; pass `change_set_id` to `write_file`, `edit_file`, and `delete_path` to capture mutations automatically. Rollback tracks missing paths (created later), restores deleted/modified paths, and can resume after partial failure.
|
|
119
|
+
|
|
120
|
+
### Diagnostics / data
|
|
121
|
+
- `system_diagnostics` / `diagnose_service`
|
|
122
|
+
- `health_watch` / `health_status` / `health_stop` — persistent application-level watchers with single-process ownership and restart recovery.
|
|
123
|
+
- `health_watch` / `health_status` / `health_stop`
|
|
124
|
+
- `database_query` / `database_schema`
|
|
125
|
+
|
|
126
|
+
### MCP context / extensibility
|
|
127
|
+
- Resources: system, services, network, projects and audit
|
|
128
|
+
- Prompts: diagnose, deploy, security audit and project inspection
|
|
129
|
+
- `plugin_list` / `plugin_install` / `plugin_remove`
|
|
130
|
+
|
|
108
131
|
## CLI (`ramcp`)
|
|
109
132
|
|
|
110
133
|
| Command | Subcommands / flags | Notes |
|
|
@@ -150,3 +173,12 @@ persist via `saveConfig` and hot-reload; they cannot touch other tokens.
|
|
|
150
173
|
Env overrides (tests, minimal deploys): `RAMCP_TOKEN RAMCP_HOST RAMCP_PORT
|
|
151
174
|
RAMCP_PUBLIC_HOST RAMCP_SHELL RAMCP_ALLOWED_PATHS RAMCP_DENIED_PATHS`
|
|
152
175
|
(legacy `DANA_*` still honored). `SSH_BIN` existed for fleet tests — gone.
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
### Approvals
|
|
179
|
+
|
|
180
|
+
Shell approvals are persisted under the data directory, survive gateway restarts, are bound to the exact command and working directory, record the approving token fingerprint, and are atomically consumed after one execution. An approval cannot be reused for another command.
|
|
181
|
+
|
|
182
|
+
### Plugins
|
|
183
|
+
|
|
184
|
+
Installed plugins must explicitly set `trusted: true`. Plugin entrypoints are constrained to remain inside their own plugin directory. Plugins are intentionally a trusted in-process extension point, not a security sandbox; do not install untrusted code.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-access-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "Turn any machine into a secure AI-agent-accessible endpoint via MCP. Connect ChatGPT, Claude, Grok, and other MCP clients to files, shell, git, services, and more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -82,5 +82,8 @@
|
|
|
82
82
|
"better-sqlite3@12.11.1": true,
|
|
83
83
|
"esbuild@0.28.2": true,
|
|
84
84
|
"esbuild@0.21.5": true
|
|
85
|
+
},
|
|
86
|
+
"overrides": {
|
|
87
|
+
"qs": ">=6.16.0"
|
|
85
88
|
}
|
|
86
89
|
}
|