Agent Memory From Your Task Manager: CLI + MCP, No Vector DB

May 30, 2026 · 5 min read · agent-memory, mcp, claude, ticktick, rag, retrieval

Most “agent memory” projects ask you to build a new store: a vector database, a bespoke framework, a fresh pile of markdown. It drifts from reality the moment you stop feeding it. But you already maintain a curated knowledge base by hand, every day: your task manager. Years of prioritized, deduplicated context, pre-filtered by the most reliable ranker there is, which is you.

ats (Agentic Task System) makes that context agent-native without a migration. Keep the app you already live in, TickTick or an Obsidian vault today, and give your agent a fast, structured, two-way channel into it.

npm install -g @reneza/ats-cli @reneza/ats-adapter-ticktick
ats config use ticktick
ats auth login
ats find "deployment runbook"

Why agent memory from your task manager beats a new vector DB

Andrej Karpathy’s LLM-wiki idea, keep notes as plain markdown an LLM can reason over, is right about the destination and wrong about the starting line. Almost nobody’s knowledge lives in clean markdown. It lives in the task app they have used for years.

A net-new vector store starts empty and rots unless you babysit it. Your task app is already curated and current because you keep it that way to run your week. ats closes the gap with pluggable storage adapters, so you get an agent-queryable knowledge layer without re-homing a single note. Adapter, not migration.

What changes when you wire it up

Three shifts, in the order they surprised me in real use.

1. The task app becomes a two-way bus between you and your agent. It is not just somewhere the agent reads. It is where you and the agent hand work back and forth. Drop a task with a file attached and the agent picks it up with full context, then writes results back where you will actually see them. Your existing capture habit becomes the I/O channel, attachments and all.

2. Semantic retrieval makes the first fetch the right one. Parallel hybrid retrieval (dense, sparse, and keyword, fused with Reciprocal Rank Fusion, with provenance) instead of keyword grep. This collapses the usual search-refine-search loop into a single fetch that comes back both faster and richer. Better context on turn one means better answers on turn one.

3. Context gets curated at write time, not just read time. The half everyone skips. Every item is hung on a “trunk”, a theme you already care about (writing, client-work, side-project), the moment it is captured, so retrieval has structure to grab instead of a flat pile.

Underneath sits the plumbing that makes it usable every turn: a disk-backed corpus cache with sub-100ms warm latency, and a benchmark harness so retrieval quality is measured, not asserted.

Quick start with the TickTick adapter

Installed from the snippet at the top? Pick up at the OAuth step.

# Sets up TickTick OAuth + writes ~/.config/ats/config.json
ats config use ticktick
ats auth login

# Optional: local semantic / hybrid retrieval via Qdrant + Ollama
docker run -d --name qdrant -p 6333:6333 qdrant/qdrant
docker run -d --name ollama -p 11434:11434 ollama/ollama
docker exec ollama ollama pull nomic-embed-text
ats sync vector

ats find "ffmpeg commands"

Prefer plain files? The Obsidian adapter is the same contract over a local markdown vault. Point ATS_OBSIDIAN_VAULT at your vault and ats find / ats open / ats links just work.

Use it from an agent (MCP)

@reneza/ats-mcp exposes the active adapter to any MCP client (Claude Desktop, Cursor) as a small tool set: find, get_task, list_projects, create_task, update_task, similar, url_for. All of it backed by the same hybrid + RRF retrieval, storage-agnostic over the adapter contract.

// Claude Desktop config
{
  "mcpServers": {
    "ats": { "command": "ats-mcp", "env": { "ATS_ADAPTER": "@reneza/ats-adapter-ticktick" } }
  }
}

Write an adapter in an afternoon

The reason this is a layer and not a lock-in: the storage contract is six methods.

interface KnowledgeAdapter {
  listProjects(): Promise<Project[]>
  listTasksInProject(projectId: string): Promise<Task[]>
  getTask(projectId: string, taskId: string): Promise<Task>
  createTask(input: TaskInput): Promise<Task>
  updateTask(projectId: string, taskId: string, patch: TaskPatch): Promise<Task>
  urlFor(ref: { projectId: string, taskId: string }): string
}

Three optional methods (searchByQuery, bulkFetch, embeddings) let an adapter supply native search or embeddings; Core falls back to its own logic when they are absent. Scaffold one and verify it against the contract:

ats adapter new notion              # writes ats-adapter-notion/ (six stubs + package.json)
# ...implement the six methods...
ats adapter test ./ats-adapter-notion   # pass/fail/skip per contract check

TickTick ships as the reference adapter and Obsidian as a worked example over plain markdown. Notion is next, and Things, Apple Notes, and Google Tasks are on the wishlist. The scaffold plus conformance kit make most well-behaved APIs a couple-hundred-line job. PRs are welcome.

The CLI surface worth knowing

ats find <query>                   # parallel + RRF + provenance (the default)
ats find <query> --explain         # per-branch rank + the RRF math
ats open <id-or-title>             # deep-link straight into your task app
ats get <id-or-title> --extract json   # pull a fenced json/yaml block for agents
ats similar <id>                   # semantically nearby docs
ats find "deploy" --json | jq '.tasks[].title'   # any read command pipes
ats bench run && ats bench score   # hit@1 / recall@5 / MRR, measured not asserted

Why a memory layer must not re-encode state

Agent systems fail when the harness silently re-renders state between turns. A memory layer has to hold that line. In ats, writes round-trip without lossy re-encoding, the store-to-Task mapping is contract-tested rather than a black box, and every retrieval result carries its provenance (sources, find --explain). The same rule guards the outbound boundary: a publish-safety gate fails the build if personal data could leak into a package. Memory you cannot trust is worse than no memory, so integrity is the design rule, not a feature.

Get it

If it saves you from standing up yet another vector store, a star on the repo is the cheapest way to say so, and it helps the next person find it.

Author

I build production AI automation for DACH teams: agents with memory, approvals, and rollback, wired into the systems people already use. ats came out of running my own agents against my task manager every day. If you want this kind of context layer in your stack, start here.

Star agentic-task-system on GitHub