New
Apps 821Makers 820This week 821
Promote your app−30%
Atlas screenshot 1
2views in
the last 30 days

Atlas

A personal Claude agent that runs in your terminal. Files, web search, gated shell, and vector...

Built with Claude/Claude Code

by samgabriel-here · from INIndia · added Oct 29, 2026
no ratings0 comments

A personal Claude agent that runs in your terminal. It reads and writes files in directories you nominate, searches the web, runs shell commands behind an approval gate, and remembers things about you across sessions.

Built on the Anthropic API directly, with no framework in between.

› what did I decide about the trimeffects port?

  memory? 1 match
Yarn mappings stopped at 1.21.11, so the 26.x port targets the unobfuscated
jar directly rather than waiting for mappings...
  $0.0184 this session

Setup

cd atlas
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
cp .env.example .env      # then put your key in it
.venv/bin/python main.py

Get an API key at console.anthropic.com, or run ant auth login and leave ANTHROPIC_API_KEY unset, and the SDK picks up the profile automatically.

First launch downloads a ~80 MB local embedding model for memory. It happens once, at startup, with a spinner.

Usage

python main.py                      # interactive
python main.py -p "summarize ~/Desktop/notes.md"   # one-shot
python main.py --resume LAST        # continue the previous session
python main.py --thinking           # show the model's reasoning as it works

In the REPL:

Command
/memory [query] list or search long-term memory
/forget <id> delete a memory
/sessions list saved sessions
/thinking toggle reasoning display
/cost tokens and spend for this session
/clear fresh conversation, memory kept
/exit quit

What it can do

Files

read_file, write_file, edit_file, list_dir, find_files, search_text. Every path is resolved and checked against ATLAS_WORKSPACE_ROOTS before anything touches disk, so .. traversal and symlinks pointing outside the workspace are refused rather than followed.

Web

web_search and web_fetch run server-side on Anthropic's infrastructure. Nothing to install, and results are filtered before they reach the context window.

Shell

run_command. Destructive patterns (rm -r/-f, sudo, curl | sh, dd of=, force-push, git reset --hard, git clean -f, find -delete, fork bombs) are blocked outright, including when they hide after a newline, inside $(...), or behind xargs. Read-only commands are allowlisted and run without interruption, as long as every path they name is inside the workspace. Everything else prompts you for approval before it runs, including:

  • interpreters and installers (python, node, pip, npm, pytest, sh), even if your own ATLAS_SHELL_ALLOWLIST lists them
  • any git subcommand that isn't read-only (status, log, diff, show, ...)
  • find -exec and rg --pre, which run another program

The file tools also refuse to write inside a .git directory, where hooks and config run code on the next git command, and inside Atlas's own folder, whose .env and source decide what these guardrails allow.

Memory

remember, recall, forget, backed by a local Chroma vector store. Relevant memories are retrieved and injected automatically at the start of each turn, so you don't have to ask. Memory is local; nothing is sent anywhere except as context on your own requests.

Configuration

Everything lives in .env. See .env.example for the full list.

Variable Default
ATLAS_MODEL claude-opus-5-5 any current Claude model id
ATLAS_EFFORT high low to max; how hard it thinks and works
ATLAS_MAX_TOKENS 64000 ceiling on thinking + response per turn
ATLAS_WORKSPACE_ROOTS ~/Desktop colon-separated; the only reachable dirs
ATLAS_SHELL_MODE ask ask, allowlist (no prompts, deny unknown), yolo
ATLAS_MEMORY_MIN_SCORE 0.15 absolute relevance floor for recall
ATLAS_MEMORY_REL_RATIO 0.6 keep hits within this fraction of the best hit

ATLAS_EFFORT is the main cost/quality dial. high is a good default; drop to medium or low for routine work, raise to xhigh for hard multi-step tasks.

Layout

main.py                  CLI entry point and REPL
src/
  agent/loop.py          the agent loop
  agent/session.py       conversation state and persistence
  agent/memory.py        vector memory
  tools/registry.py      tool registration and dispatch
  tools/{files,shell,memory_tools}.py
  tools/server.py        web search/fetch declarations
  models/config.py       every tunable, in one place
  prompts/system.py      the system prompt
  utils/{guardrails,logging,render}.py
tests/                   mirrors src/
data/                    memory store and saved sessions (gitignored)
logs/                    JSONL traces (gitignored)

Design notes

Why a manual loop, not the SDK tool runner

The runner is the usual recommendation, but it doesn't resume a turn that stops with stop_reason: "pause_turn". It returns the paused turn as the final message instead. Since this agent mixes client-side tools with server-side web search, which is exactly what triggers a pause, that would surface as a silently truncated answer with no error. The loop in src/agent/loop.py handles it explicitly, along with refusals and token-ceiling truncation.

Two-stage relevance filtering

Embedding scores for short queries sit in a narrow band, and a correct hit for one query can score lower than an incorrect hit for another: measured here, 0.231 versus 0.363. So a single absolute cutoff either leaks noise or drops real matches. An absolute floor answers "is anything relevant at all", then a relative floor keeps only what's competitive with the best hit. Both are tunable; the defaults were calibrated against the local model and are pinned by tests in tests/test_memory.py.

Memory as a mid-conversation system message

Memory goes in as a mid-conversation system message, which keeps the cached conversation prefix intact instead of rewriting the system prompt each turn. On models that don't accept those, the agent falls back to folding memory into the user turn automatically.

Prompt caching

Caching is set on the system block, which holds the tools and system prompt and is identical across every session, and on the conversation prefix. /cost shows how many tokens came from cache.

Traces

Every model request, tool call, and error is appended to logs/trace-YYYY-MM-DD.jsonl with token counts and cost. Anything resembling a credential is redacted before it's written.

Tests

.venv/bin/python -m pytest

57 tests, no network or API key required. The guardrail tests cover path traversal, symlink escape, and command classification; the loop tests cover pause-turn resumption, refusal handling, and not returning tool results for server-side tools.

Limitations

  • Cost figures are computed from list prices in src/models/config.py. A model missing from that table costs $0 in the readout, and Atlas says so at startup.
  • The shell gate is pattern matching, not isolation. It catches the common ways a command reaches outside the workspace or runs other code, but approved commands run with your full permissions. It is a speed bump, not a sandbox, so don't set ATLAS_SHELL_MODE=yolo and walk away.
  • Long conversations aren't compacted. The 1M-token context window means this is unlikely to bite in a personal session, but a very long one will eventually exhaust it.

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#agent · #cli · #memory