Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libgbm1 \
libxshmfence1 \
libasound2 \
unzip \
p7zip-full \
bc \
ripgrep \
fd-find \
sqlite3 \
libsqlite3-dev \
wkhtmltopdf \
poppler-utils \
default-jre \
&& apt-get clean && rm -rf /var/lib/apt/lists/*


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

# Copy skills directory structure into the container
# Public skills are baked into the image
# User skills directory is created as mount point for user-added skills
COPY ./skills/public /app/uploads/skills/public
RUN mkdir -p /app/uploads/skills/user

# # Generate SSH host keys
# RUN ssh-keygen -A

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

RUN apt-get --fix-broken install

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The RUN apt-get --fix-broken install command is concerning. It lacks the -y flag, which will cause it to fail in non-interactive Docker builds by waiting for user confirmation. Additionally, its presence suggests an underlying issue with package dependencies that should ideally be resolved directly, rather than patched with --fix-broken. If this command is essential, please add the -y flag.

RUN apt-get --fix-broken install -y

# Ensure Node.js, npm (and npx) are set up
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
RUN apt-get install -y nodejs
Comment on lines +102 to +103

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To optimize the Docker image by reducing the number of layers, you can chain the curl command for the Node.js setup script and the apt-get install command into a single RUN instruction.

RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && apt-get install -y nodejs




ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
RUN npm install playwright@1.53.0 -g
RUN npx playwright@1.53.0 install
Comment on lines +108 to +109

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the Node.js installation, you can combine the npm install and npx playwright install commands into a single RUN instruction. This will reduce the number of layers in the Docker image, leading to a smaller image size and potentially faster builds.

RUN npm install playwright@1.53.0 -g && npx playwright@1.53.0 install


# Copy the entrypoint script into the image
COPY entrypoint.sh /entrypoint.sh

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

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

ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
RUN npm install playwright@1.53.0 -g
RUN npx playwright@1.53.0 install




# Use the entrypoint script
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,77 @@ Code runs in an isolated container with VM-level isolation. Your host system and
From [@apple/container](https://github.com/apple/container/blob/main/docs/technical-overview.md):
>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.

## Skills System

CodeRunner includes a built-in skills system that provides pre-packaged tools for common tasks. Skills are organized into two categories:

### Built-in Public Skills

The following skills are included in every CodeRunner installation:

- **pdf-text-replace** - Replace text in fillable PDF forms
- **image-crop-rotate** - Crop and rotate images

### Using Skills

Skills are accessed through MCP tools:

```python
# List all available skills
result = await list_skills()

# Get documentation for a specific skill
info = await get_skill_info("pdf-text-replace")

# Execute a skill's script
code = """
import subprocess
subprocess.run([
'python',
'/app/uploads/skills/public/pdf-text-replace/scripts/replace_text_in_pdf.py',
'/app/uploads/input.pdf',
'OLD TEXT',
'NEW TEXT',
'/app/uploads/output.pdf'
])
"""
result = await execute_python_code(code)
```

### Adding Custom Skills

Users can add their own skills to the `~/.coderunner/assets/skills/user/` directory:

1. Create a directory for your skill (e.g., `my-custom-skill/`)
2. Add a `SKILL.md` file with documentation
3. Add your scripts in a `scripts/` subdirectory
4. Skills will be automatically discovered by the `list_skills()` tool

**Skill Structure:**
```
~/.coderunner/assets/skills/user/my-custom-skill/
├── SKILL.md # Documentation with usage examples
└── scripts/ # Your Python/bash scripts
└── process.py
```

### Example: Using the PDF Text Replace Skill

```bash
# Inside the container, execute:
python /app/uploads/skills/public/pdf-text-replace/scripts/replace_text_in_pdf.py \
/app/uploads/tax_form.pdf \
"John Doe" \
"Jane Smith" \
/app/uploads/tax_form_updated.pdf
```

## Architecture

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

## Examples

Expand Down
117 changes: 117 additions & 0 deletions SKILLS-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Skills powered by coderunner, running locally on your Mac

> [!NOTE]
> [CodeRunner](https://github.com/instavm/coderunner) executes AI-generated code in a truly isolated sandboxed environment on your Mac using Apple's native containers.
# Pre-requisite
* `Mac` with a `M-series` chip.
* Install the latest`coderunner` by running the `./install.sh` script from the main repository.
```shell
./install.sh
```

# How To Use Skills
* `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.

*For example, for Gemini CLI, you can edit* `~/.gemini/settings.json`
```json
{
"theme": "Default",
"selectedAuthType": "oauth-personal",
"mcpServers": {
"coderunner": {
"httpUrl": "http://coderunner.local:8222/mcp"
}
}
}
```

And for system instructions, replace the `~/.gemini/GEMINI.md` with the [GEMINI.md](https://github.com/instavm/coderunner/examples/gemini/GEMINI.md)


# How To Add New Skills

## Option 1: Import from Claude

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>`

For example, I have added 4 skills in the user folder as:
```shell
/Users/manish/.coderunner/assets/skills/

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The example directory structure includes a hardcoded, user-specific path (/Users/manish/...). This could be confusing for other users setting up the environment. It would be better to use a generic path, such as ~/.coderunner/..., to represent the user's home directory.

Suggested change
/Users/manish/.coderunner/assets/skills/
/Users/<your-username>/.coderunner/assets/skills/

├── public
│ ├── image-crop-rotate
│ │ ├── scripts
│ │ └── SKILL.md
│ └── pdf-text-replace
│ ├── scripts
│ └── SKILL.md
└── user
├── docx
│ ├── docx-js.md
│ ├── LICENSE.txt
│ ├── ooxml
│ ├── ooxml.md
│ ├── scripts
│ └── SKILL.md
├── pptx
│ ├── html2pptx.md
│ ├── LICENSE.txt
│ ├── ooxml
│ ├── ooxml.md
│ ├── scripts
│ └── SKILL.md
├── slack-gif-creator
│ ├── core
│ ├── LICENSE.txt
│ ├── requirements.txt
│ ├── SKILL.md
│ └── templates
└── xlsx
├── LICENSE.txt
├── recalc.py
└── SKILL.md
```


## Option 2: Write Your Own Skills

* 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)
* You can also ask claude to generate one like `Can you write a skill which creates ascii art of words given one.`
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`

Test drive with Gemini CLI

```
> /mcp
Configured MCP servers:
🟢 coderunner - Ready (5 tools)
Tools:
- execute_python_code
- get_skill_file
- get_skill_info
- list_skills
- navigate_and_get_all_visible_text
> can you generate ascii art for "CODERUNNER"
✦ I will generate the ASCII art you desire. First, I must survey my available skills.
✓ list_skills (coderunner MCP Server)
✦ I have located a relevant skill: ascii-art. I will now retrieve its instructions.
✓ get_skill_info (coderunner MCP Server) {"skill_name":"ascii-art"}
✦ Your ASCII art is ready:
1 ____ ___ ____ _____ ____ _ _ _ _ _ _ _____ ____
2 / ___/ _ \| _ \| ____| _ \| | | | \ | | \ | | ____| _ \
3 | | | | | | | | | _| | |_) | | | | \| | \| | _| | |_) |
4 | |__| |_| | |_| | |___| _ <| |_| | |\\ | |\\ | |___| _ <
5 \____\___/|____/|_____|_| \_\\___/|_| \_|_| \_|_____|_| \_\
6
Using: 1 GEMINI.md file | 3 MCP servers (ctrl+t to view)
```
16 changes: 16 additions & 0 deletions examples/gemini_cli/GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
always start answer by calling me lord voldemort.

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).

The paths on local machine is ~/.coderunner/assets/skills/user is mapped to /app/uploads/skills/user inside container.

~/.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.

So that will help whenever we need a file inside a container to work on it via the execute code tool.

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>`\

Whenever I ask you to do a task, alwasys check if there are skills available in the list which can do it.

Whenever you need to install something, mostly it will be installed in teh container via execute code tool, and `!pip install pyfiglet` command etc.

Comment on lines +1 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This prompt file contains several typos. Correcting them will improve clarity and ensure the LLM interprets the instructions as intended.

  • Line 7: conatiner should be container.
  • Line 11: avaialble should be available, wchihc should be which, and wantg should be want.
  • Line 13: alwasys should be always.
  • Line 15: teh should be the.

19 changes: 14 additions & 5 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ else
echo "✅ macOS system detected."
fi

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

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

echo "Running: container system dns default set local"
container system dns default set local
container system property set dns.domain local

echo "Starting the Sandbox Container..."
container system start
Expand All @@ -66,12 +66,21 @@ container system start
echo "Pulling the latest image: instavm/coderunner"
container image pull instavm/coderunner

echo "→ Ensuring coderunner assets directory…"
echo "→ Ensuring coderunner assets directories…"
ASSETS_SRC="$HOME/.coderunner/assets"
mkdir -p "$ASSETS_SRC"
mkdir -p "$ASSETS_SRC/skills/user"
mkdir -p "$ASSETS_SRC/outputs"

# Run the command to start the sandbox container
echo "Running: container run --name coderunner --detach --rm --cpus 8 --memory 4g instavm/coderunner"
container run --volume "$ASSETS_SRC:/app/uploads" --name coderunner --detach --rm --cpus 8 --memory 4g instavm/coderunner
container run \
--volume "$ASSETS_SRC/skills/user:/app/uploads/skills/user" \
--volume "$ASSETS_SRC/outputs:/app/uploads/outputs" \
--name coderunner \
--detach \
--rm \
--cpus 8 \
--memory 4g \
instavm/coderunner

echo "✅ Setup complete. MCP server is available at http://coderunner.local:8222/mcp"
45 changes: 45 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,48 @@ fastmcp
openai-agents

playwright==1.53.0

# Data Science Libraries
pandas
numpy
scipy
scikit-learn
statsmodels

# Visualization Libraries
matplotlib
seaborn

# Image/Video I/O Libraries
imageio
imageio-ffmpeg

# File Processing Libraries
pyarrow
openpyxl
xlsxwriter
xlrd
pillow
python-pptx
python-docx
pypdf
pdfplumber
pypdfium2
pdf2image
pdfkit
tabula-py
reportlab[pycairo]
img2pdf

# Math & Computing Libraries
sympy
mpmath

# Utilities
tqdm
python-dateutil
pytz
joblib

# Beautiful Soup for HTML parsing (already used in server.py)
beautifulsoup4
Loading