Commit bfb3211
Add shell command interception and approval support (#51)
* Add shell command interception and approval support
Add shell_cmd_handler parameter to KernelClient and CodeExecutor for
intercepting IPython ! and !! shell commands. Add approve_shell_cmds
flag that routes shell commands through the ToolServer approval flow.
Traceback output is rewritten to show !cmd syntax instead of internal
get_ipython().system() calls, and handler frames are filtered out.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Add configurable blocking of direct subprocess/os.system calls
Add block_direct_shell parameter to KernelClient and CodeExecutor.
When enabled, patches subprocess.Popen and os.system in the kernel
to raise RuntimeError unless called from the ! shell handler. Uses
a ContextVar to track the guard state.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Refactor kernel init into dedicated module and add tests
- Extract kernel init code generation to ipybox/kernel_mgr/init.py with
triple-quoted string constants and build_init_code() function
- Simplify KernelClient._init_kernel to thin wrapper over build_init_code
- Remove shell_cmd_handler param; hardcode approval handler in init module
- Rename block_direct_shell to require_shell_escape
- Fix docstrings to use Markdown backticks instead of rST double backticks
- Add unit tests for build_init_code and _rewrite_traceback
- Add integration tests for approve_shell_cmds and require_shell_escape
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Add approve_tool_calls parameter to CodeExecutor
Exposes ToolServer's approval_required as a CodeExecutor constructor
arg (default True), allowing callers to disable MCP tool call approval.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Rewrite documentation to focus on unified execution model
Shift narrative from "Python code execution sandbox with MCP tool calling"
to "unified execution environment for Python code, shell commands and
programmatic MCP tool calls." Update intro, capabilities, quickstart,
architecture, and code execution docs to cover shell command execution,
shell command approval, and preventing approval bypass. Add example
snippets for new features.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Remove unused examples/intercept.py
Functionality is covered by snippets in codexec.py and quickstart.py.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Refine documentation wording and structure
Replace "unified execution model" with "unified execution interface" across
all files. Restructure codeexec.md approval sections under a single heading
with tool calls and shell commands as subsections. Add tool calls section
before approval. Update internal docs for new modules and shell command flow.
Align README, mkdocs.yml, and server.json with index.md intro.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Fix documentation inconsistencies with codebase
- CLAUDE.md: IpyboxMCPServer → MCPServer (matches actual class name)
- mcpserver.md: execute_ipython_cell timeout default "no timeout" → 120
- mcpserver.md: Brave Search npm package and GitHub URL to match quickstart
- mcpserver.md: grammar fix ("use" → "uses")
- mcp_server.py: {API_KEY} → ${API_KEY} in docstring
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Refocus documentation on unified execution model
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Upgrade mcpygen to 0.1.4 and switch from local editable to registry
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
* Fix format_map KeyError, add shell rejection test, extend subprocess guards
- Use _ipybox_safe_dict (dict subclass with __missing__) so shell commands
with {undefined_var} show the literal placeholder in the approval request
instead of raising KeyError
- Add integration test for shell command rejection (reject() flow)
- Add integration test for undefined variable in shell commands
- Extend subprocess guard to os.exec*, os.spawn*, os.posix_spawn*, pty.spawn
- Add ValueError when require_shell_escape=True without approve_shell_cmds
- Update docs and docstrings to reflect extended guard coverage
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>1 parent 2ea848f commit bfb3211
27 files changed
Lines changed: 979 additions & 203 deletions
File tree
- docs
- images
- internal
- examples
- ipybox
- kernel_mgr
- tests
- integration
- unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
20 | 24 | | |
21 | 25 | | |
22 | 26 | | |
| |||
34 | 38 | | |
35 | 39 | | |
36 | 40 | | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
45 | 49 | | |
46 | 50 | | |
47 | 51 | | |
| |||
51 | 55 | | |
52 | 56 | | |
53 | 57 | | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | 58 | | |
61 | | - | |
| 59 | + | |
62 | 60 | | |
63 | | - | |
| 61 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
16 | 16 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
3 | 5 | | |
4 | 6 | | |
5 | 7 | | |
6 | 8 | | |
7 | | - | |
8 | | - | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
22 | 38 | | |
23 | 39 | | |
24 | 40 | | |
25 | 41 | | |
26 | 42 | | |
27 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
28 | 69 | | |
29 | 70 | | |
30 | 71 | | |
| |||
34 | 75 | | |
35 | 76 | | |
36 | 77 | | |
37 | | - | |
| 78 | + | |
38 | 79 | | |
39 | 80 | | |
40 | 81 | | |
41 | | - | |
| 82 | + | |
42 | 83 | | |
43 | 84 | | |
44 | 85 | | |
| |||
59 | 100 | | |
60 | 101 | | |
61 | 102 | | |
62 | | - | |
| 103 | + | |
63 | 104 | | |
64 | 105 | | |
65 | 106 | | |
| |||
71 | 112 | | |
72 | 113 | | |
73 | 114 | | |
74 | | - | |
| 115 | + | |
75 | 116 | | |
76 | 117 | | |
77 | 118 | | |
78 | 119 | | |
79 | 120 | | |
80 | 121 | | |
81 | 122 | | |
82 | | - | |
| 123 | + | |
83 | 124 | | |
84 | | - | |
85 | | - | |
86 | | - | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
87 | 128 | | |
88 | 129 | | |
89 | 130 | | |
| |||
Loading
Binary file not shown.
Binary file not shown.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
8 | 12 | | |
9 | 13 | | |
10 | 14 | | |
11 | 15 | | |
12 | 16 | | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
21 | 25 | | |
22 | 26 | | |
23 | 27 | | |
| |||
27 | 31 | | |
28 | 32 | | |
29 | 33 | | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 34 | + | |
37 | 35 | | |
38 | | - | |
| 36 | + | |
0 commit comments