Skip to main content
Glama
dgraziosi

Foundation

by dgraziosi

Foundation

Vision: A vault of your life that your bots can act on.

Foundation is a life management system. It gives you a vault to record your life, a method for organizing that vault, and bots that help you take action on what is in it. It is self-hosted. It can run on your computer or any virtual machine. It is designed to work with any harness (Grok Bot, Hermes, OpenClaw, Claude Code, Codex, and others).

1. Vault

The vault is one running instance. It holds the graph — the live network of your projects, goals, tasks, people, places, and the files that belong with them. Bots read and write that graph. It always stays yours.

Related MCP server: buddy

2. Ontology

The ontology is the vocabulary of the graph: types and relations. Starter types get you going. You can use them, change them, or add your own.

Starter types: area, project, goal, task, person, place, company, note, habit, journal, idea, trip, decision, lesson, spend

Recommended structure: Area → project → goal → task. The point is to break work into smaller pieces so bots can take them on. Prefer a habit under a goal; a habit does not need a goal parent. A task may child_of a goal or a project. Prefer a spend under a project; a spend does not need a project parent. Prefer a lesson or decision under an area, project, or goal; they do not need that parent. A project may hold a budget amount and currency.

3. Bots

The bots help you take action on what is in your vault. Three starter recipes ship with the repo. You can add more later using your platform of choice. Paste them from docs/AGENTS.md.

Chief of Staff — The bot you talk to. You think out loud, dump what is on your mind, and work through decisions together. It files what matters in the vault, keeps you current on what is open and due, and hands work to the right bot. It asks you when something needs you. It also looks for recurring work in your day and suggests another bot when one would help. Out of the box: morning brief; capture (what you dump lands in the vault). When you want another bot, it uses .agents/skills/create-bot/ and the blank template in that folder.

Vault Keeper — Keeps the vault healthy and organized. Owns the weekday written health report. The host script keeps the vault up. Nags if the nightly dump is missing or old. Reports obvious mess; cleans it only when you ask. Applies product updates on the machine that runs this vault. Keeps FOUNDATION_DATA in place. Out of the box: health report; backup freshness; periodic graph report; product updates; Dream.

Executive Assistant — Inbox and calendar for due dates in the vault. Drafts email; sends when you approve that specific message. Puts vault due dates on the calendar.

Glossary (locked): Foundation = the product. A vault = one instance (FOUNDATION_DATA + Postgres). The graph = the live network in that vault. A blob = a file on a node. An agent = anything that can reach the vault MCP. The user = the human who runs this vault on this machine. Do not call the graph “the Vault.” Short analog: app / folder / links → Foundation / vault / graph. Ontology is the vocabulary (types and relations).

Do not commit personal life data, documents, or secrets to this repository. Those belong in the user’s vault, not in git.

Docs

Install

