Jarvis is arguably my favorite AI assistant from any sci-fi stories. He's capable, low key, intelligent, and witty. He is my idea of how a personal AI assistant should be like. Watching Iron Man has been a great inspiration.
Now we finally have the technology to build this out, or ... close enough.
There are great personal AI assistants out there I have no doubt, but for me it is more fun to build out my own version of Jarvis, shaping it to be the way I want. That's what I am doing with JARVIS.py.
Run Jarvis inside Docker. Bring the containers up first:
docker compose up -d --buildDocker Compose should create ~/.jarvis/workspace/ on first run; if it does not, create it manually with
mkdir -p ~/.jarvis/workspace~/.jarvis/workspace/ will be the workspace dir for the agent.
Set up secrets by creating files under secrets/. The full expected list and doc URLs are in secrets/README.md.
In telegram BotFather, add commands:
new - start a new session
stop - pause Jarvis
compact - compact current session
models - show active LLM providers and models
Jarvis can use OpenAI Codex through a host-run codex app-server. In Jarvis settings, set llm.default_provider: codex and, if desired, subagent.provider: codex.
Jarvis does not hold your OpenAI OAuth session itself. The host Codex app-server does. Jarvis only needs the same websocket bearer token that the host app-server expects.
Create one shared websocket token and put it in both places:
mkdir -p ~/.codex
openssl rand -hex 32 | tee ~/.codex/jarvis-ws-token > secrets/JARVIS_CODEX_WS_BEARER_TOKEN
chmod 600 ~/.codex/jarvis-ws-token secrets/JARVIS_CODEX_WS_BEARER_TOKENStart Codex app-server on the host:
codex app-server \
--listen ws://0.0.0.0:4500 \
--ws-auth capability-token \
--ws-token-file ~/.codex/jarvis-ws-tokenThen recreate jarvis_runtime so the secret is mounted:
docker compose up -d --build jarvis_runtimeDefault Docker settings expect Codex at ws://host.docker.internal:4500. If you use a different listener, update providers.codex.ws_url in settings.yml.
On the first Codex-backed message, Jarvis will send you a browser login URL. Open it and complete the OpenAI login flow. After that, the host Codex app-server keeps the OAuth session and later Jarvis turns should connect without another login unless the host session expires.
- At container startup time,
jarvis_runtimeseedsworkspace/settings/settings.ymlandworkspace/identities/*.mdonly when they are missing, but always refreshesworkspace/settings/settings_gui.htmlandworkspace/migrate.shfrom the repo copies - Jarvis reads runtime settings from
workspace/settings/settings.ymlwhen it exists, and falls back to the packaged template YAML only if that workspace file is absent. - Settings GUI is also available in
workspace/settings/settings_gui.html. Open or drag insettings.ymlthere, edit the settings in the GUI, and save edited settings. workspace/migrate.shcreates a zip archive ofarchive/,memory/,runtime_tools/, andsettings/from the current directory. Pass--allto archive everything in the current directory exceptnode_modules/.
docker compose exec jarvis_runtime bash -lc "cd /repo && uv sync --locked --group dev"
docker compose exec jarvis_runtime bash -lc "cd /repo && uv run jarvis"For tests and linting, use the same container-managed environment:
docker compose exec jarvis_runtime bash -lc "cd /repo && uv run pytest"
docker compose exec jarvis_runtime bash -lc "cd /repo && uv run ruff check ."Tests that make real AI provider API calls are skipped by default. Run them explicitly with:
docker compose exec jarvis_runtime bash -lc "cd /repo && uv run pytest --run-live-api"- Shortcut
add this to ~/.zshrc:
alias jarvis='<path>/Jarvis/utils/run_jarvis.sh'Run on host with alias: jarvis or jarvis --reinstall
- Manually
docker compose exec jarvis_runtime bash -lc "bash utils/install_build.sh"To force a fresh rebuild and reinstall:
docker compose exec jarvis_runtime bash -lc "bash utils/install_build.sh --reinstall"Run installed artifact with:
docker compose exec jarvis_runtime bash -lc "jarvis"