Skip to content

Commit 4ee467a

Browse files
authored
Merge pull request #12 from instavm/skills
WHAT'S NEW Skills System - Added Skills framework for extending CodeRunner with reusable, shareable capabilities - Skills are Python scripts with markdown documentation that can be installed and used via MCP - New SKILLS-README.md with comprehensive documentation on creating and using skills Built-in Skills - image-crop-rotate: Crop and rotate images with precise control - pdf-text-replace: Search and replace text in PDF documents while preserving formatting Infrastructure Changes - Enhanced Dockerfile with additional dependencies for image processing (opencv-python, pillow) and PDF manipulation (PyMuPDF, reportlab) - Updated install.sh to copy skills directory to ~/.coderunner/assets/ - Extended server.py with skills discovery, loading, and tool registration (201 new lines) - Added 45 new Python dependencies in requirements.txt for skills support Documentation - Added Gemini CLI system instructions in examples/gemini_cli/GEMINI.md - Updated README.md with Skills section and usage examples - Documented skills architecture and contribution guidelines Bug Fixes - Fixed container DNS configuration (removed obsolete 'container dns default' command) Key Components: - Skills discovery from ~/.coderunner/assets/skills and container's /app/skills - Dynamic MCP tool registration for each skill - Validation of skill structure (SKILL.md + scripts directory) - Support for both public and custom skills Testing: - Verified with smiley creator GIF generation - Tested DOCX and PPTX file handling with markdown fetching - Validated image crop/rotate and PDF text replacement skills
2 parents 5de0695 + 4f131c4 commit 4ee467a

File tree

11 files changed

+858
-11
lines changed

11 files changed

+858
-11
lines changed

