remote-access-mcp 1.0.0

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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/cli/main.d.ts +2 -0
  4. package/dist/cli/main.d.ts.map +1 -0
  5. package/dist/cli/main.js +430 -0
  6. package/dist/cli/main.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +7 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/core/config.d.ts +17 -0
  12. package/dist/core/config.d.ts.map +1 -0
  13. package/dist/core/config.js +57 -0
  14. package/dist/core/config.js.map +1 -0
  15. package/dist/core/policy.d.ts +22 -0
  16. package/dist/core/policy.d.ts.map +1 -0
  17. package/dist/core/policy.js +66 -0
  18. package/dist/core/policy.js.map +1 -0
  19. package/dist/main.d.ts +3 -0
  20. package/dist/main.d.ts.map +1 -0
  21. package/dist/main.js +7 -0
  22. package/dist/main.js.map +1 -0
  23. package/dist/server/app.d.ts +7 -0
  24. package/dist/server/app.d.ts.map +1 -0
  25. package/dist/server/app.js +95 -0
  26. package/dist/server/app.js.map +1 -0
  27. package/dist/server/run.d.ts +2 -0
  28. package/dist/server/run.d.ts.map +1 -0
  29. package/dist/server/run.js +25 -0
  30. package/dist/server/run.js.map +1 -0
  31. package/dist/tools/filesystem.d.ts +5 -0
  32. package/dist/tools/filesystem.d.ts.map +1 -0
  33. package/dist/tools/filesystem.js +155 -0
  34. package/dist/tools/filesystem.js.map +1 -0
  35. package/dist/tools/git.d.ts +4 -0
  36. package/dist/tools/git.d.ts.map +1 -0
  37. package/dist/tools/git.js +33 -0
  38. package/dist/tools/git.js.map +1 -0
  39. package/dist/tools/http.d.ts +3 -0
  40. package/dist/tools/http.d.ts.map +1 -0
  41. package/dist/tools/http.js +70 -0
  42. package/dist/tools/http.js.map +1 -0
  43. package/dist/tools/index.d.ts +5 -0
  44. package/dist/tools/index.d.ts.map +1 -0
  45. package/dist/tools/index.js +17 -0
  46. package/dist/tools/index.js.map +1 -0
  47. package/dist/tools/policy.d.ts +4 -0
  48. package/dist/tools/policy.d.ts.map +1 -0
  49. package/dist/tools/policy.js +52 -0
  50. package/dist/tools/policy.js.map +1 -0
  51. package/dist/tools/shell.d.ts +4 -0
  52. package/dist/tools/shell.d.ts.map +1 -0
  53. package/dist/tools/shell.js +73 -0
  54. package/dist/tools/shell.js.map +1 -0
  55. package/dist/tools/sqlite.d.ts +4 -0
  56. package/dist/tools/sqlite.d.ts.map +1 -0
  57. package/dist/tools/sqlite.js +57 -0
  58. package/dist/tools/sqlite.js.map +1 -0
  59. package/dist/tools/system.d.ts +3 -0
  60. package/dist/tools/system.d.ts.map +1 -0
  61. package/dist/tools/system.js +56 -0
  62. package/dist/tools/system.js.map +1 -0
  63. package/install.sh +79 -0
  64. package/package.json +63 -0
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import crypto from 'node:crypto';
5
+ const CONFIG_DIR = path.join(os.homedir(), '.config', 'remote-access-mcp');
6
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
7
+ export function configDir() {
8
+ return CONFIG_DIR;
9
+ }
10
+ export function configPath() {
11
+ return CONFIG_FILE;
12
+ }
13
+ function resolveEnvFile() {
14
+ // Back-compat: Dana-style .env next to cwd — only read explicitly, never write.
15
+ const legacy = path.join(process.cwd(), '.env');
16
+ if (fs.existsSync(legacy))
17
+ return legacy;
18
+ return '';
19
+ }
20
+ export function loadConfig() {
21
+ let cfg = {};
22
+ if (fs.existsSync(CONFIG_FILE)) {
23
+ cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
24
+ }
25
+ // Environment overrides (RAMCP_* / legacy DANA_* for parity with the old gateway)
26
+ const env = process.env;
27
+ const envToken = env.RAMCP_TOKEN || env.DANA_AUTH_TOKEN;
28
+ const envHost = env.RAMCP_HOST || env.DANA_HOST;
29
+ const envPort = env.RAMCP_PORT || env.DANA_PORT;
30
+ const envPublic = env.RAMCP_PUBLIC_HOST || env.DANA_PUBLIC_HOST;
31
+ const resolved = {
32
+ token: envToken || cfg.token || '',
33
+ host: envHost || cfg.host || '127.0.0.1',
34
+ port: envPort ? parseInt(envPort, 10) : (cfg.port || 8765),
35
+ public_host: envPublic || cfg.public_host || '',
36
+ mcp_path: cfg.mcp_path || '/mcp',
37
+ shell_enabled: cfg.shell_enabled ?? false,
38
+ allowed_paths: cfg.allowed_paths || [],
39
+ denied_paths: cfg.denied_paths || [],
40
+ };
41
+ return resolved;
42
+ }
43
+ export function saveConfig(cfg) {
44
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
45
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(cfg, null, 2) + '\n', { mode: 0o600 });
46
+ }
47
+ export function generateToken() {
48
+ return crypto.randomBytes(36).toString('base64url');
49
+ }
50
+ export function requireToken(cfg) {
51
+ if (!cfg.token) {
52
+ console.error('No token configured. Run `ramcp init` first.');
53
+ process.exit(1);
54
+ }
55
+ return cfg.token;
56
+ }
57
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface PolicyConfig {
2
+ allowed_paths: string[];
3
+ denied_paths: string[];
4
+ shell_enabled: boolean;
5
+ }
6
+ /** Thrown by tools when a target path is outside the policy sandbox. */
7
+ export declare class PolicyError extends Error {
8
+ readonly target: string;
9
+ constructor(target: string);
10
+ }
11
+ /**
12
+ * Resolve a path the way the tools will actually touch it:
13
+ * absolute, symlink-free where possible, `..` collapsed.
14
+ * For not-yet-existing targets (write case), the deepest existing ancestor
15
+ * is resolved and the remainder re-attached — symlinked parents still collapse.
16
+ */
17
+ export declare function resolveReal(p: string): string;
18
+ export declare function isPathAllowed(policy: PolicyConfig, p: string): boolean;
19
+ /** Policy gate for filesystem tools — throws PolicyError when refused. */
20
+ export declare function assertAllowed(policy: PolicyConfig, p: string): void;
21
+ export declare function shellAllowed(policy: PolicyConfig): boolean;
22
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/core/policy.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wEAAwE;AACxE,qBAAa,WAAY,SAAQ,KAAK;aACR,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;CAI3C;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAiB7C;AAQD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAUtE;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAEnE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAE1D"}
@@ -0,0 +1,66 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /** Thrown by tools when a target path is outside the policy sandbox. */
4
+ export class PolicyError extends Error {
5
+ target;
6
+ constructor(target) {
7
+ super(`Access to ${target} is not allowed by the path policy`);
8
+ this.target = target;
9
+ this.name = 'PolicyError';
10
+ }
11
+ }
12
+ /**
13
+ * Resolve a path the way the tools will actually touch it:
14
+ * absolute, symlink-free where possible, `..` collapsed.
15
+ * For not-yet-existing targets (write case), the deepest existing ancestor
16
+ * is resolved and the remainder re-attached — symlinked parents still collapse.
17
+ */
18
+ export function resolveReal(p) {
19
+ const abs = path.resolve(p);
20
+ try {
21
+ return fs.realpathSync(abs);
22
+ }
23
+ catch {
24
+ let dir = abs;
25
+ const parts = [];
26
+ while (dir !== '/' && !fs.existsSync(dir)) {
27
+ parts.unshift(path.basename(dir));
28
+ dir = path.dirname(dir);
29
+ }
30
+ try {
31
+ return path.join(fs.realpathSync(dir), ...parts);
32
+ }
33
+ catch {
34
+ return abs;
35
+ }
36
+ }
37
+ }
38
+ function isWithin(child, ancestor) {
39
+ if (child === ancestor)
40
+ return true;
41
+ const a = ancestor.endsWith('/') ? ancestor : ancestor + '/';
42
+ return child.startsWith(a);
43
+ }
44
+ export function isPathAllowed(policy, p) {
45
+ const real = resolveReal(p);
46
+ for (const deny of policy.denied_paths) {
47
+ if (isWithin(real, resolveReal(deny)))
48
+ return false;
49
+ }
50
+ if (policy.allowed_paths.length === 0)
51
+ return false;
52
+ for (const allow of policy.allowed_paths) {
53
+ if (isWithin(real, resolveReal(allow)))
54
+ return true;
55
+ }
56
+ return false;
57
+ }
58
+ /** Policy gate for filesystem tools — throws PolicyError when refused. */
59
+ export function assertAllowed(policy, p) {
60
+ if (!isPathAllowed(policy, p))
61
+ throw new PolicyError(p);
62
+ }
63
+ export function shellAllowed(policy) {
64
+ return policy.shell_enabled;
65
+ }
66
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/core/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,wEAAwE;AACxE,MAAM,OAAO,WAAY,SAAQ,KAAK;IACR;IAA5B,YAA4B,MAAc;QACxC,KAAK,CAAC,aAAa,MAAM,oCAAoC,CAAC,CAAC;QADrC,WAAM,GAAN,MAAM,CAAQ;QAExC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,GAAG,GAAG,CAAC;QACd,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAClC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,GAAG,CAAC;QACb,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,QAAgB;IAC/C,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC;IAC7D,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,CAAS;IAC3D,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACvC,IAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzC,IAAI,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,CAAS;IAC3D,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;QAAE,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,OAAO,MAAM,CAAC,aAAa,CAAC;AAC9B,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/dist/main.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from './cli/main.js';
3
+ main(process.argv.slice(2)).catch((e) => {
4
+ console.error(e);
5
+ process.exit(1);
6
+ });
7
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import express from 'express';
2
+ import { type RamcpConfig } from '../core/config.js';
3
+ export declare function buildApp(): {
4
+ app: express.Express;
5
+ cfg: RamcpConfig;
6
+ };
7
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAAA,OAAO,OAA2D,MAAM,SAAS,CAAC;AAIlF,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIjE,wBAAgB,QAAQ,IAAI;IAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC;IAAC,GAAG,EAAE,WAAW,CAAA;CAAE,CA4FrE"}
@@ -0,0 +1,95 @@
1
+ import express from 'express';
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
+ import { loadConfig } from '../core/config.js';
5
+ import { registerAllTools } from '../tools/index.js';
6
+ export function buildApp() {
7
+ const cfg = loadConfig();
8
+ const policy = {
9
+ allowed_paths: cfg.allowed_paths,
10
+ denied_paths: cfg.denied_paths,
11
+ shell_enabled: cfg.shell_enabled,
12
+ };
13
+ const app = express();
14
+ // JSON bodies only. The MCP transport accepts a pre-parsed object —
15
+ // raw Buffers confuse it (it treats the Buffer itself as the message).
16
+ app.use(express.json({ limit: '64mb' }));
17
+ // ---- helpers --------------------------------------------------------------
18
+ function unauthorized(res, msg = 'Unauthorized') {
19
+ res.status(401).json({ error: msg });
20
+ }
21
+ function tokenFromAuthHeader(req) {
22
+ const h = req.headers.authorization;
23
+ if (!h)
24
+ return null;
25
+ const m = /^Bearer\s+(.+)$/i.exec(h);
26
+ return m ? m[1] : null;
27
+ }
28
+ // ---- health ----------------------------------------------------------------
29
+ app.get('/health', (_req, res) => {
30
+ res.json({ status: 'ok', service: 'remote-access-mcp', version: '1.0.0' });
31
+ });
32
+ // ---- connector -----------------------------------------------------------------
33
+ app.get('/connector', (req, res) => {
34
+ const token = tokenFromAuthHeader(req);
35
+ if (!token || token !== cfg.token)
36
+ return unauthorized(res);
37
+ const host = cfg.public_host || `127.0.0.1:${cfg.port}`;
38
+ const scheme = cfg.public_host ? 'https' : 'http';
39
+ res.json({
40
+ title: 'Chatbot Connection Link',
41
+ url: `${scheme}://${host}/${cfg.token}${cfg.mcp_path}`,
42
+ });
43
+ });
44
+ // ---- MCP handler (shared by both routes) ------------------------------------------
45
+ async function handleMcp(req, res) {
46
+ // Fresh server per request (stateless). Tools re-registered each time —
47
+ // policy mutation via tools takes effect on the very next request.
48
+ const server = new McpServer({ name: 'remote-access-mcp', version: '1.0.0' }, { capabilities: { tools: {} } });
49
+ registerAllTools(server, cfg, policy, () => { });
50
+ const transport = new StreamableHTTPServerTransport({
51
+ sessionIdGenerator: undefined, // stateless
52
+ enableJsonResponse: true,
53
+ });
54
+ res.on('close', () => {
55
+ transport.close().catch(() => { });
56
+ server.close().catch(() => { });
57
+ });
58
+ await server.connect(transport);
59
+ await transport.handleRequest(req, res, req.body);
60
+ }
61
+ // ---- canonical route: /mcp (Authorization header) ------------------------------------
62
+ app.all('/mcp', async (req, res, next) => {
63
+ try {
64
+ const token = tokenFromAuthHeader(req);
65
+ if (!token || token !== cfg.token)
66
+ return unauthorized(res);
67
+ await handleMcp(req, res);
68
+ }
69
+ catch (e) {
70
+ next(e);
71
+ }
72
+ });
73
+ // ---- token-in-path route: /<token>/mcp (ChatGPT-style) ----------------------------------
74
+ app.all('/:token/mcp', async (req, res, next) => {
75
+ try {
76
+ if (req.params.token !== cfg.token)
77
+ return unauthorized(res);
78
+ await handleMcp(req, res);
79
+ }
80
+ catch (e) {
81
+ next(e);
82
+ }
83
+ });
84
+ // ---- 404 + error -------------------------------------------------------------------
85
+ app.use((req, res) => {
86
+ res.status(404).json({ error: 'Not Found' });
87
+ });
88
+ app.use((err, _req, res, _next) => {
89
+ console.error('[gateway]', err);
90
+ if (!res.headersSent)
91
+ res.status(500).json({ error: 'Internal Server Error' });
92
+ });
93
+ return { app, cfg };
94
+ }
95
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runServer(): Promise<void>;
2
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/server/run.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB/C"}
@@ -0,0 +1,25 @@
1
+ import { createServer } from 'node:http';
2
+ import { loadConfig, requireToken } from '../core/config.js';
3
+ import { buildApp } from './app.js';
4
+ export async function runServer() {
5
+ const cfg = loadConfig();
6
+ requireToken(cfg);
7
+ const { app } = buildApp();
8
+ const httpServer = createServer(app);
9
+ httpServer.listen(cfg.port, cfg.host, () => {
10
+ const publicUrl = cfg.public_host
11
+ ? `https://${cfg.public_host}${cfg.mcp_path}`
12
+ : `http://${cfg.host}:${cfg.port}${cfg.mcp_path}`;
13
+ console.log(`remote-access-mcp listening on ${cfg.host}:${cfg.port}`);
14
+ console.log(`endpoint: ${publicUrl}`);
15
+ console.log(`stateless MCP over streamable HTTP — token auth required`);
16
+ });
17
+ const shutdown = () => {
18
+ console.log('\nshutting down...');
19
+ httpServer.close(() => process.exit(0));
20
+ setTimeout(() => process.exit(0), 3000).unref();
21
+ };
22
+ process.on('SIGINT', shutdown);
23
+ process.on('SIGTERM', shutdown);
24
+ }
25
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/server/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,YAAY,CAAC,GAAG,CAAC,CAAC;IAElB,MAAM,EAAE,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAErC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE;QACzC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW;YAC/B,CAAC,CAAC,WAAW,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,QAAQ,EAAE;YAC7C,CAAC,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,kCAAkC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IAClD,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { PolicyConfig, PolicyError } from '../core/policy.js';
3
+ export declare function registerFilesystemTools(server: McpServer, policy: PolicyConfig): void;
4
+ export { PolicyError };
5
+ //# sourceMappingURL=filesystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/tools/filesystem.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAiB,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAkJrF;AAGD,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,155 @@
1
+ import fs from 'node:fs';
2
+ import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { z } from 'zod';
5
+ import { assertAllowed, PolicyError } from '../core/policy.js';
6
+ export function registerFilesystemTools(server, policy) {
7
+ // ---- list_directory ---------------------------------------------------
8
+ server.registerTool('list_directory', {
9
+ description: 'List a directory. Policy-checked.',
10
+ inputSchema: { path: z.string().describe('Directory path') },
11
+ }, async ({ path: dir }) => {
12
+ assertAllowed(policy, dir);
13
+ const entries = await fsp.readdir(dir, { withFileTypes: true });
14
+ const lines = entries.map(e => {
15
+ const suffix = e.isDirectory() ? '/' : e.isSymbolicLink() ? '@' : '';
16
+ return `${e.name}${suffix}`;
17
+ });
18
+ return { content: [{ type: 'text', text: lines.length ? lines.join('\n') : '(empty)' }] };
19
+ });
20
+ // ---- read_file ---------------------------------------------------------
21
+ server.registerTool('read_file', {
22
+ description: 'Read a UTF-8 text file. Policy-checked.',
23
+ inputSchema: { path: z.string().describe('File path') },
24
+ }, async ({ path: file }) => {
25
+ assertAllowed(policy, file);
26
+ const data = await fsp.readFile(file, 'utf8');
27
+ return { content: [{ type: 'text', text: data }] };
28
+ });
29
+ // ---- write_file --------------------------------------------------------
30
+ server.registerTool('write_file', {
31
+ description: 'Create or overwrite a file with UTF-8 text content. Policy-checked.',
32
+ inputSchema: {
33
+ path: z.string().describe('File path'),
34
+ content: z.string().describe('Full file content'),
35
+ },
36
+ }, async ({ path: file, content }) => {
37
+ assertAllowed(policy, file);
38
+ await fsp.mkdir(path.dirname(file), { recursive: true });
39
+ await fsp.writeFile(file, content, 'utf8');
40
+ return { content: [{ type: 'text', text: `Wrote ${Buffer.byteLength(content)} bytes to ${file}` }] };
41
+ });
42
+ // ---- edit_file ---------------------------------------------------------
43
+ server.registerTool('edit_file', {
44
+ description: 'Replace exact text inside a file. Policy-checked.',
45
+ inputSchema: {
46
+ path: z.string().describe('File path'),
47
+ old_text: z.string().describe('Exact text to find'),
48
+ new_text: z.string().describe('Replacement text'),
49
+ all: z.boolean().optional().default(false).describe('Replace every occurrence'),
50
+ },
51
+ }, async ({ path: file, old_text, new_text, all }) => {
52
+ assertAllowed(policy, file);
53
+ const data = await fsp.readFile(file, 'utf8');
54
+ if (!data.includes(old_text)) {
55
+ return { content: [{ type: 'text', text: `old_text not found in ${file}` }], isError: true };
56
+ }
57
+ const updated = all ? data.split(old_text).join(new_text) : data.replace(old_text, new_text);
58
+ await fsp.writeFile(file, updated, 'utf8');
59
+ return { content: [{ type: 'text', text: `Edited ${file}` }] };
60
+ });
61
+ // ---- delete_path -------------------------------------------------------
62
+ server.registerTool('delete_path', {
63
+ description: 'Delete a file or a directory tree. Policy-checked. Destructive.',
64
+ inputSchema: { path: z.string().describe('Path to delete') },
65
+ }, async ({ path: target }) => {
66
+ assertAllowed(policy, target);
67
+ const st = fs.lstatSync(target);
68
+ if (st.isDirectory()) {
69
+ await fsp.rm(target, { recursive: true });
70
+ }
71
+ else {
72
+ await fsp.unlink(target);
73
+ }
74
+ return { content: [{ type: 'text', text: `Deleted ${target}` }] };
75
+ });
76
+ // ---- search_code --------------------------------------------------------
77
+ server.registerTool('search_code', {
78
+ description: 'Recursive regex search under a directory. Policy-checked. Returns file:line:match.',
79
+ inputSchema: {
80
+ path: z.string().describe('Directory to search'),
81
+ pattern: z.string().describe('JavaScript regex, e.g. "TODO|FIXME"'),
82
+ include: z.string().optional().describe('Glob filter for file names, e.g. "*.ts"'),
83
+ max_results: z.number().optional().default(100).describe('Cap on matches'),
84
+ },
85
+ }, async ({ path: dir, pattern, include, max_results }) => {
86
+ assertAllowed(policy, dir);
87
+ const re = new RegExp(pattern);
88
+ const results = [];
89
+ const walk = async (d) => {
90
+ if (results.length >= max_results)
91
+ return;
92
+ let entries;
93
+ try {
94
+ entries = await fsp.readdir(d, { withFileTypes: true });
95
+ }
96
+ catch {
97
+ return;
98
+ }
99
+ for (const e of entries) {
100
+ if (results.length >= max_results)
101
+ return;
102
+ if (e.name === '.git' || e.name === 'node_modules')
103
+ continue;
104
+ const full = path.join(d, e.name);
105
+ if (e.isDirectory()) {
106
+ await walk(full);
107
+ continue;
108
+ }
109
+ if (!e.isFile())
110
+ continue;
111
+ if (include) {
112
+ try {
113
+ if (!new RegExp(include.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*')).test(e.name))
114
+ continue;
115
+ }
116
+ catch { /* bad glob → no filter */ }
117
+ }
118
+ let content;
119
+ try {
120
+ content = await fsp.readFile(full, 'utf8');
121
+ }
122
+ catch {
123
+ continue;
124
+ }
125
+ const lines = content.split('\n');
126
+ for (let i = 0; i < lines.length && results.length < max_results; i++) {
127
+ if (re.test(lines[i]))
128
+ results.push(`${full}:${i + 1}:${lines[i].trim().slice(0, 200)}`);
129
+ }
130
+ }
131
+ };
132
+ await walk(dir);
133
+ return { content: [{ type: 'text', text: results.length ? results.join('\n') : 'No matches' }] };
134
+ });
135
+ // ---- file_info -----------------------------------------------------------
136
+ server.registerTool('file_info', {
137
+ description: 'Stat a file or directory: size, timestamps, permissions, owner. Policy-checked.',
138
+ inputSchema: { path: z.string().describe('Path') },
139
+ }, async ({ path: target }) => {
140
+ assertAllowed(policy, target);
141
+ const st = await fsp.stat(target);
142
+ const out = [
143
+ `path: ${target}`,
144
+ `type: ${st.isDirectory() ? 'directory' : 'file'}`,
145
+ `size: ${st.size}`,
146
+ `mode: ${(st.mode & 0o777).toString(8)}`,
147
+ `mtime: ${st.mtime.toISOString()}`,
148
+ `atime: ${st.atime.toISOString()}`,
149
+ ].join('\n');
150
+ return { content: [{ type: 'text', text: out }] };
151
+ });
152
+ }
153
+ // Re-export so tool modules share the same error surface.
154
+ export { PolicyError };
155
+ //# sourceMappingURL=filesystem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/tools/filesystem.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { PolicyConfig } from '../core/policy.js';
3
+ export declare function registerGitTools(server: McpServer, policy: PolicyConfig): void;
4
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,YAAY,EAAiB,MAAM,mBAAmB,CAAC;AAIhE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CA0B9E"}
@@ -0,0 +1,33 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { z } from 'zod';
4
+ import { assertAllowed } from '../core/policy.js';
5
+ const exec = promisify(execFile);
6
+ export function registerGitTools(server, policy) {
7
+ // ---- git ------------------------------------------------------------------------
8
+ server.registerTool('git', {
9
+ description: 'Run git commands in a repository. Policy-checked.',
10
+ inputSchema: {
11
+ repo_path: z.string().describe('Path to the git repository'),
12
+ args: z.array(z.string()).describe('Arguments to git, e.g. ["status", "--short"]'),
13
+ },
14
+ }, async ({ repo_path, args }) => {
15
+ assertAllowed(policy, repo_path);
16
+ try {
17
+ const { stdout, stderr } = await exec('git', args, {
18
+ cwd: repo_path,
19
+ timeout: 60_000,
20
+ maxBuffer: 10 * 1024 * 1024,
21
+ });
22
+ let out = stdout;
23
+ if (stderr)
24
+ out += (out ? '\n' : '') + stderr;
25
+ return { content: [{ type: 'text', text: out || '(no output)' }] };
26
+ }
27
+ catch (e) {
28
+ const msg = [e.message, e.stdout, e.stderr].filter(Boolean).join('\n');
29
+ return { content: [{ type: 'text', text: msg || e.message }], isError: true };
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/tools/git.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,EAAgB,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEjC,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAoB;IACtE,oFAAoF;IACpF,MAAM,CAAC,YAAY,CAAC,KAAK,EACvB;QACE,WAAW,EAAE,mDAAmD;QAChE,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC5D,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;SACnF;KACF,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5B,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;gBACjD,GAAG,EAAE,SAAS;gBACd,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;aAC5B,CAAC,CAAC;YACH,IAAI,GAAG,GAAG,MAAM,CAAC;YACjB,IAAI,MAAM;gBAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,aAAa,EAAE,CAAC,EAAE,CAAC;QACrE,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAChF,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerHttpTools(server: McpServer): void;
3
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/tools/http.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqEzD"}