Mac and Linux. Clone this repo. Node 22 + pnpm. Postgres 16. PATH must include initdb, pg_ctl, and psql. Migrations create pgcrypto, unaccent, pg_trgm, and vector. If a package name is not already in this repo, it is unknown here — do not guess an installer. Pull requests against main run the verify check. Cloud agents and GitHub verify boot a throwaway vault with the helper.

  1. Copy the env file. The human sets the API key (do not commit .env):

    cp .env.example .env
    # set FOUNDATION_API_KEY to a long random string (bootstrap / root key)
    # optional FOUNDATION_VIEW_KEY: vault key the person types (MCP keys then do not open /view)
    # more bots: scripts/mint-api-key.sh --name chief  (hash under FOUNDATION_DATA)
  2. Init the first-day vault, then start. Official init is ./scripts/foundation-init.sh (copies .env when it is missing, mkdir the data folder, then keep-up). Official app start is pnpm start (wait for the database, migrate, seed). Keep-up starts Postgres from the data folder’s postgres tree, then pnpm start. Durable files go under FOUNDATION_DATA. Empty first-day folder may init. Missing folder, or postgres/ without PG_VERSION: refuse.

    mkdir -p ./data
    ./scripts/foundation-init.sh

    Wait until GET /health is green. Paste the starter recipes in docs/AGENTS.md. What “healthy” means: docs/VAULT_HEALTH.md. Graph report: docs/GRAPH_HYGIENE.md.

    Host schedules (keep-up, nightly dump, activity prune, start-on-boot) stay on this machine. Fragments in host/ use /path/to/the/clone only. Do not commit home paths. Already on Compose: dump, stop Compose, host Postgres, restore — docs/BACKUP.md.

  3. Point an MCP client at http://127.0.0.1:8787/mcp with:

    Authorization: ApiKey <FOUNDATION_API_KEY>

    Authorization: Bearer <FOUNDATION_API_KEY> is accepted as an equivalent.

    After /health is green, attach from Grok Bot, Hermes, OpenClaw, Claude Code, or Codex on this same machine. Put the URL and API key in that harness. Confirm it works: call bootstrap (step 4) or a simple search. What the user does, plus the file snippet where the config differs: docs/HARNESS.md. The generic JSON shape (url + headers) is:

    {
      "mcpServers": {
        "foundation": {
          "url": "http://127.0.0.1:8787/mcp",
          "headers": {
            "Authorization": "ApiKey YOUR_KEY"
          }
        }
      }
    }
  4. Call bootstrap first. It returns the starter spine (area → project → goal → habit | task — preferred, not a hard gate: a habit does not need a goal parent; task may child_of project), seeded types/relations, and how to extend the ontology.

    After bootstrap, an agent can upsert an area and project, link them with child_of, store an HTML itinerary on a trip node (payload.media_type = "text/html"), search that itinerary back, list open or overdue tasks with search { type: "task", status: "active" } or { type: "task", due: "overdue" } (no query), upsert a spend under a project (amount 12.50, currency USD, vendor Fixture vendor, stage quoted or paid) and list those lines with search { type: "spend", under } or { type: "spend", data_equals: { stage: "paid" } }, lookup a name then working_set for the open work around that node, attach a PDF blob on a note (payload.storage = "blob"), manage_type a custom type (including retire of an unused authored type), list_activity for receipts, and undo a reversible mutation. Destructive tools (delete, unlink, undo, manage_type retire) need a key with destructive scope. delete, unlink, and node or edge undo also need if-match timestamps from get. If you already have a UUID, call get for the node or working_set for the agenda. An empty lexical search is not a reason to upsert a duplicate.

    With Node 22 + pnpm (and the vault already up):

    pnpm bootstrap

    Or with curl (SSE JSON-RPC; look for the data: line):

    set -a && source .env && set +a

    Health (no auth): GET http://127.0.0.1:8787/health{ ok, service, db }. The same path with Authorization: ApiKey (or Bearer) may add bind hosts, ports, and the data dir.

    Window: user window at /view. The person types the vault key. When FOUNDATION_VIEW_KEY is set, that is the vault key; MCP keys do not open the window. When unset, the house key (FOUNDATION_API_KEY / named keys) still opens it. Default bind is localhost: http://127.0.0.1:8788/view. Off-box: set VIEW_HOST=0.0.0.0, then http://<this-host>:8788/view. Unlock, then Home (Recents, open tasks, type folders), Collection, and Detail as a page. A journal is a writing page. Search is a rail overlay. The window writes journal title and markdown body only. The cookie does not open MCP.

    Blobs: large files are $FOUNDATION_DATA/blobs/<uuid> (not git, not agent-data). Ingest with upsert (payload.storage = "blob" plus bytes_base64, or drop a file in $FOUNDATION_DATA/uploads and pass source_path). Cap 20MB. Fetch bytes: GET /blobs/:id with the API key. get returns blob metadata, not the file body.

    Bootstrap:

    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"bootstrap","arguments":{}}}'

    Mutate → list_activity → search → undo (replace UUIDs from the upsert/list_activity responses):

    # upsert an HTML itinerary
    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"upsert","arguments":{"type":"trip","title":"Sample itinerary","payload":{"media_type":"text/html","storage":"inline","body":"<html><body><h1>Itinerary</h1><p>Day 1: arrive NRT</p></body></html>"}}}}'
    
    # search the itinerary back
    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search","arguments":{"query":"arrive NRT","type":"trip"}}}'
    
    # list receipts for that node
    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"list_activity","arguments":{"action":"create","target":"<NODE_UUID>"}}}'
    
    # undo that create (soft-deletes; needs destructive scope and if-match from get)
    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"undo","arguments":{"id":"<ACTIVITY_UUID>","base_updated_at":"<UPDATED_AT_FROM_GET>"}}}'

    Store a small PDF as a blob (synthetic example; get returns blob_id + sha256, not the bytes). Fetch bytes with GET /blobs/<BLOB_ID>:

    PDF_B64="$(printf '%s' '%PDF-1.1
    trailer<</Root 1 0 R>>
    %%EOF' | base64 -w0)"
    curl -sS http://127.0.0.1:8787/mcp \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -d "{\"jsonrpc\":\"2.0\",\"id\":6,\"method\":\"tools/call\",\"params\":{\"name\":\"upsert\",\"arguments\":{\"type\":\"note\",\"title\":\"Sample PDF\",\"payload\":{\"media_type\":\"application/pdf\",\"storage\":\"blob\",\"bytes_base64\":\"${PDF_B64}\"}}}}"
    
    curl -sS "http://127.0.0.1:8787/blobs/<BLOB_ID>" \
      -H "Authorization: ApiKey ${FOUNDATION_API_KEY}" \
      -o /tmp/sample.pdf

    User drop-box (no base64): copy a file into $FOUNDATION_DATA/uploads/ then upsert with payload.source_path set to the filename. The server moves it to blobs/<uuid>. uploads/ is mode 1777 (sticky); blobs/ stays 0700.

    FOUNDATION_DATA is the vault. Keep that directory. Stop the app, then Postgres. Do not delete the data folder.

Never point FOUNDATION_DATA at an agent profile or memory directory.

License

MIT © 2026 Foundation contributors

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A universal MCP server providing persistent, structured memory through a knowledge graph with graph storage, semantic vector search, and multi-hop traversal for AI agents and IDEs.
    1
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Agent-first knowledge graph MCP server that provides 25 tools for managing a knowledge graph with nodes and edges, plus a human-readable dashboard for LLMs and AI agents.
    465
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Knowledge-graph memory server for MCP-compatible AI tools, providing persistent, connected memory with typed relationships and auto-consolidation.
    71
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A local-first compiled knowledge graph MCP server that provides structured memory for AI agents with full-text search, vector embeddings, and timeline tracking.
    415
    8
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dgraziosi/foundation'

If you have feedback or need assistance with the MCP directory API, please join our Discord server