marotte puts Kiro in your browser as a self-hosted agentic IDE. Chat with the Kiro agent, kiro-cli, from a phone or a desktop, with a file editor, a terminal and git in the same tab.
marotte is in alpha. Any update can change how it works, or how chats and settings are stored, without converting yours. Pin an image tag from the releases instead of latest, and read the release notes before you upgrade.
marotte lets you write and ship code with the Kiro agent from any device, while your repositories and chats stay on your own server.
- Pick up the same conversation on every screen, your phone included.
- Review a whole turn's file edits before you keep them, or rewind a chat and its edits.
- Edit files, use a terminal, and commit and open pull requests on GitHub, GitLab, Codeberg or Gitea.
- Install language servers and command-line tools from a catalog of about 900.
- Get notified when the agent finishes or needs approval.
marotte is built for a developer who wants a full Kiro workspace on a server they run, in any browser. Start a task at your desk, then follow it and answer the agent from your phone. One container is one person's workspace.
You need a Kiro account and an amd64 or arm64 Docker host. marotte has no login of its own, so keep it on your private network or behind a reverse proxy with a login.
Consider Web Terminal for Kiro, by the same author, if you want kiro-cli's own terminal screen with no chat layer.
marotte is free software under the AGPL-3.0-or-later license.
The image is on GitHub Container Registry and Docker Hub, for amd64 and arm64. This is the compose.yaml in this repository.
services:
marotte:
image: ghcr.io/cplieger/marotte:latest
container_name: marotte
restart: unless-stopped
# Create the three host folders below and run "sudo chown -R 1000:1000 /opt/appdata/marotte"
# before the first start, or the container restarts in a loop. If .env sets PUID and PGID, use those numbers.
user: "${PUID:-1000}:${PGID:-1000}"
ports:
- "9847:9847" # keep this port on your own network, see README "Security"
volumes:
- "/opt/appdata/marotte/config:/config" # chats, the Kiro sign-in, installed tools
- "/opt/appdata/marotte/workspace:/workspace" # your repositories
- "/opt/appdata/marotte/uploads:/uploads" # files you attach to a message- Create the folders with
sudo mkdir -p /opt/appdata/marotte/config /opt/appdata/marotte/workspace /opt/appdata/marotte/uploads. - Give them to user 1000 with
sudo chown -R 1000:1000 /opt/appdata/marotte. If you setPUIDandPGIDin.env, use those numbers. - Run
docker compose up -d. - Open
http://<server>:9847, where<server>is the address of the server on your network, for examplehttp://192.0.2.10:9847. - Sign in with your Kiro account when the page asks. Chats use that account's plan and credits, which the sidebar shows. The sign-in is marotte's own, so a
kiro-cliyou start in the terminal keeps a separate one.
The first start downloads kiro-cli, about 530 MB, which can take a few minutes. The page, files, git and the terminal work in the meantime, and chats say kiro-cli is still installing. Amazon publishes kiro-cli under the AWS Customer Agreement. marotte downloads it instead of shipping it in the image, so starting the container means you accept that agreement.
Run docker logs marotte. After the download you should see msg=installed package=kiro-cli. If you see failed to create required directories, step 2 was skipped.
Open the same address in your phone's browser and add it to the home screen to install it as an app. Notifications for a finished turn or workflow run, a pull request's checks, or a permission request then arrive with the tab closed. Browsers allow both only over HTTPS or on localhost, so a phone needs the reverse proxy from Security. The other features are in Features.
Settings in the compose environment: block are read at start, so recreate the container after a change. Models, permissions, tools, notifications and chat retention are set on the page under Settings instead. No variable is required.
| Variable | Description | Default |
|---|---|---|
ALLOWED_HOSTS |
Hostnames and IPs you open marotte at, comma-separated. Any other address gets 403. |
(unset) |
TRUSTED_PROXIES |
Address ranges of your reverse proxy, so the logs record the real client address. | (unset) |
TRUSTED_INSTALL_UIDS |
User IDs that may write to /config/tools without marotte refusing to install kiro-cli. Only for shared or network volumes. |
(unset) |
MAROTTE_BROWSE_ROOTS |
Extra folders the file browser shows, colon-separated absolute paths. | (unset) |
MAROTTE_ALLOW_AGENT_ENV |
Program-changing variables, such as LD_PRELOAD, the agent may set for its commands. |
(unset) |
MAROTTE_ALLOW_BRIDGE_ENV |
Variable names that look like credentials but should still reach kiro-cli, comma-separated. | (unset) |
MAROTTE_KIRO_ACP_ARGS |
Extra kiro-cli acp flags for the agent engine. |
(unset) |
Every setting, with what each one checks, is in Configuration.
| Mount | Description |
|---|---|
/config |
Chats, the Kiro sign-in, the kiro-cli install, installed tools and settings |
/workspace |
Your repositories, and where chats and the terminal start |
/uploads |
Files you attach to a message. Without a volume they are lost when the container is recreated |
| Port | Description |
|---|---|
9847 |
The web page, its live updates and the terminal |
marotte has no login of its own. Anyone who can reach port 9847 can use the agent, which runs commands and edits files under /workspace, and the Kiro sign-in in /config. Keep the port on your private network, or put marotte behind a reverse proxy that asks for a login, such as Caddy forward-auth, oauth2-proxy or Authentik. Signing in on the page gives the agent your Kiro account. It does not protect marotte itself.
Set ALLOWED_HOSTS on any server that stays up. marotte then answers only at the addresses you list, so another website cannot use your browser to reach it.
The agent can read the container's environment:. marotte drops names ending in _TOKEN or _SECRET and the AWS key pair, so keep other credentials out of it.
marotte sends no telemetry. kiro-cli's own telemetry is on by default, as in kiro-cli, and one switch in Settings turns it off. Security covers the container user, tool installs and how kiro-cli is verified.
Docker checks /api/health every 30 seconds. The container shows healthy once marotte is up and kiro-cli is installed and working, and the first start gets five minutes for the download. While it shows unhealthy the page still works and only chats wait. Docker does not restart a container because it is unhealthy.
- The container restarts in a loop with
failed to create required directories. The host folders are missing or belong to another user. Repeat steps 1 and 2 of the quick start. - Health stays at
kiro-cli install retryingorkiro-cli unavailable. The download failed. marotte tries four times, then waits for a container restart. - The logs say a folder under
/config"can be modified by" another account. This happens on shared or network volumes. SeeTRUSTED_INSTALL_UIDSin Configuration. - Health shows
sign-in required. A chat's last turn failed because marotte is not signed in to Kiro, or Kiro refused the sign-in. Sign in from the account menu. The next turn that succeeds clears it. - The page answers
403. The address you typed is not inALLOWED_HOSTS.
- Features describes every part of the page, knowledge bases included.
- Configuration lists every setting and what it checks.
- Security covers tool installs, the image and the kiro-cli install.
- How marotte works explains syncing across devices, the agent engine, and how kiro-cli is installed and repaired.
- Launch flags and OS packages cover two less common setups.
marotte drives kiro-cli, the Kiro agent, which the container downloads on first start. The terminal is built on web-terminal-engine. Chat search ranking, the approval timeout for scheduled runs and the ladder of permission profiles follow Kiro Crew.
See CONTRIBUTING.md.
This project is built with care and follows security best practices, but it is intended for personal / self-hosted use. No guarantees of fitness for production environments. Use at your own risk.
This project was built with AI-assisted tooling using Claude, GPT, and Kiro. The human maintainer defines architecture, supervises implementation, and makes all final decisions.
AGPL-3.0-or-later. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.
The terminal's two web fonts ship under their own licences, each licence text served beside the font files under /vendor/fonts/: Monaspace Neon NF under SIL Open Font License 1.1, and web-terminal-glyphs under Apache-2.0.
