Self-hosted service
open-webui/open-terminal avatar
open-webui/open-terminal

Open Terminal: a curl-able remote shell for AI agents

A computer you can curl ⚡

3,247 stars282 forksPythonMIT

At a glance

What is it?
Open Terminal is a self-hosted REST API that gives agents a shell, file management and code execution. It ships as a Docker image or a pip package, and the trade-offs are mostly about how much of your host you hand over.
Who is it for?
Adopt Open Terminal when an agent needs a real shell and you can keep it inside the Docker sandbox with an API key set. Do not adopt it on bare metal for untrusted input, and do not mount /var/run/docker.sock unless everyone with terminal access is trusted with host root.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap Open Terminal fills between an agent and a machine

An AI assistant can write a script. It cannot run one unless something exposes an execution surface. Open Terminal is that surface: a self-hosted terminal reachable over a REST API, with file management, search and command execution. The README frames it plainly, saying AI assistants need somewhere to run code and that this project is that place.

The intended users are people wiring agents and automation tools into a real environment, and the project sits under the open-webui topic, so the Open WebUI crowd is the obvious audience. The API-key model means a single deployment can serve one agent or several, depending on how you configure it. It is a server, not a library, and that shapes everything else: you get a process listening on a port, and whatever that process can reach, the agent can reach.

How Open Terminal executes commands and serves files

The architecture is a Python service. pyproject.toml lists FastAPI and uvicorn as the web layer, with click providing the open-terminal command-line entry point. Dependencies also include aiofiles for async file access, python-multipart for uploads, and a set of document parsers: pypdf, python-docx, openpyxl, python-pptx, striprtf and xlrd. Notebook execution is handled by nbclient and ipykernel. An optional extra named mcp pulls in fastmcp.

That dependency list tells you what the API is expected to touch: documents, spreadsheets, presentations, notebooks. The Dockerfile goes further and installs a wide toolkit at build time, including git, build-essential, ffmpeg, pandoc, poppler-utils, imagemagick, LibreOffice (headless) and TeX Live, plus Node.js 22 and the Docker CLI with Compose and Buildx. The default image is roughly 4 GB for that reason.

Configuration resolves in a documented order, highest priority first: CLI flags, then environment variables, then the user config at $XDG_CONFIG_HOME/open-terminal/config.toml (defaulting to ~/.config/open-terminal/config.toml), then /etc/open-terminal/config.toml, then built-in defaults. The README suggests putting host and port in the system config and the API key in the user config, so the key stays out of ps and htop output. That is a small detail with real operational value.

Installing Open Terminal with Docker and running a first command

The README calls Docker the recommended path. This command starts the container, publishes port 8000, mounts a named volume at /home/user, and sets an API key. If you omit the key, one is generated and you retrieve it from the container logs.

bash
docker run -d --name open-terminal --restart unless-stopped -p 8000:8000 -v open-terminal:/home/user -e OPEN_TERMINAL_API_KEY=your-secret-key ghcr.io/open-webui/open-terminal

After it starts, the service is reachable at http://localhost:8000. The README notes that without OPEN_TERMINAL_API_KEY a key is generated automatically, and `docker logs open-terminal` prints it.

Image variants matter before you go further. `latest` is about 4 GB and bundles Node.js, gcc, ffmpeg, LibreOffice, LaTeX, the Docker CLI and data science libraries, supports runtime package installs via sudo, multi-user mode and an egress firewall. `slim` (about 430 MB) and `alpine` (about 230 MB) carry git, curl and jq, and the README states they have the same feature set as each other, differing in libc: Debian glibc versus musl. The `openshift` variant targets restricted non-root pod policies and drops runtime installs, Docker socket access, the iptables egress firewall and OPEN_TERMINAL_MULTI_USER.

bash
docker run -d -p 8000:8000 -e OPEN_TERMINAL_API_KEY=secret ghcr.io/open-webui/open-terminal:slim
docker run -d -p 8000:8000 -e OPEN_TERMINAL_API_KEY=secret ghcr.io/open-webui/open-terminal:alpine
docker run -d -p 8000:8000 -e OPEN_TERMINAL_API_KEY=secret ghcr.io/open-webui/open-terminal:openshift

Adding tooling without forking is done through environment variables. The README warns that these packages are installed on every container start, so large lists slow startup, and that slim and alpine do not support these variables at all.

bash
docker run -d --name open-terminal -p 8000:8000 \
  -e OPEN_TERMINAL_PACKAGES="cowsay figlet" \
  -e OPEN_TERMINAL_PIP_PACKAGES="httpx polars" \
  -e OPEN_TERMINAL_NPM_PACKAGES="typescript tsx" \
  ghcr.io/open-webui/open-terminal

On bare metal the project is a standard Python package requiring Python 3.11 or newer. The README gives two forms, one with uvx and no install, one with pip.

bash
uvx open-terminal run --host 0.0.0.0 --port 8000 --api-key your-secret-key
pip install open-terminal
open-terminal run --host 0.0.0.0 --port 8000 --api-key your-secret-key

A TOML config file can carry the same settings. The README shows these keys, all optional, with execute_timeout unset by default.

toml
host = "0.0.0.0"
port = 8000
api_key = "sk-my-secret-key"
cors_allowed_origins = "*"
log_dir = "/var/log/open-terminal"
binary_mime_prefixes = "image,audio"
execute_timeout = 5  # seconds to wait for command output (unset by default)
file_browser_root = "home"