Dockerfile

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
4141
libgbm1 \
4242
libxshmfence1 \
4343
libasound2 \
44+
unzip \
45+
p7zip-full \
46+
bc \
47+
ripgrep \
48+
fd-find \
49+
sqlite3 \
50+
libsqlite3-dev \
51+
wkhtmltopdf \
52+
poppler-utils \
53+
default-jre \
4454
&& apt-get clean && rm -rf /var/lib/apt/lists/*
4555

4656

@@ -64,6 +74,12 @@ COPY ./server.py /app/server.py
6474
# Create application/jupyter directories
6575
RUN mkdir -p /app/uploads /app/jupyter_runtime
6676

77+
# Copy skills directory structure into the container
78+
# Public skills are baked into the image
79+
# User skills directory is created as mount point for user-added skills
80+
COPY ./skills/public /app/uploads/skills/public
81+
RUN mkdir -p /app/uploads/skills/user
82+
6783
# # Generate SSH host keys
6884
# RUN ssh-keygen -A
6985

@@ -81,20 +97,26 @@ EXPOSE 8222
8197
# Start the FastAPI application
8298
# CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8002", "--workers", "1", "--no-access-log"]
8399

100+
RUN apt-get --fix-broken install
101+
# Ensure Node.js, npm (and npx) are set up
102+
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
103+
RUN apt-get install -y nodejs
104+
105+
106+
107+
ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
108+
RUN npm install [email protected] -g
109+
RUN npx [email protected] install
84110

85111
# Copy the entrypoint script into the image
86112
COPY entrypoint.sh /entrypoint.sh
87113

88114
# Make the entrypoint script executable
89115
RUN chmod +x /entrypoint.sh
90116

91-
# Ensure Node.js, npm (and npx) are set up
92-
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
93-
RUN apt-get install -y nodejs
94117

95-
ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
96-
RUN npm install [email protected] -g
97-
RUN npx [email protected] install
118+
119+
98120

99121

100122
# Use the entrypoint script

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,77 @@ Code runs in an isolated container with VM-level isolation. Your host system and
178178
From [@apple/container](https://github.com/apple/container/blob/main/docs/technical-overview.md):
179179
>Each container has the isolation properties of a full VM, using a minimal set of core utilities and dynamic libraries to reduce resource utilization and attack surface.
180180
181+
## Skills System
182+
183+
CodeRunner includes a built-in skills system that provides pre-packaged tools for common tasks. Skills are organized into two categories:
184+
185+
### Built-in Public Skills
186+
187+
The following skills are included in every CodeRunner installation:
188+
189+
- **pdf-text-replace** - Replace text in fillable PDF forms
190+
- **image-crop-rotate** - Crop and rotate images
191+
192+
### Using Skills
193+
194+
Skills are accessed through MCP tools:
195+
196+
```python
197+
# List all available skills
198+
result = await list_skills()
199+
200+
# Get documentation for a specific skill
201+
info = await get_skill_info("pdf-text-replace")
202+
203+
# Execute a skill's script
204+
code = """
205+
import subprocess
206+
subprocess.run([
207+
'python',
208+
'/app/uploads/skills/public/pdf-text-replace/scripts/replace_text_in_pdf.py',
209+
'/app/uploads/input.pdf',
210+
'OLD TEXT',
211+
'NEW TEXT',
212+
'/app/uploads/output.pdf'
213+
])
214+
"""
215+
result = await execute_python_code(code)
216+
```
217+
218+
### Adding Custom Skills
219+
220+
Users can add their own skills to the `~/.coderunner/assets/skills/user/` directory:
221+
222+
1. Create a directory for your skill (e.g., `my-custom-skill/`)
223+
2. Add a `SKILL.md` file with documentation
224+
3. Add your scripts in a `scripts/` subdirectory
225+
4. Skills will be automatically discovered by the `list_skills()` tool
226+
227+
**Skill Structure:**
228+
```
229+
~/.coderunner/assets/skills/user/my-custom-skill/
230+
├── SKILL.md # Documentation with usage examples
231+
└── scripts/ # Your Python/bash scripts
232+
└── process.py
233+
```
234+
235+
### Example: Using the PDF Text Replace Skill
236+
237+
```bash
238+
# Inside the container, execute:
239+
python /app/uploads/skills/public/pdf-text-replace/scripts/replace_text_in_pdf.py \
240+
/app/uploads/tax_form.pdf \
241+
"John Doe" \
242+
"Jane Smith" \
243+
/app/uploads/tax_form_updated.pdf
244+
```
245+
181246
## Architecture
182247

183248
CodeRunner consists of:
184249
- **Sandbox Container:** Isolated execution environment with Jupyter kernel
185250
- **MCP Server:** Handles communication between AI models and the sandbox
251+
- **Skills System:** Pre-packaged tools for common tasks (PDF manipulation, image processing, etc.)
186252

187253
## Examples
188254

SKILLS-README.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Skills powered by coderunner, running locally on your Mac
2+
3+
> [!NOTE]
4+
> [CodeRunner](https://github.com/instavm/coderunner) executes AI-generated code in a truly isolated sandboxed environment on your Mac using Apple's native containers.
5+
6+
# Pre-requisite
7+
* `Mac` with a `M-series` chip.
8+
* Install the latest`coderunner` by running the `./install.sh` script from the main repository.
9+
```shell
10+
./install.sh
11+
```
12+
13+
# How To Use Skills
14+
* `coderunner` is exposed as an MCP and can be connected to tools like `gemini cli` or `qwen cli` or `claude desktop` or anything that supports MCP. The execution is completely local, done on your Mac.
15+
16+
*For example, for Gemini CLI, you can edit* `~/.gemini/settings.json`
17+
```json
18+
{
19+
"theme": "Default",
20+
"selectedAuthType": "oauth-personal",
21+
"mcpServers": {
22+
"coderunner": {
23+
"httpUrl": "http://coderunner.local:8222/mcp"
24+
}
25+
}
26+
}
27+
```
28+
29+
And for system instructions, replace the `~/.gemini/GEMINI.md` with the [GEMINI.md](https://github.com/instavm/coderunner/examples/gemini/GEMINI.md)
30+
31+
32+
# How To Add New Skills
33+
34+
## Option 1: Import from Claude
35+
36+
You can either download and copy the folder from Anthropic skills's [github repo](https://github.com/anthropics/skills/) to `~/.coderunner/assets/skills/user/<new-skill-folder>`
37+
38+
For example, I have added 4 skills in the user folder as:
39+
```shell
40+
/Users/manish/.coderunner/assets/skills/
41+
├── public
42+
│ ├── image-crop-rotate
43+
│ │ ├── scripts
44+
│ │ └── SKILL.md
45+
│ └── pdf-text-replace
46+
│ ├── scripts
47+
│ └── SKILL.md
48+
└── user
49+
├── docx
50+
│ ├── docx-js.md
51+
│ ├── LICENSE.txt
52+
│ ├── ooxml
53+
│ ├── ooxml.md
54+
│ ├── scripts
55+
│ └── SKILL.md
56+
├── pptx
57+
│ ├── html2pptx.md
58+
│ ├── LICENSE.txt
59+
│ ├── ooxml
60+
│ ├── ooxml.md
61+
│ ├── scripts
62+
│ └── SKILL.md
63+
├── slack-gif-creator
64+
│ ├── core
65+
│ ├── LICENSE.txt
66+
│ ├── requirements.txt
67+
│ ├── SKILL.md
68+
│ └── templates
69+
└── xlsx
70+
├── LICENSE.txt
71+
├── recalc.py
72+
└── SKILL.md
73+
```
74+
75+
76+
## Option 2: Write Your Own Skills
77+
78+
* You can create a folder in the similar structure as above, where only mandatory file is the `SKILL.md`. [Docs](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview)
79+
* You can also ask claude to generate one like `Can you write a skill which creates ascii art of words given one.`
80+
After it creates the skill, it will let you download a `ZIP` file which you can place directly (no need to expand) in `~/.coderunner/assets/skills/user`
81+
82+
Test drive with Gemini CLI
83+
84+
```
85+
> /mcp
86+
87+
Configured MCP servers:
88+
89+
🟢 coderunner - Ready (5 tools)
90+
Tools:
91+
- execute_python_code
92+
- get_skill_file
93+
- get_skill_info
94+
- list_skills
95+
- navigate_and_get_all_visible_text
96+
97+
> can you generate ascii art for "CODERUNNER"
98+
99+
✦ I will generate the ASCII art you desire. First, I must survey my available skills.
100+
✓ list_skills (coderunner MCP Server)
101+
102+
✦ I have located a relevant skill: ascii-art. I will now retrieve its instructions.
103+
✓ get_skill_info (coderunner MCP Server) {"skill_name":"ascii-art"}
104+
✦ Your ASCII art is ready:
105+
106+
1 ____ ___ ____ _____ ____ _ _ _ _ _ _ _____ ____
107+
2 / ___/ _ \| _ \| ____| _ \| | | | \ | | \ | | ____| _ \
108+
3 | | | | | | | | | _| | |_) | | | | \| | \| | _| | |_) |
109+
4 | |__| |_| | |_| | |___| _ <| |_| | |\\ | |\\ | |___| _ <
110+
5 \____\___/|____/|_____|_| \_\\___/|_| \_|_| \_|_____|_| \_\
111+
6
112+
113+
114+
115+
116+
Using: 1 GEMINI.md file | 3 MCP servers (ctrl+t to view)
117+
```

examples/gemini_cli/GEMINI.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
always start answer by calling me lord voldemort.
2+
3+
So, we are currently on macbook, and whenever required we use tool to execute codes (in a jupyter like server). the code is executed in a container (you wouldn't notice but just know this).
4+
5+
The paths on local machine is ~/.coderunner/assets/skills/user is mapped to /app/uploads/skills/user inside container.
6+
7+
~/.coderunner/assets/outputs (in the host machine) is mapped to /app/uploads/outputs inside conatiner. This is where user will puts their files they want to edit like some png, pdf, txt etc. You should also use it to output your artifacts generated.
8+
9+
So that will help whenever we need a file inside a container to work on it via the execute code tool.
10+
11+
There are also "skills" which can do jobs by executing scripts already residing in /app/uploads/skills/<public|user>/<skill-name> . There are tools available to check what skills are avaialble, after checking you can decide wchihc specific skill you wantg to use and then get info about that skill using tool. That will have instructions on how to call execute code with stuff like `!python /path/to/script.py <input> <output>`\
12+
13+
Whenever I ask you to do a task, alwasys check if there are skills available in the list which can do it.
14+
15+
Whenever you need to install something, mostly it will be installed in teh container via execute code tool, and `!pip install pyfiglet` command etc.
16+

install.sh

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ else
1919
echo "✅ macOS system detected."
2020
fi
2121

22-
download_url="https://github.com/apple/container/releases/download/0.3.0/container-0.3.0-installer-signed.pkg"
22+
download_url="https://github.com/apple/container/releases/download/0.5.0/container-0.5.0-installer-signed.pkg"
2323

2424
# Check if container is installed and display its version
2525
if command -v container &> /dev/null
@@ -57,7 +57,7 @@ echo "Running: sudo container system dns create local"
5757
sudo container system dns create local
5858

5959
echo "Running: container system dns default set local"
60-
container system dns default set local
60+
container system property set dns.domain local
6161

6262
echo "Starting the Sandbox Container..."
6363
container system start
@@ -66,12 +66,21 @@ container system start
6666
echo "Pulling the latest image: instavm/coderunner"
6767
container image pull instavm/coderunner
6868

69-
echo "→ Ensuring coderunner assets directory"
69+
echo "→ Ensuring coderunner assets directories"
7070
ASSETS_SRC="$HOME/.coderunner/assets"
71-
mkdir -p "$ASSETS_SRC"
71+
mkdir -p "$ASSETS_SRC/skills/user"
72+
mkdir -p "$ASSETS_SRC/outputs"
7273

7374
# Run the command to start the sandbox container
7475
echo "Running: container run --name coderunner --detach --rm --cpus 8 --memory 4g instavm/coderunner"
75-
container run --volume "$ASSETS_SRC:/app/uploads" --name coderunner --detach --rm --cpus 8 --memory 4g instavm/coderunner
76+
container run \
77+
--volume "$ASSETS_SRC/skills/user:/app/uploads/skills/user" \
78+
--volume "$ASSETS_SRC/outputs:/app/uploads/outputs" \
79+
--name coderunner \
80+
--detach \
81+
--rm \
82+
--cpus 8 \
83+
--memory 4g \
84+
instavm/coderunner
7685

7786
echo "✅ Setup complete. MCP server is available at http://coderunner.local:8222/mcp"

requirements.txt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,48 @@ fastmcp
3838
openai-agents
3939

4040
playwright==1.53.0
41+
42+
# Data Science Libraries
43+
pandas
44+
numpy
45+
scipy
46+
scikit-learn
47+
statsmodels
48+
49+
# Visualization Libraries
50+
matplotlib
51+
seaborn
52+
53+
# Image/Video I/O Libraries
54+
imageio
55+
imageio-ffmpeg
56+
57+
# File Processing Libraries
58+
pyarrow
59+
openpyxl
60+
xlsxwriter
61+
xlrd
62+
pillow
63+
python-pptx
64+
python-docx
65+
pypdf
66+
pdfplumber
67+
pypdfium2
68+
pdf2image
69+
pdfkit
70+
tabula-py
71+
reportlab[pycairo]
72+
img2pdf
73+
74+
# Math & Computing Libraries
75+
sympy
76+
mpmath
77+
78+
# Utilities
79+
tqdm
80+
python-dateutil
81+
pytz
82+
joblib
83+
84+
# Beautiful Soup for HTML parsing (already used in server.py)
85+
beautifulsoup4

0 commit comments

Comments
 (0)