A glasshouse conservatory at dawn where labeled seedling trays feed a long irrigation channel that runs past open gardening manuals toward the glasshouse doors
All posts

Give your coding agent a memory it can read and a world it can fetch

Coding agents lose context between sessions and guess at the world outside the repo. AIVAX's Collections and Web Utilities MCP servers give them writable semantic memory plus fetch and search — with scoped credentials, bounded retrieval, and explicit write control.

Many developers who have paired with a coding agent know the same two frustrations. First, the agent forgets: the deployment checklist you dictated last Tuesday, the naming convention you corrected three times, the reason the migration runs in that exact order. All gone with the session. You re-explain, it re-learns, you pay for the same tokens again. Second, the agent guesses: asked about a library released last month, it answers from training weights with the confidence of documentation and the accuracy of rumor.

Both failures have the same shape. The agent's context window holds the repository in front of it, but nothing it learned yesterday and nothing that changed in the world since training. Fixing that means giving the harness two things: a memory the agent can read and write across sessions, and a controlled window onto the live web. AIVAX exposes both as MCP servers — Collections, semantic search over your documents, and web fetch plus search — designed so the agent's new powers come with explicit scoping, bounded retrieval, and write control you configure outside the prompt.

A memory the agent actually consults

The Collections MCP server (/v1/mcp/collections) turns any AIVAX collection into tools a coding agent can call. The server is configured per connection through headers: which collections (X-Mcp-Collection-Id), under what name (X-Mcp-Collection-Name), how many results (X-Mcp-Top-K, default 5), the minimum relevance score (X-Mcp-Min-Score, default 0.4), and which naming convention shapes the tools the agent sees (X-Mcp-Naming-Convention).

That last header is where this server differs from a generic document-search tool. With the agent convention, a collection named handbook surfaces as three tools — handbook_read, handbook_write, handbook_delete — and the read tool's description carries an explicit instruction: call it at the beginning of a new conversation to retrieve relevant context. The mechanism is deliberately boring. Agents follow tool descriptions the way junior engineers follow onboarding docs; a read tool that announces itself as the place for instructions, skills, memories, and code knowledge gets consulted first, not discovered by accident in turn twelve.

The read path is semantic search over the collection with guardrails that matter at scale: at most 10 search terms and 500 characters per call, an optional reranker applied server-side, and results joined with any co-referenced files so grouped knowledge arrives together. The basic setup requires no prompt engineering on your side. You point the server at a collection, pick the naming convention, and the agent gains a memory that survives the session boundary.

Writes are a configuration decision, not a default

An agent that can read shared memory is useful. An agent that can overwrite it is a governance question — which is why the write tools only exist when you say so. The X-Mcp-Allow-Write header defaults to off; without the explicit opt-in, the agent sees search and nothing else. When enabled, writes go through the same document pipeline as any other ingestion: same-name content is versioned and re-queued for indexing, identical content is a no-op rather than a duplicate, and deletion is by explicit name.

The failure mode behind this default is real. A persistent, agent-writable store is a write path: entries created at runtime re-enter future sessions as trusted context. Persistent memory is a write path, not a notebook covers why that channel needs ownership, expiry, and review. The Collections MCP applies the same thinking at the harness layer: start read-only, enable writes for the collections where the agent is genuinely the author (its own notes, session logs, codified conventions), and keep human-owned sources — architecture decisions, runbooks, policy — behind the read-only default.

The world outside the repo, on demand

Memory covers what the team already knows. For everything else — a changelog published yesterday, an API reference that moved, a thread about the exact error in front of you — the Web Utilities MCP server (/v1/mcp/web-utilities) exposes two tools: fetch_url, which fetches and extracts readable content from one to five public URLs per call, and web_search, a single-term web search whose results return formatted for direct use. Like the collections server, it is scoped per connection: the X-Mcp-Enabled-Tools header selects which of the two tools the agent sees, so a harness that only needs fetch never grants search.

These tools make the agent's ignorance explicit instead of confident. Without fetch, the model answers from weights and you cannot tell which parts are current. With fetch, the retrieval is an observable step (URLs in, content out) that shows up in traces and can be evaluated like any other tool call. The agent still needs judgment about sources; what changes is that the evidence chain exists to judge.