You can point the CLI at a specific file with `open-terminal run --config /path/to/my-config.toml`. Updating the Docker deployment is a pull and a recreate: `docker pull ghcr.io/open-webui/open-terminal`, then `docker rm -f open-terminal`, then re-run the original command. The README does not document a rollback procedure.

Where Open Terminal is the wrong tool

The security model is the limitation. On bare metal, the README's own caution is that commands run directly on your machine with your user's permissions, and it points to Docker for sandboxed execution. That is not a footnote. If you expose the API to anything you do not fully control, bare metal turns a prompt injection into a shell on your workstation.

The Docker socket is the second sharp edge. Mounting /var/run/docker.sock so agents can build and run containers gives the container full control over the host's Docker daemon, which the README describes as effectively root access on the host. Anyone with terminal access can run privileged containers, mount host directories and reach host networking. The project says to do this only in fully trusted environments, and that is the right reading.

There are smaller constraints too. Slim and alpine cannot install packages at runtime, so a missing tool means building a custom image from Dockerfile.slim or Dockerfile.alpine. The default image carries LibreOffice for Office-to-PDF conversion while the smaller variants do not, and the README says to build a custom image if those variants need it. The openshift image drops the egress firewall and multi-user mode. And execute_timeout is unset by default, so long-running commands are not bounded unless you set it.

If your need is a one-shot code interpreter with no filesystem persistence and no network, this is heavier than you need. If your need is a full development environment for a human, an SSH server or a dev container does that job without an API layer.

Open Terminal compared with a plain SSH session

The closest alternative is the thing everyone already has: SSH into a machine and let the agent run commands there. The difference is the interface. SSH gives you a shell protocol and expects a human or a script with credentials and host keys. Open Terminal gives you a documented REST surface with an API key, plus file browsing metadata such as GET /files/cwd, which the README says clients use to hide parent navigation. That endpoint exists because an agent client needs to know where it is without parsing shell output.

SSH also has no concept of image variants, package bootstrapping or an egress firewall. Open Terminal bundles those decisions into a container you can rebuild. The cost is that you now maintain a service with its own config precedence, its own timeout semantics and its own release cadence. If all you need is a shell on a box you already trust, SSH is less machinery. If you need a sandbox you can hand to an agent and tear down, the container path is the reason to pick this project.

Maintenance, licensing and upgrade cost

The repository is not archived, and the last push was on 2026-09-09. Releases v0.12.3, v0.12.4 and v0.12.5 landed between 2026-08-27 and 2026-09-09, while pyproject.toml on the default branch already declares version 0.13.0, so the package metadata runs ahead of the published release list. Plan for frequent small upgrades rather than long stable stretches.

The upgrade path for Docker is explicit: pull the new image, remove the container, re-run the run command. Because OPEN_TERMINAL_PACKAGES, OPEN_TERMINAL_PIP_PACKAGES and OPEN_TERMINAL_NPM_PACKAGES install on every start, a recreate also re-installs them, which adds startup time proportional to the list. The README recommends building a custom image for heavy customization, and that is the better trade if your package list is long. The Dockerfile pins python:3.12.13 and comments that bumping the base image tag is preferred over running a blanket apt upgrade, which keeps builds reproducible.

The licence is MIT, declared both in pyproject.toml and in the repository's LICENSE file. That is permissive and places few obligations on how you redistribute or modify it. It says nothing about the licences of the bundled tooling inside the Docker image, and the README does not inventory them, so if you redistribute the image rather than just run it, that is your own check to make. Nothing here is legal advice.

Editorial conclusion

Adopt Open Terminal when an agent needs a real shell and you can keep it inside the Docker sandbox with an API key set. Do not adopt it on bare metal for untrusted input, and do not mount /var/run/docker.sock unless everyone with terminal access is trusted with host root. Before rollout, verify which image variant you need, because slim, alpine and openshift cannot install packages at runtime, and confirm whether OPEN_TERMINAL_MULTI_USER is required for your setup.

Frequently asked questions

What is Open Terminal?

It is a self-hosted terminal exposed over a REST API, letting AI agents and automation tools run commands, manage files and execute code. It runs either as a Docker container or as a Python package installed with pip.

How do I install Open Terminal?

The README recommends Docker: run the ghcr.io/open-webui/open-terminal image with port 8000 published and OPEN_TERMINAL_API_KEY set. Without Docker, install the Python package and start it with open-terminal run --host 0.0.0.0 --port 8000 --api-key your-secret-key, or use uvx to run it without installing.

What is the difference between Open Terminal and Open WebUI?

The material only shows that Open Terminal is a separate repository under the open-webui organisation and carries the open-webui topic. It is a terminal API for running commands and managing files, not a chat interface, and the README does not describe how the two projects integrate.

How do I use Open Terminal with Open WebUI?

The README does not document an Open WebUI integration or any client setup steps. What it does describe is the API itself: a service on port 8000, protected by OPEN_TERMINAL_API_KEY, that exposes command execution and file management.

Official sources

  1. License: MIT
  2. open-webui/open-terminal on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/open-webui-open-terminal.svg)](https://hysenlabs.com/projects/open-webui-open-terminal)