@true-and-useful/janee 0.8.3 → 0.8.5
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/README.md +82 -2
- package/dist/cli/commands/add.d.ts +5 -0
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +91 -5
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/serve-mcp.d.ts.map +1 -1
- package/dist/cli/commands/serve-mcp.js +41 -1
- package/dist/cli/commands/serve-mcp.js.map +1 -1
- package/dist/cli/commands/status.d.ts +4 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +127 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/config-yaml.d.ts +18 -0
- package/dist/cli/config-yaml.d.ts.map +1 -1
- package/dist/cli/config-yaml.js +28 -1
- package/dist/cli/config-yaml.js.map +1 -1
- package/dist/cli/index.js +11 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/agent-scope.d.ts +81 -0
- package/dist/core/agent-scope.d.ts.map +1 -0
- package/dist/core/agent-scope.js +146 -0
- package/dist/core/agent-scope.js.map +1 -0
- package/dist/core/exec.d.ts +86 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +149 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/health.d.ts +27 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +73 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/mcp-server.d.ts +13 -0
- package/dist/core/mcp-server.d.ts.map +1 -1
- package/dist/core/mcp-server.js +299 -11
- package/dist/core/mcp-server.js.map +1 -1
- package/dist/core/sessions.d.ts.map +1 -1
- package/dist/core/sessions.js +11 -1
- package/dist/core/sessions.js.map +1 -1
- package/dist/providers/env.d.ts +27 -0
- package/dist/providers/env.d.ts.map +1 -0
- package/dist/providers/env.js +64 -0
- package/dist/providers/env.js.map +1 -0
- package/dist/providers/filesystem.d.ts +34 -0
- package/dist/providers/filesystem.d.ts.map +1 -0
- package/dist/providers/filesystem.js +143 -0
- package/dist/providers/filesystem.js.map +1 -0
- package/dist/providers/index.d.ts +25 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +39 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/registry.d.ts +40 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +113 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/types.d.ts +137 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +135 -0
- package/dist/providers/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Secure CLI Execution for Janee (RFC 0001)
|
|
4
|
+
*
|
|
5
|
+
* Executes CLI commands with credentials injected via environment variables.
|
|
6
|
+
* The agent specifies the command to run but never sees the actual credential.
|
|
7
|
+
* Janee's core security property is preserved: agent never sees the key.
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.validateCommand = validateCommand;
|
|
14
|
+
exports.buildExecEnv = buildExecEnv;
|
|
15
|
+
exports.scrubCredentials = scrubCredentials;
|
|
16
|
+
exports.executeCommand = executeCommand;
|
|
17
|
+
const child_process_1 = require("child_process");
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
/**
|
|
20
|
+
* Validate that a command is allowed by the capability's whitelist
|
|
21
|
+
*/
|
|
22
|
+
function validateCommand(command, allowCommands) {
|
|
23
|
+
if (!command || command.length === 0) {
|
|
24
|
+
return { allowed: false, reason: 'Empty command' };
|
|
25
|
+
}
|
|
26
|
+
const executable = path_1.default.basename(command[0]);
|
|
27
|
+
if (!allowCommands.includes(executable)) {
|
|
28
|
+
return {
|
|
29
|
+
allowed: false,
|
|
30
|
+
reason: `Command '${executable}' not allowed by capability. Allowed: ${allowCommands.join(', ')}`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Check for shell injection patterns in arguments
|
|
34
|
+
const shellMetachars = /[;&|`$(){}\\<>]/;
|
|
35
|
+
for (let i = 1; i < command.length; i++) {
|
|
36
|
+
if (shellMetachars.test(command[i])) {
|
|
37
|
+
return {
|
|
38
|
+
allowed: false,
|
|
39
|
+
reason: `Argument ${i} contains shell metacharacters. Use structured arguments instead of shell syntax.`
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { allowed: true };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build environment variables for command execution.
|
|
47
|
+
* Replaces {{credential}} placeholders with the actual secret.
|
|
48
|
+
* Replaces {{apiKey}} and {{apiSecret}} for HMAC-style auth.
|
|
49
|
+
*/
|
|
50
|
+
function buildExecEnv(envTemplate, credential, extraCredentials) {
|
|
51
|
+
const env = {};
|
|
52
|
+
for (const [key, value] of Object.entries(envTemplate)) {
|
|
53
|
+
let resolved = value;
|
|
54
|
+
resolved = resolved.replace(/{{credential}}/g, credential);
|
|
55
|
+
if (extraCredentials?.apiKey) {
|
|
56
|
+
resolved = resolved.replace(/{{apiKey}}/g, extraCredentials.apiKey);
|
|
57
|
+
}
|
|
58
|
+
if (extraCredentials?.apiSecret) {
|
|
59
|
+
resolved = resolved.replace(/{{apiSecret}}/g, extraCredentials.apiSecret);
|
|
60
|
+
}
|
|
61
|
+
if (extraCredentials?.passphrase) {
|
|
62
|
+
resolved = resolved.replace(/{{passphrase}}/g, extraCredentials.passphrase);
|
|
63
|
+
}
|
|
64
|
+
env[key] = resolved;
|
|
65
|
+
}
|
|
66
|
+
return env;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Scrub credential values from output strings.
|
|
70
|
+
* Prevents accidental credential leakage in stdout/stderr.
|
|
71
|
+
*/
|
|
72
|
+
function scrubCredentials(output, credential, extraCredentials) {
|
|
73
|
+
let scrubbed = output;
|
|
74
|
+
// Only scrub if credential is long enough to be meaningful
|
|
75
|
+
if (credential && credential.length >= 8) {
|
|
76
|
+
scrubbed = scrubbed.replaceAll(credential, '[REDACTED]');
|
|
77
|
+
}
|
|
78
|
+
if (extraCredentials?.apiKey && extraCredentials.apiKey.length >= 8) {
|
|
79
|
+
scrubbed = scrubbed.replaceAll(extraCredentials.apiKey, '[REDACTED]');
|
|
80
|
+
}
|
|
81
|
+
if (extraCredentials?.apiSecret && extraCredentials.apiSecret.length >= 8) {
|
|
82
|
+
scrubbed = scrubbed.replaceAll(extraCredentials.apiSecret, '[REDACTED]');
|
|
83
|
+
}
|
|
84
|
+
if (extraCredentials?.passphrase && extraCredentials.passphrase.length >= 8) {
|
|
85
|
+
scrubbed = scrubbed.replaceAll(extraCredentials.passphrase, '[REDACTED]');
|
|
86
|
+
}
|
|
87
|
+
return scrubbed;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute a CLI command with injected credentials.
|
|
91
|
+
* Returns stdout/stderr/exitCode without exposing the credential.
|
|
92
|
+
*/
|
|
93
|
+
async function executeCommand(command, injectedEnv, options) {
|
|
94
|
+
const timeout = options.timeout || 30000;
|
|
95
|
+
const startTime = Date.now();
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const proc = (0, child_process_1.spawn)(command[0], command.slice(1), {
|
|
98
|
+
env: {
|
|
99
|
+
...process.env, // Inherit base env
|
|
100
|
+
...injectedEnv, // Override with injected credentials
|
|
101
|
+
// Safety: prevent credential exfil via common env vars
|
|
102
|
+
HISTFILE: '/dev/null',
|
|
103
|
+
LESSHISTFILE: '/dev/null',
|
|
104
|
+
},
|
|
105
|
+
cwd: options.workDir || '/tmp/janee-exec',
|
|
106
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
107
|
+
timeout,
|
|
108
|
+
// Don't use shell — prevents injection
|
|
109
|
+
shell: false,
|
|
110
|
+
});
|
|
111
|
+
let stdout = '';
|
|
112
|
+
let stderr = '';
|
|
113
|
+
proc.stdout.on('data', (data) => {
|
|
114
|
+
stdout += data.toString();
|
|
115
|
+
});
|
|
116
|
+
proc.stderr.on('data', (data) => {
|
|
117
|
+
stderr += data.toString();
|
|
118
|
+
});
|
|
119
|
+
if (options.stdin) {
|
|
120
|
+
proc.stdin.write(options.stdin);
|
|
121
|
+
proc.stdin.end();
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
proc.stdin.end();
|
|
125
|
+
}
|
|
126
|
+
proc.on('close', (code) => {
|
|
127
|
+
const executionTimeMs = Date.now() - startTime;
|
|
128
|
+
// Scrub credentials from output
|
|
129
|
+
const scrubbedStdout = scrubCredentials(stdout, options.credential, options.extraCredentials);
|
|
130
|
+
const scrubbedStderr = scrubCredentials(stderr, options.credential, options.extraCredentials);
|
|
131
|
+
resolve({
|
|
132
|
+
stdout: scrubbedStdout,
|
|
133
|
+
stderr: scrubbedStderr,
|
|
134
|
+
exitCode: code ?? 1,
|
|
135
|
+
executionTimeMs,
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
proc.on('error', (error) => {
|
|
139
|
+
const executionTimeMs = Date.now() - startTime;
|
|
140
|
+
resolve({
|
|
141
|
+
stdout: '',
|
|
142
|
+
stderr: `Failed to execute command: ${error.message}`,
|
|
143
|
+
exitCode: 127,
|
|
144
|
+
executionTimeMs,
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check module for Janee services
|
|
3
|
+
* Provides connectivity and latency checks for configured API backends
|
|
4
|
+
*/
|
|
5
|
+
export interface HealthCheckResult {
|
|
6
|
+
service: string;
|
|
7
|
+
healthy: boolean;
|
|
8
|
+
statusCode?: number;
|
|
9
|
+
latencyMs: number;
|
|
10
|
+
error?: string;
|
|
11
|
+
checkedAt: string;
|
|
12
|
+
}
|
|
13
|
+
export interface HealthCheckOptions {
|
|
14
|
+
timeout?: number;
|
|
15
|
+
fetchFn?: typeof fetch;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if a service endpoint is reachable and responding
|
|
19
|
+
*/
|
|
20
|
+
export declare function checkServiceHealth(serviceName: string, baseUrl: string, options?: HealthCheckOptions): Promise<HealthCheckResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Check health of multiple services in parallel
|
|
23
|
+
*/
|
|
24
|
+
export declare function checkAllServicesHealth(services: Map<string, {
|
|
25
|
+
baseUrl: string;
|
|
26
|
+
}>, options?: HealthCheckOptions): Promise<HealthCheckResult[]>;
|
|
27
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/core/health.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CA6D5B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1C,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAK9B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Health check module for Janee services
|
|
4
|
+
* Provides connectivity and latency checks for configured API backends
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.checkServiceHealth = checkServiceHealth;
|
|
8
|
+
exports.checkAllServicesHealth = checkAllServicesHealth;
|
|
9
|
+
/**
|
|
10
|
+
* Check if a service endpoint is reachable and responding
|
|
11
|
+
*/
|
|
12
|
+
async function checkServiceHealth(serviceName, baseUrl, options = {}) {
|
|
13
|
+
const { timeout = 5000, fetchFn = fetch } = options;
|
|
14
|
+
const checkedAt = new Date().toISOString();
|
|
15
|
+
if (!baseUrl) {
|
|
16
|
+
return {
|
|
17
|
+
service: serviceName,
|
|
18
|
+
healthy: false,
|
|
19
|
+
latencyMs: 0,
|
|
20
|
+
error: 'No base URL configured',
|
|
21
|
+
checkedAt
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const start = Date.now();
|
|
25
|
+
try {
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
28
|
+
const response = await fetchFn(baseUrl, {
|
|
29
|
+
method: 'HEAD',
|
|
30
|
+
signal: controller.signal
|
|
31
|
+
});
|
|
32
|
+
clearTimeout(timeoutId);
|
|
33
|
+
const latencyMs = Date.now() - start;
|
|
34
|
+
// 2xx = healthy, 401/403 = reachable (auth expected), 4xx = unhealthy, 5xx = unhealthy
|
|
35
|
+
const isReachable = response.ok || response.status === 401 || response.status === 403;
|
|
36
|
+
if (isReachable) {
|
|
37
|
+
return {
|
|
38
|
+
service: serviceName,
|
|
39
|
+
healthy: true,
|
|
40
|
+
statusCode: response.status,
|
|
41
|
+
latencyMs,
|
|
42
|
+
checkedAt
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
service: serviceName,
|
|
47
|
+
healthy: false,
|
|
48
|
+
statusCode: response.status,
|
|
49
|
+
latencyMs,
|
|
50
|
+
error: `HTTP ${response.status} ${response.statusText}`,
|
|
51
|
+
checkedAt
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
const latencyMs = Date.now() - start;
|
|
56
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
57
|
+
return {
|
|
58
|
+
service: serviceName,
|
|
59
|
+
healthy: false,
|
|
60
|
+
latencyMs,
|
|
61
|
+
error: message,
|
|
62
|
+
checkedAt
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check health of multiple services in parallel
|
|
68
|
+
*/
|
|
69
|
+
async function checkAllServicesHealth(services, options = {}) {
|
|
70
|
+
const checks = Array.from(services.entries()).map(([name, config]) => checkServiceHealth(name, config.baseUrl, options));
|
|
71
|
+
return Promise.all(checks);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/core/health.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAmBH,gDAiEC;AAKD,wDAQC;AAjFD;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,OAAe,EACf,UAA8B,EAAE;IAEhC,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,CAAC;YACZ,KAAK,EAAE,wBAAwB;YAC/B,SAAS;SACV,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE;YACtC,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAErC,uFAAuF;QACvF,MAAM,WAAW,GAAG,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;QAEtF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO;gBACL,OAAO,EAAE,WAAW;gBACpB,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,QAAQ,CAAC,MAAM;gBAC3B,SAAS;gBACT,SAAS;aACV,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,QAAQ,CAAC,MAAM;YAC3B,SAAS;YACT,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE;YACvD,SAAS;SACV,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrC,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjE,OAAO;YACL,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,KAAK;YACd,SAAS;YACT,KAAK,EAAE,OAAO;YACd,SAAS;SACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,sBAAsB,CAC1C,QAA0C,EAC1C,UAA8B,EAAE;IAEhC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CACnE,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAClD,CAAC;IACF,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -7,6 +7,8 @@ import { SessionManager } from './sessions.js';
|
|
|
7
7
|
import { Rules } from './rules.js';
|
|
8
8
|
import { AuditLogger } from './audit.js';
|
|
9
9
|
import { URL } from 'url';
|
|
10
|
+
import { ExecResult } from './exec.js';
|
|
11
|
+
import { CredentialOwnership } from './agent-scope.js';
|
|
10
12
|
export interface Capability {
|
|
11
13
|
name: string;
|
|
12
14
|
service: string;
|
|
@@ -14,6 +16,11 @@ export interface Capability {
|
|
|
14
16
|
autoApprove?: boolean;
|
|
15
17
|
requiresReason?: boolean;
|
|
16
18
|
rules?: Rules;
|
|
19
|
+
mode?: 'proxy' | 'exec';
|
|
20
|
+
allowCommands?: string[];
|
|
21
|
+
env?: Record<string, string>;
|
|
22
|
+
workDir?: string;
|
|
23
|
+
timeout?: number;
|
|
17
24
|
}
|
|
18
25
|
export interface ServiceConfig {
|
|
19
26
|
baseUrl: string;
|
|
@@ -27,6 +34,8 @@ export interface ServiceConfig {
|
|
|
27
34
|
credentials?: string;
|
|
28
35
|
scopes?: string[];
|
|
29
36
|
};
|
|
37
|
+
/** Ownership metadata for agent-scoped credential access control */
|
|
38
|
+
ownership?: CredentialOwnership;
|
|
30
39
|
}
|
|
31
40
|
export interface APIRequest {
|
|
32
41
|
service: string;
|
|
@@ -47,10 +56,14 @@ export interface ReloadResult {
|
|
|
47
56
|
export interface MCPServerOptions {
|
|
48
57
|
capabilities: Capability[];
|
|
49
58
|
services: Map<string, ServiceConfig>;
|
|
59
|
+
/** Map of service name -> ownership metadata for agent-scoped access control */
|
|
50
60
|
sessionManager: SessionManager;
|
|
51
61
|
auditLogger: AuditLogger;
|
|
52
62
|
onExecute: (session: any, request: APIRequest) => Promise<APIResponse>;
|
|
63
|
+
onExecCommand?: (session: any, capability: Capability, command: string[], stdin?: string) => Promise<ExecResult>;
|
|
53
64
|
onReloadConfig?: () => ReloadResult;
|
|
65
|
+
/** Persist ownership changes to config storage (called after grant/revoke) */
|
|
66
|
+
onPersistOwnership?: (serviceName: string, ownership: CredentialOwnership) => void;
|
|
54
67
|
}
|
|
55
68
|
/**
|
|
56
69
|
* Create and start MCP server
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/core/mcp-server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAQnE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAc,KAAK,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/core/mcp-server.ts"],"names":[],"mappings":"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"}
|