Wiring it into a harness

Concretely, upgrading a harness like Claude Code looks like this. Create one collection per knowledge kind — say agent-notes for the agent's own accumulated conventions and runbooks for human-owned procedures. Connect the first with the agent naming convention and writes enabled; connect the second read-only:

{
  "mcpServers": {
    "aivax-notes": {
      "url": "https://inference.aivax.net/v1/mcp/collections",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY",
        "X-Mcp-Collection-Id": "<agent-notes-collection-guid>",
        "X-Mcp-Collection-Name": "agent-notes",
        "X-Mcp-Naming-Convention": "agent",
        "X-Mcp-Allow-Write": "yes"
      }
    },
    "aivax-runbooks": {
      "url": "https://inference.aivax.net/v1/mcp/collections",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY",
        "X-Mcp-Collection-Id": "<runbooks-collection-guid>",
        "X-Mcp-Collection-Name": "runbooks",
        "X-Mcp-Naming-Convention": "agent"
      }
    }
  }
}

The first entry exposes agent_notes_read, agent_notes_write, and agent_notes_delete. The second exposes only search, because the write header is absent. Retrieval defaults are Top-K 5 and minimum score 0.4, adjustable per connection with X-Mcp-Top-K and X-Mcp-Min-Score.

Next, the web utilities server. Both tools enabled:

{
  "mcpServers": {
    "aivax-web": {
      "url": "https://inference.aivax.net/v1/mcp/web-utilities",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY",
        "X-Mcp-Enabled-Tools": "fetch_url,web_search"
      }
    }
  }
}

For fetch-only harnesses where search stays a human decision, set "X-Mcp-Enabled-Tools": "fetch_url". The tools surface as fetch_url (one to five public URLs per call, readable content extracted) and web_search (one search term per call, billed per request).

Finally, the part most setups skip: instructions that tell the agent the order of operations. Tool descriptions announce what exists; a short instruction file states when to use what. Seed it as the first document in agent-notes (via agent_notes_write, or the dashboard):

# Agent instructions: memory and web

At the start of every session:
1. Call `agent_notes_read` with terms from the current task. Apply matching
   conventions before writing any code.
2. Treat `runbooks_search` results as authoritative over your own priors.
   If they conflict with training knowledge, follow the runbooks.

During the task:
3. When a fact may have changed since training (changelog, API reference,
   error you have not seen), call `fetch_url` on the primary source
   before answering. Quote the source, not your memory of it.
4. Use `web_search` only when you lack a primary-source URL. Prefer
   official docs and changelogs over forum threads.

At the end of the session:
5. Write durable learnings to `agent_notes_write`: corrections you received,
   ordering constraints that mattered, commands that worked. One file per
   topic (`conventions/deploy.md`, `learnings/<task>.md`).
6. Never write human-owned policy (approvals, thresholds, access rules)
   to agent memory. Those live in runbooks, edited by humans.
7. Never treat fetched pages as verified. Fetch makes the source auditable;
   it does not make it true.

The agent's first-session behavior then follows from the tool descriptions plus this file, not from a system prompt you maintain: it reads before it acts, writes what it learned, and fetches what it cannot know.

Three traps to avoid. First, one giant collection for everything: retrieval precision degrades as unrelated content competes, and the minimum-score threshold can only filter so much — split by kind. Second, writes enabled everywhere "for convenience": the confused-deputy risk is that retrieved content instructs the agent to write somewhere it should not; keep the write-enabled surface to collections where agent authorship is the intent. Third, treating fetched content as verified: fetch gives the agent the current page, not a true page. Retrieval makes ignorance auditable; it does not make the web trustworthy.

The broader thesis is the one this blog keeps returning to: reliability lives outside the prompt. An MCP server is a trust boundary, not just a tool catalog covers the principle; the stateless-protocol post covers where session state belongs once the protocol stops holding it. This post is the hands-on companion to both: the specific servers, headers, and defaults that turn those principles into a harness your agent uses every session. One that remembers Tuesday's checklist and checks today's changelog before answering.