just-bash-mcp 2.9.5 → 3.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.
- package/README.md +33 -7
- package/package.json +3 -2
- package/src/config/index.ts +346 -326
- package/src/index.ts +8 -12
- package/src/tools/bash-instance.ts +66 -131
- package/src/tools/exec-tools.ts +92 -139
- package/src/tools/file-tools.ts +89 -182
- package/src/tools/index.ts +19 -27
- package/src/tools/info-tools.ts +103 -135
- package/src/tools/sandbox-tools.ts +114 -209
- package/src/types.ts +1 -1
- package/src/utils/index.ts +20 -55
package/src/tools/file-tools.ts
CHANGED
|
@@ -3,204 +3,111 @@
|
|
|
3
3
|
* Tools for reading, writing, and listing files in the bash environment
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
6
|
+
import type {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
7
|
+
import {z} from 'zod/v4'
|
|
8
|
+
import {config} from '../config/index.ts'
|
|
9
|
+
import {createErrorResponse, createSuccessResponse, truncateOutput} from '../utils/index.ts'
|
|
10
|
+
import {getPersistentBash} from './bash-instance.ts'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Register file operation tools with the MCP server
|
|
14
14
|
*/
|
|
15
15
|
export function registerFileTools(server: McpServer): void {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
path: z.string().describe("The file path to write to"),
|
|
25
|
-
content: z.string().describe("The content to write"),
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
async ({ path, content }: { path: string; content: string }) => {
|
|
29
|
-
try {
|
|
30
|
-
const bash = getPersistentBash();
|
|
31
|
-
const escapedContent = content.replace(/'/g, "'\\''");
|
|
32
|
-
const result = await bash.exec(
|
|
33
|
-
`mkdir -p "$(dirname '${path}')" && cat > '${path}' << 'JUST_BASH_EOF'\n${escapedContent}\nJUST_BASH_EOF`,
|
|
34
|
-
);
|
|
16
|
+
// ========================================================================
|
|
17
|
+
// bash_write_file - Write file via shell
|
|
18
|
+
// ========================================================================
|
|
19
|
+
server.registerTool('bash_write_file', {description: 'Write content to a file in the persistent bash environment.', inputSchema: {path: z.string().describe('The file path to write to'), content: z.string().describe('The content to write')}}, async ({path, content}: {path: string; content: string}) => {
|
|
20
|
+
try {
|
|
21
|
+
const bash = getPersistentBash()
|
|
22
|
+
const escapedContent = content.replace(/'/g, "'\\''")
|
|
23
|
+
const result = await bash.exec(`mkdir -p "$(dirname '${path}')" && cat > '${path}' << 'JUST_BASH_EOF'\n${escapedContent}\nJUST_BASH_EOF`)
|
|
35
24
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
type: "text" as const,
|
|
41
|
-
text: `Failed to write file: ${result.stderr}`,
|
|
42
|
-
},
|
|
43
|
-
],
|
|
44
|
-
isError: true,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
25
|
+
if (result.exitCode !== 0) {
|
|
26
|
+
return {content: [{type: 'text' as const, text: `Failed to write file: ${result.stderr}`}], isError: true}
|
|
27
|
+
}
|
|
47
28
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
);
|
|
29
|
+
return createSuccessResponse(`Successfully wrote ${content.length} bytes to ${path}`)
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return createErrorResponse(error, 'Write error')
|
|
32
|
+
}
|
|
33
|
+
})
|
|
54
34
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
inputSchema: {
|
|
63
|
-
path: z.string().describe("The file path to read"),
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
async ({ path }: { path: string }) => {
|
|
67
|
-
try {
|
|
68
|
-
const bash = getPersistentBash();
|
|
69
|
-
const result = await bash.exec(`cat '${path}'`);
|
|
35
|
+
// ========================================================================
|
|
36
|
+
// bash_read_file - Read file via shell
|
|
37
|
+
// ========================================================================
|
|
38
|
+
server.registerTool('bash_read_file', {description: 'Read content from a file in the persistent bash environment.', inputSchema: {path: z.string().describe('The file path to read')}}, async ({path}: {path: string}) => {
|
|
39
|
+
try {
|
|
40
|
+
const bash = getPersistentBash()
|
|
41
|
+
const result = await bash.exec(`cat '${path}'`)
|
|
70
42
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
type: "text" as const,
|
|
76
|
-
text: `Failed to read file: ${result.stderr}`,
|
|
77
|
-
},
|
|
78
|
-
],
|
|
79
|
-
isError: true,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
43
|
+
if (result.exitCode !== 0) {
|
|
44
|
+
return {content: [{type: 'text' as const, text: `Failed to read file: ${result.stderr}`}], isError: true}
|
|
45
|
+
}
|
|
82
46
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
};
|
|
91
|
-
} catch (error) {
|
|
92
|
-
return createErrorResponse(error, "Read error");
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
);
|
|
47
|
+
return {content: [{type: 'text' as const, text: truncateOutput(result.stdout, config.MAX_OUTPUT_LENGTH, 'stdout')}]}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return createErrorResponse(error, 'Read error')
|
|
50
|
+
}
|
|
51
|
+
})
|
|
96
52
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
showHidden: z.boolean().optional().describe("Whether to show hidden files"),
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
async ({
|
|
114
|
-
path = ".",
|
|
115
|
-
recursive = false,
|
|
116
|
-
showHidden = false,
|
|
117
|
-
}: {
|
|
118
|
-
path?: string;
|
|
119
|
-
recursive?: boolean;
|
|
120
|
-
showHidden?: boolean;
|
|
121
|
-
}) => {
|
|
122
|
-
try {
|
|
123
|
-
const bash = getPersistentBash();
|
|
124
|
-
let cmd: string;
|
|
53
|
+
// ========================================================================
|
|
54
|
+
// bash_list_files - List files
|
|
55
|
+
// ========================================================================
|
|
56
|
+
server.registerTool(
|
|
57
|
+
'bash_list_files',
|
|
58
|
+
{
|
|
59
|
+
description: 'List files and directories in the persistent bash environment.',
|
|
60
|
+
inputSchema: {path: z.string().optional().describe('The directory path to list (defaults to current directory)'), recursive: z.boolean().optional().describe('Whether to list recursively'), showHidden: z.boolean().optional().describe('Whether to show hidden files')}
|
|
61
|
+
},
|
|
62
|
+
async ({path = '.', recursive = false, showHidden = false}: {path?: string; recursive?: boolean; showHidden?: boolean}) => {
|
|
63
|
+
try {
|
|
64
|
+
const bash = getPersistentBash()
|
|
65
|
+
let cmd: string
|
|
125
66
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
cmd = showHidden ? `ls -la '${path}'` : `ls -l '${path}'`;
|
|
132
|
-
}
|
|
67
|
+
if (recursive) {
|
|
68
|
+
cmd = showHidden ? `find '${path}' -type f` : `find '${path}' -type f ! -name '.*' ! -path '*/.*'`
|
|
69
|
+
} else {
|
|
70
|
+
cmd = showHidden ? `ls -la '${path}'` : `ls -l '${path}'`
|
|
71
|
+
}
|
|
133
72
|
|
|
134
|
-
|
|
73
|
+
const result = await bash.exec(cmd)
|
|
135
74
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
],
|
|
143
|
-
isError: result.exitCode !== 0,
|
|
144
|
-
};
|
|
145
|
-
} catch (error) {
|
|
146
|
-
return createErrorResponse(error, "List error");
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
);
|
|
75
|
+
return {content: [{type: 'text' as const, text: result.stdout || '(empty directory)'}], isError: result.exitCode !== 0}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return createErrorResponse(error, 'List error')
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
)
|
|
150
81
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"Read a file directly from the persistent bash filesystem (without running cat).",
|
|
159
|
-
inputSchema: {
|
|
160
|
-
path: z.string().describe("The file path to read"),
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
async ({ path }: { path: string }) => {
|
|
164
|
-
try {
|
|
165
|
-
const bash = getPersistentBash();
|
|
166
|
-
const content = await bash.readFile(path);
|
|
82
|
+
// ========================================================================
|
|
83
|
+
// bash_direct_read - Direct filesystem read
|
|
84
|
+
// ========================================================================
|
|
85
|
+
server.registerTool('bash_direct_read', {description: 'Read a file directly from the persistent bash filesystem (without running cat).', inputSchema: {path: z.string().describe('The file path to read')}}, async ({path}: {path: string}) => {
|
|
86
|
+
try {
|
|
87
|
+
const bash = getPersistentBash()
|
|
88
|
+
const content = await bash.readFile(path)
|
|
167
89
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
};
|
|
176
|
-
} catch (error) {
|
|
177
|
-
return createErrorResponse(error, "Read error");
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
);
|
|
90
|
+
return {content: [{type: 'text' as const, text: truncateOutput(content, config.MAX_OUTPUT_LENGTH, 'stdout')}]}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return createErrorResponse(error, 'Read error')
|
|
93
|
+
}
|
|
94
|
+
})
|
|
181
95
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
content: z.string().describe("The content to write"),
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
async ({ path, content }: { path: string; content: string }) => {
|
|
196
|
-
try {
|
|
197
|
-
const bash = getPersistentBash();
|
|
198
|
-
await bash.writeFile(path, content);
|
|
96
|
+
// ========================================================================
|
|
97
|
+
// bash_direct_write - Direct filesystem write
|
|
98
|
+
// ========================================================================
|
|
99
|
+
server.registerTool(
|
|
100
|
+
'bash_direct_write',
|
|
101
|
+
{description: 'Write a file directly to the persistent bash filesystem (without running shell commands).', inputSchema: {path: z.string().describe('The file path to write'), content: z.string().describe('The content to write')}},
|
|
102
|
+
async ({path, content}: {path: string; content: string}) => {
|
|
103
|
+
try {
|
|
104
|
+
const bash = getPersistentBash()
|
|
105
|
+
await bash.writeFile(path, content)
|
|
199
106
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
107
|
+
return createSuccessResponse(`Successfully wrote ${content.length} bytes to ${path}`)
|
|
108
|
+
} catch (error) {
|
|
109
|
+
return createErrorResponse(error, 'Write error')
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
)
|
|
206
113
|
}
|
package/src/tools/index.ts
CHANGED
|
@@ -3,43 +3,35 @@
|
|
|
3
3
|
* Aggregates and exports all MCP tools
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
7
|
+
import {registerExecTools} from './exec-tools.ts'
|
|
8
|
+
import {registerFileTools} from './file-tools.ts'
|
|
9
|
+
import {registerInfoTools} from './info-tools.ts'
|
|
10
|
+
import {registerSandboxTools} from './sandbox-tools.ts'
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
import { registerFileTools } from "./file-tools.ts";
|
|
10
|
-
import { registerInfoTools } from "./info-tools.ts";
|
|
11
|
-
import { registerSandboxTools } from "./sandbox-tools.ts";
|
|
12
|
+
export {setJavaScriptToolHandler} from '../config/index.ts'
|
|
12
13
|
|
|
13
14
|
// Re-export bash instance utilities
|
|
14
|
-
export {
|
|
15
|
-
createBashInstance,
|
|
16
|
-
defineCommand,
|
|
17
|
-
getDefenseInDepthBox,
|
|
18
|
-
getPersistentBash,
|
|
19
|
-
getPersistentSandbox,
|
|
20
|
-
resetPersistentBash,
|
|
21
|
-
resetPersistentSandbox,
|
|
22
|
-
violationLogger,
|
|
23
|
-
} from "./bash-instance.ts";
|
|
15
|
+
export {createBashInstance, defineCommand, getDefenseInDepthBox, getPersistentBash, getPersistentSandbox, resetPersistentBash, resetPersistentSandbox, violationLogger} from './bash-instance.ts'
|
|
24
16
|
// Re-export individual registrations for fine-grained control
|
|
25
|
-
export {
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
17
|
+
export {registerExecTools} from './exec-tools.ts'
|
|
18
|
+
export {registerFileTools} from './file-tools.ts'
|
|
19
|
+
export {registerInfoTools} from './info-tools.ts'
|
|
20
|
+
export {registerSandboxTools} from './sandbox-tools.ts'
|
|
29
21
|
|
|
30
22
|
/**
|
|
31
23
|
* Register all MCP tools with the server
|
|
32
24
|
*/
|
|
33
25
|
export function registerAllTools(server: McpServer): void {
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
// Core execution tools
|
|
27
|
+
registerExecTools(server)
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
29
|
+
// File operation tools
|
|
30
|
+
registerFileTools(server)
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
// Additional persistent sandbox tools
|
|
33
|
+
registerSandboxTools(server)
|
|
42
34
|
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
// Information and state tools
|
|
36
|
+
registerInfoTools(server)
|
|
45
37
|
}
|
package/src/tools/info-tools.ts
CHANGED
|
@@ -6,152 +6,120 @@
|
|
|
6
6
|
* SecurityViolationLogger for defense-in-depth violation reporting.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
getNetworkCommandNames,
|
|
15
|
-
getPythonCommandNames,
|
|
16
|
-
} from "just-bash";
|
|
17
|
-
import {
|
|
18
|
-
buildExecutionLimits,
|
|
19
|
-
COMMAND_CATEGORIES,
|
|
20
|
-
config,
|
|
21
|
-
ENVIRONMENT_VARIABLES,
|
|
22
|
-
FEATURES,
|
|
23
|
-
parseMountsConfig,
|
|
24
|
-
UPSTREAM_JUST_BASH_VERSION,
|
|
25
|
-
violationLogger,
|
|
26
|
-
} from "../config/index.ts";
|
|
27
|
-
import { createErrorResponse, createJsonResponse } from "../utils/index.ts";
|
|
28
|
-
import { getDefenseInDepthBox, getPersistentBash } from "./bash-instance.ts";
|
|
9
|
+
import type {McpServer} from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
10
|
+
import {type AllCommandName, type CommandName, getCommandNames, getJavaScriptCommandNames, getNetworkCommandNames, getPythonCommandNames} from 'just-bash'
|
|
11
|
+
import {buildExecutionLimits, COMMAND_CATEGORIES, config, ENVIRONMENT_VARIABLES, FEATURES, parseMountsConfig, UPSTREAM_JUST_BASH_VERSION, violationLogger} from '../config/index.ts'
|
|
12
|
+
import {createErrorResponse, createJsonResponse} from '../utils/index.ts'
|
|
13
|
+
import {getDefenseInDepthBox, getPersistentBash} from './bash-instance.ts'
|
|
29
14
|
|
|
30
15
|
/**
|
|
31
16
|
* Register information tools with the MCP server
|
|
32
17
|
*/
|
|
33
18
|
export function registerInfoTools(server: McpServer): void {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
description: "Get information about the bash environment configuration.",
|
|
41
|
-
inputSchema: {},
|
|
42
|
-
},
|
|
43
|
-
async () => {
|
|
44
|
-
const mounts = parseMountsConfig();
|
|
45
|
-
const fsMode =
|
|
46
|
-
mounts.length > 0
|
|
47
|
-
? "mountable"
|
|
48
|
-
: config.READ_WRITE_ROOT
|
|
49
|
-
? "read-write"
|
|
50
|
-
: config.OVERLAY_ROOT
|
|
51
|
-
? "overlay"
|
|
52
|
-
: "in-memory";
|
|
19
|
+
// ========================================================================
|
|
20
|
+
// bash_info - Environment information
|
|
21
|
+
// ========================================================================
|
|
22
|
+
server.registerTool('bash_info', {description: 'Get information about the bash environment configuration.', inputSchema: {}}, async () => {
|
|
23
|
+
const mounts = parseMountsConfig()
|
|
24
|
+
const fsMode = mounts.length > 0 ? 'mountable' : config.READ_WRITE_ROOT ? 'read-write' : config.OVERLAY_ROOT ? 'overlay' : 'in-memory'
|
|
53
25
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
? allBuiltinCommands.filter((cmd) =>
|
|
58
|
-
config.ALLOWED_COMMANDS?.includes(cmd as AllCommandName as CommandName),
|
|
59
|
-
)
|
|
60
|
-
: allBuiltinCommands;
|
|
26
|
+
// Get actual available commands (respects ALLOWED_COMMANDS filter)
|
|
27
|
+
const allBuiltinCommands = getCommandNames()
|
|
28
|
+
const availableCommands = config.ALLOWED_COMMANDS ? allBuiltinCommands.filter(cmd => config.ALLOWED_COMMANDS?.includes(cmd as AllCommandName as CommandName)) : allBuiltinCommands
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
total: violationLogger.getTotalCount(),
|
|
75
|
-
hasViolations: violationLogger.hasViolations(),
|
|
76
|
-
summary: violationLogger.getSummary(),
|
|
77
|
-
},
|
|
78
|
-
}
|
|
79
|
-
: { enabled: false };
|
|
30
|
+
// Build defense-in-depth status with violation stats
|
|
31
|
+
const didBox = getDefenseInDepthBox()
|
|
32
|
+
const defenseInDepthStatus = config.ENABLE_DEFENSE_IN_DEPTH
|
|
33
|
+
? {
|
|
34
|
+
enabled: true,
|
|
35
|
+
auditMode: config.DEFENSE_IN_DEPTH_AUDIT,
|
|
36
|
+
consoleLogging: config.DEFENSE_IN_DEPTH_LOG,
|
|
37
|
+
boxActive: didBox?.isActive() ?? false,
|
|
38
|
+
...(didBox && {stats: didBox.getStats()}),
|
|
39
|
+
violations: {total: violationLogger.getTotalCount(), hasViolations: violationLogger.hasViolations(), summary: violationLogger.getSummary()}
|
|
40
|
+
}
|
|
41
|
+
: {enabled: false}
|
|
80
42
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
43
|
+
const info = {
|
|
44
|
+
version: config.VERSION,
|
|
45
|
+
upstreamVersion: UPSTREAM_JUST_BASH_VERSION,
|
|
46
|
+
fsMode,
|
|
47
|
+
fsRoot: config.READ_WRITE_ROOT || config.OVERLAY_ROOT || null,
|
|
48
|
+
overlayReadOnly: config.OVERLAY_ROOT ? config.OVERLAY_READ_ONLY : null,
|
|
49
|
+
mounts: mounts.length > 0 ? mounts.map(m => ({mountPoint: m.mountPoint})) : null,
|
|
50
|
+
initialCwd: config.INITIAL_CWD,
|
|
51
|
+
networkEnabled: config.ALLOW_NETWORK,
|
|
52
|
+
allowedUrlPrefixes: config.ALLOWED_URL_PREFIXES.length > 0 ? config.ALLOWED_URL_PREFIXES : null,
|
|
53
|
+
allowedMethods: config.ALLOW_NETWORK ? config.ALLOWED_METHODS : null,
|
|
54
|
+
maxResponseSize: config.MAX_RESPONSE_SIZE ?? null,
|
|
55
|
+
maxOutputLength: config.MAX_OUTPUT_LENGTH,
|
|
56
|
+
maxFileReadSize: config.MAX_FILE_READ_SIZE ?? null,
|
|
57
|
+
loggingEnabled: config.ENABLE_LOGGING,
|
|
58
|
+
tracingEnabled: config.ENABLE_TRACING,
|
|
59
|
+
pythonEnabled: config.ENABLE_PYTHON,
|
|
60
|
+
javascriptEnabled: config.ENABLE_JAVASCRIPT,
|
|
61
|
+
javascriptBootstrapConfigured: config.JAVASCRIPT_BOOTSTRAP !== undefined,
|
|
62
|
+
defenseInDepth: defenseInDepthStatus,
|
|
63
|
+
commandFilter: config.ALLOWED_COMMANDS || null,
|
|
64
|
+
mcpTools: [
|
|
65
|
+
'bash',
|
|
66
|
+
'bash_exec',
|
|
67
|
+
'bash_exec_persistent',
|
|
68
|
+
'bash_reset',
|
|
69
|
+
'bash_write_file',
|
|
70
|
+
'bash_read_file',
|
|
71
|
+
'bash_list_files',
|
|
72
|
+
'bash_direct_read',
|
|
73
|
+
'bash_direct_write',
|
|
74
|
+
'bash_sandbox_run',
|
|
75
|
+
'bash_sandbox_domain',
|
|
76
|
+
'bash_sandbox_write_files',
|
|
77
|
+
'bash_sandbox_read_file',
|
|
78
|
+
'bash_sandbox_mkdir',
|
|
79
|
+
'bash_sandbox_stop',
|
|
80
|
+
'bash_sandbox_reset',
|
|
81
|
+
'bash_info',
|
|
82
|
+
'bash_get_cwd',
|
|
83
|
+
'bash_get_env'
|
|
84
|
+
],
|
|
85
|
+
executionLimits: buildExecutionLimits(),
|
|
86
|
+
availableCommands,
|
|
87
|
+
networkCommands: config.ALLOW_NETWORK ? getNetworkCommandNames() : [],
|
|
88
|
+
pythonCommands: config.ENABLE_PYTHON ? getPythonCommandNames() : [],
|
|
89
|
+
javascriptCommands: config.ENABLE_JAVASCRIPT ? getJavaScriptCommandNames() : [],
|
|
90
|
+
commandCategories: COMMAND_CATEGORIES,
|
|
91
|
+
features: FEATURES,
|
|
92
|
+
environmentVariables: ENVIRONMENT_VARIABLES
|
|
93
|
+
}
|
|
109
94
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
);
|
|
95
|
+
return createJsonResponse(info)
|
|
96
|
+
})
|
|
113
97
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
inputSchema: {},
|
|
122
|
-
},
|
|
123
|
-
async () => {
|
|
124
|
-
try {
|
|
125
|
-
const bash = getPersistentBash();
|
|
126
|
-
const cwd = bash.getCwd();
|
|
98
|
+
// ========================================================================
|
|
99
|
+
// bash_get_cwd - Get current working directory
|
|
100
|
+
// ========================================================================
|
|
101
|
+
server.registerTool('bash_get_cwd', {description: 'Get the current working directory of the persistent bash environment.', inputSchema: {}}, async () => {
|
|
102
|
+
try {
|
|
103
|
+
const bash = getPersistentBash()
|
|
104
|
+
const cwd = bash.getCwd()
|
|
127
105
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
);
|
|
106
|
+
return {content: [{type: 'text' as const, text: cwd}]}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return createErrorResponse(error)
|
|
109
|
+
}
|
|
110
|
+
})
|
|
136
111
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
inputSchema: {},
|
|
145
|
-
},
|
|
146
|
-
async () => {
|
|
147
|
-
try {
|
|
148
|
-
const bash = getPersistentBash();
|
|
149
|
-
const env = bash.getEnv();
|
|
112
|
+
// ========================================================================
|
|
113
|
+
// bash_get_env - Get environment variables
|
|
114
|
+
// ========================================================================
|
|
115
|
+
server.registerTool('bash_get_env', {description: 'Get all environment variables from the persistent bash environment.', inputSchema: {}}, async () => {
|
|
116
|
+
try {
|
|
117
|
+
const bash = getPersistentBash()
|
|
118
|
+
const env = bash.getEnv()
|
|
150
119
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
120
|
+
return createJsonResponse(env)
|
|
121
|
+
} catch (error) {
|
|
122
|
+
return createErrorResponse(error)
|
|
123
|
+
}
|
|
124
|
+
})
|
|
157
125
|
}
|