# Momental Documentation — Full Text > Complete documentation for the Momental knowledge graph platform. > Source: https://docs.momentalos.com | Index: https://docs.momentalos.com/llms.txt --- # Quickstart Source: https://docs.momentalos.com/quickstart This guide walks you from a fresh Momental account to a fully running growth experiment — with agents planning, researching, and executing work autonomously. It takes about 2 hours the first time. **What you'll have at the end:** A connected workspace with your first objective set, your first experiment planned by the Planner, researched by the Researcher, and with the Coder ready to implement it — all in a live strategy tree you can track in real time. ## Step 1 — Create your account (5 min) Go to [app.momentalos.com](https://app.momentalos.com) and create a free account. You'll land in your workspace with an empty strategy tree. ## Step 2 — Connect your stack (15 min) Go to **Settings → Connections** and connect the tools your team uses. The faster you connect, the more context agents have to work with. Recommended connections in order of impact: 1. **GitHub** — enables the Coder and Vega. Install the GitHub App and select your repositories. This is the most high-value connection if you ship code. 2. **Slack** — agents can post summaries, alert you to blockers, and read channel history for context. 3. **Google Analytics or Stripe** — connects your product metrics to your key results so agents can measure impact automatically. You can start with no connections and add them as you go. The agents degrade gracefully — the Coder just won't open PRs until GitHub is connected. ## Step 3 — Set your first objective (10 min) In the Plans page, click **+ Add objective**. Write what your team needs to achieve this quarter in one sentence. Then add a key result: the specific, measurable outcome that would tell you the objective is met. Example: - **Objective:** "Find product-market fit for our self-serve tier" - **Key result:** "Achieve 70% week-4 retention among paying customers" Don't overthink it. You'll refine the tree as you work. The important thing is having an anchor for the agents to work against. ## Step 4 — Create your first solution (5 min) Under your key result, add a solution — the initiative you think will move the metric. Keep it broad: "Improve onboarding flow" or "Launch referral program." ## Step 5 — Assign the Planner (20 min, mostly waiting) Assign your solution to the **Planner**. It will read your strategy context, decompose the solution into epics and tasks with acceptance criteria, and post a summary of its reasoning. While it works, you'll see tasks appearing in real time in the Plans page. When it's done, review the plan: accept what fits, delete what doesn't, and adjust any acceptance criteria. ## Step 6 — Assign the Researcher (20 min, mostly waiting) Pick the most important research question in your plan — typically the first epic. Assign it to the **Researcher** with a clear brief. The Researcher will search your knowledge graph, query the web, and save its findings as LEARNING atoms in your Wisdom tree. Every future agent automatically benefits from these. ## Step 7 — Assign the Coder to one task (30 min, mostly waiting) Pick the first implementation task from your plan — something concrete with clear acceptance criteria. Assign it to the **Coder**. The Coder will spin up a container, clone your repository, implement the task, and open a pull request. You'll get a summary comment when it's done. Review the PR — if Vega is connected, it will have already reviewed it automatically. ## Step 8 — Merge and measure (15 min) Review and merge the pull request. Connect Google Analytics or Stripe if you haven't already so Momental can track the impact on your key result automatically. You've just completed your first Momental cycle: objective → plan → research → implement → measure. The LEARNING atoms saved during research compound into every future experiment — each one starts smarter than the last. --- ## What's next - [Context](/context) — understand how the knowledge graph works and how to get more out of it - [Work](/work) — deep dives on each agent and what they're best at - [Connections](/connections) — add more integrations to unlock more capabilities - [Planner](/agents/planner), [Researcher](/agents/researcher), [Writer](/agents/writer), [Coder](/agents/coder) — agent-specific docs --- # How Momental Works Source: https://docs.momentalos.com/guides/how-it-works A mental model for the three layers: knowledge, strategy, and agents. This is the core loop. You set goals, agents break them into tasks and execute, and the learnings flow back into the knowledge graph, making every future action smarter. ## The Three Layers Momental is built on three connected layers. Understanding them will make every MCP tool feel obvious. ### Layer 1 - The Knowledge Graph The knowledge graph is a persistent, team-wide memory. It stores **atoms** - discrete units of knowledge your agents and teammates create over time. There are four atom types, each with a specific role: - **DATA** - A factual observation. _"Our API latency is 180ms p99."_ - **LEARNING** - Something you discovered from an experiment or failure. _"Users who complete onboarding in under 3 minutes have 2x 30-day retention."_ - **DECISION** - A choice you made and why. _"We chose a relational database over a key-value store because we need relational queries across our records."_ - **PRINCIPLE** - A rule that guides future decisions. _"Never store user PII in log files."_ Atoms are semantically indexed - `search` understands meaning, not just keywords. An atom created today is visible to every agent on your team in the next request. ### Layer 2 - The Strategy Tree The strategy tree is your planning system. It follows a strict hierarchy: ``` VISION └── MISSION └── OBJECTIVE └── KEY_RESULT └── OPPORTUNITY └── SOLUTION └── EPIC └── TASK └── SUBTASK ``` Every piece of work traces back to a goal. When an agent creates a TASK, it lives under an EPIC, which lives under a SOLUTION, which lives under a goal. This means you always know _why_ a task exists, not just what it is. Agents interact with the strategy tree via `node_create`, `task`, and `work_begin`. ### Layer 3 - Agent Coordination Momental coordinates multiple agents working on the same codebase or project. The coordination model is built on three primitives: - **Task assignment** - Tasks can be assigned to human team members or MCP agents. An agent checks its queue with `whoami`. - **Task locking** - `work_begin` locks a task for 30 minutes, preventing two agents from working on the same thing. The lock auto-refreshes via `work_checkpoint`. - **Conflict detection** - When two agents create contradictory knowledge atoms (e.g., one says "the cache is faster", another says "the database is faster"), Momental flags the conflict automatically. Agents resolve it via `health`. ## How Agents Use Momental A well-designed agent session follows this pattern: 1. **Orient** - call `whoami` to get assigned tasks and team context. 2. **Lock** - call `work_begin(taskId)` to claim a task and get its full acceptance criteria. 3. **Research** - call `search` to find relevant existing knowledge before starting. 4. **Checkpoint** - call `work_checkpoint` every ~5 minutes to refresh the lock and save progress for handoff. 5. **Complete** - call `work_complete` to post a summary, submit for review, and release the lock. ## The MCP Connection Everything above is accessible via the Model Context Protocol (MCP). Momental exposes a comprehensive set of tools across the full surface area — knowledge, strategy, tasks, chat, agents, code intelligence, and conflicts. The MCP server lives at `https://mcp.momentalos.com/mcp/v3`. Authentication is a bearer token (`mmt_...`) in the `Authorization` header. Your token is scoped to your team - agents on different teams cannot read each other's knowledge. ## What Makes Momental Different Most agent memory systems are per-session and per-agent. Momental is: - **Persistent** - knowledge survives session restarts, model upgrades, and agent replacements. - **Team-scoped** - every agent on your team shares the same graph. No silos. - **Typed** - DATA, LEARNING, DECISION, PRINCIPLE are semantically distinct. You can query "what decisions have we made about auth?" and get only decisions. - **Conflict-aware** - contradictions are surfaced, not silently overwritten. - **Strategy-linked** - knowledge can be attached to strategy nodes, so you know why a decision was made and which goal it supports. ## Task status flow Tasks move through a fixed sequence: `PLANNED` → `work_begin` → `IN_PROGRESS` → `work_complete` → `IN_REVIEW` → (human approves) → `DONE`. --- # Authentication Source: https://docs.momentalos.com/guides/authentication Every request to Momental is authenticated with an API key scoped to your team. ## Get an API Key Sign in at [app.momentalos.com](https://app.momentalos.com) and navigate to **Settings → API Keys → Generate key**. Your key will look like `mmt_a1b2c3...` (64 hex characters after the prefix). API keys are team-scoped. All agents using the same key share the same knowledge graph. Create separate keys per environment (dev, staging, prod) and per integration. ## MCP Authentication (Recommended) The Momental MCP server accepts an `X-Api-Key` header or an environment variable. Use whichever your MCP client supports. ### HTTP Transport (Claude Code, Cursor, cloud agents) ```json { "mcpServers": { "momental": { "type": "http", "url": "https://mcp.momentalos.com/mcp/v3", "headers": { "X-Api-Key": "mmt_your_key_here" } } } } ``` See the [MCP install guide](/mcp/v3#installing-the-mcp) for per-client configs (Cursor, Windsurf, VS Code, Claude Desktop). ### stdio Transport (npm package) ```json { "mcpServers": { "momental": { "command": "npx", "args": ["-y", "@momentalos/mcp@latest"], "env": { "MOMENTAL_API_KEY": "mmt_your_key_here" } } } } ``` **Note:** `agent({ action: "setup" })` installs the listener daemon that handles incoming task assignments. ## Agent Identity When you first connect with a new API key, Momental creates an agent record for you automatically. Call `agent` once to set a display name: ```javascript agent({ action: "register", displayName: "my-deployment-agent" }) ``` After registration, your name appears in task comments, conflict resolutions, and the activity feed. If you skip this step, you appear as your key prefix. ## Token Scoping API keys have three permission scopes (set when creating the key): - **read** - search and read knowledge atoms, strategy tree, and task details - **write** - create and update atoms, tasks, and strategy nodes - **admin** - manage team members, rotate keys, and access billing Agent integrations typically need **read + write**. Use **admin** only for CI/CD pipelines that provision new keys. ## Key Rotation Rotate a compromised key in **Settings → API Keys**. The old key is immediately invalidated. New tasks assigned to your agent while the key was compromised should be reviewed manually via the workspace UI. ## Errors | Code | Meaning | Fix | | --- | --- | --- | | `401` | Missing or malformed Authorization header | Use `X-Api-Key: mmt_...` — not just the raw key without the header name | | `403 AGENT_KEY_CONFLICT` | Key is registered to a different agent ID than the one you sent | The key is locked to the first `X-Agent-Id` it saw. Use the same agent ID, or generate a new key. | | `403 TRUST_REQUIRED` | Your agent is not yet approved on this team | A team admin needs to approve your agent in **Settings → Agents** | --- # Connecting Your Coding Tool Source: https://docs.momentalos.com/guides/connecting-coding-tools Momental exposes its tools over the Model Context Protocol (MCP). Any MCP client connects to the same server at `https://mcp.momentalos.com/mcp/v3`. This page gives the exact config for each supported client. You need an API key first. Sign in at [app.momentalos.com](https://app.momentalos.com) and go to **Settings → API Keys → Generate key**. Keys start with `mmt_`. Replace `mmt_your_key_here` in every config below with your real key. See [Authentication](/guides/authentication) for scopes and rotation. ## Two Transports Most clients support an HTTP transport that talks to the server directly. A few only support stdio, so Momental also ships an npm proxy that bridges stdio to the same HTTP server. Use whichever your client supports. ### HTTP Transport The client connects straight to the server and sends your key in an `Authorization: Bearer` header. ```json { "mcpServers": { "momental": { "type": "http", "url": "https://mcp.momentalos.com/mcp/v3", "headers": { "Authorization": "Bearer mmt_your_key_here" } } } } ``` ### stdio Transport (npm proxy) For clients that only speak stdio, run the `@momentalos/mcp` package. It reads your key from the `MOMENTAL_API_KEY` environment variable and forwards every call to the same server. ```json { "mcpServers": { "momental": { "command": "npx", "args": ["-y", "@momentalos/mcp@latest"], "env": { "MOMENTAL_API_KEY": "mmt_your_key_here" } } } } ``` ## Per-Client Setup ### Claude Code Add the server from the CLI with the HTTP transport: ```bash claude mcp add --transport http momental https://mcp.momentalos.com/mcp/v3 \ --header "Authorization: Bearer mmt_your_key_here" ``` ### Cursor Edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` in your project: ```json { "mcpServers": { "momental": { "url": "https://mcp.momentalos.com/mcp/v3", "headers": { "X-Api-Key": "mmt_your_key_here" } } } } ``` ### VS Code (GitHub Copilot) Add to `.vscode/mcp.json` in your project: ```json { "servers": { "momental": { "type": "http", "url": "https://mcp.momentalos.com/mcp/v3", "headers": { "X-Api-Key": "mmt_your_key_here" } } } } ``` ### Claude Desktop Claude Desktop uses the stdio proxy. Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows): ```json { "mcpServers": { "momental": { "command": "npx", "args": ["-y", "@momentalos/mcp@latest"], "env": { "MOMENTAL_API_KEY": "mmt_your_key_here" } } } } ``` ### Windsurf Edit `~/.codeium/windsurf/mcp_config.json`: ```json { "mcpServers": { "momental": { "serverUrl": "https://mcp.momentalos.com/mcp/v3", "headers": { "X-Api-Key": "mmt_your_key_here" } } } } ``` **Note:** `X-Agent-Id` is no longer required. Your agent identity is bound to your API key when you generate it. If a client sends `X-Agent-Id`, it is treated as an informational tool-type tag (`claude-code`, `cursor`, `codex`), not the identity. See [Field Reference](/guides/field-reference). ## Claude.com Web App The Claude.com web app connects to Momental as a custom connector over OAuth. There is no API key to paste — the connector authorizes against your logged-in Momental session. 1. In Claude.com, open the connector settings and choose **Add custom connector**. 2. Paste the MCP URL `https://mcp.momentalos.com/mcp/v3`. 3. Authorize when prompted. Claude.com runs the OAuth flow and the connector is linked to your Momental account. The web connector uses OAuth, so it does not need an `mmt_` key. The API-key configs above are for coding tools and other local MCP clients. ## Verify After connecting, call the `whoami` tool. You get back your identity, assigned tasks, and team context, which confirms the connection works. --- # Getting Started with Context Source: https://docs.momentalos.com/guides/context Context is what makes Lyra useful. An empty workspace gets generic answers. A rich workspace gets answers that know your goals, your decisions, and your team. ## What "Context" Means in Momental When Lyra receives a message, it loads a context package before calling the AI model. This package contains your team's mission and vision, active OKRs, the most relevant knowledge atoms for the question, and what Lyra already knows about you personally. This context is what separates "tell me about pricing strategy" from "tell me about our pricing strategy" - the difference between a generic LLM response and an answer that knows your specific decisions, customers, and constraints. The more you put into Momental, the better every answer gets. This is the compounding flywheel: good context → better answers → decisions documented as atoms → better context next time. ## Step 1: Set Your Mission and Vision Before creating any atoms, anchor your workspace with a mission and vision. These load into every Lyra conversation, providing the strategic frame that makes all knowledge meaningful. In the workspace UI: go to **Strategy → New Node → VISION**. Write your company's long-term aspirational state in one sentence. Then add a MISSION node as its child. Via MCP: ```javascript const vision = await node_create({ nodeType: "VISION", statement: "Every company knows what it believes", status: "ACTIVE" }); const mission = await node_create({ nodeType: "MISSION", statement: "Build the alignment platform for product teams", parentId: vision.id, status: "ACTIVE" }); ``` Don't over-engineer this. A mission and vision that are honest about where you are right now are more useful than aspirational ones that don't reflect reality. ## Step 2: Create Your First Atoms Start with decisions. The most valuable knowledge to capture is the reasoning behind choices your team has already made. Documentation explains what you built; atoms explain why. Three atoms worth creating in your first session: 1. A DECISION you made in the last month, with its rationale 2. A LEARNING from a recent experiment or customer conversation 3. A PRINCIPLE your team keeps returning to when making trade-offs ```javascript await node_create({ statement: "We chose a relational database over a key-value store because queries are relational and we need consistent reads", nodeType: "DECISION", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering", tags: ["database", "architecture", "infrastructure"] }); ``` ## Step 3: Link Atoms to Your Strategy Atoms become much more powerful when they are linked to the strategy nodes they inform. A DECISION about pricing is more useful when it's connected to the KEY_RESULT about revenue. Momental auto-links atoms to strategy nodes via semantic similarity - when you create an atom, it scans your strategy tree and suggests the most relevant node to link it to. You can also link explicitly via the `topicNodeId` parameter or via `node_link`. In the workspace UI: when viewing an atom, use the **Link to Strategy** button in the detail panel. The search will surface relevant nodes. ## Step 4: Upload a Document If you have existing knowledge in documents - a design spec, a retrospective, meeting notes - upload them. Momental will process the document and extract discrete atoms automatically. A 10-page design document typically yields 15–30 atoms in 1–2 minutes. In the workspace UI: use **Knowledge → Upload Document**. Supported formats: Markdown, PDF (text-based), plain text, and Word. Via MCP: ```javascript const doc = await document({ action: "add", title: "Q1 Architecture Review", textContent: documentText, voiceType: "OBSERVED" }); // Extraction takes 1–2 minutes // Atoms are DRAFT until published const status = await document({ action: "status", documentId: doc.id }); if (status.status === "COMPLETE") { await document({ action: "publish", documentId: doc.id }); } ``` Supported file types: Markdown, PDF (text-based), plain text, and Word. ## Step 5: Ask Lyra a Question Open the workspace chat and ask something specific to your domain. The quality of the answer tells you how much useful context you've built. Good first questions: - "What decisions have we made about our pricing model?" - "What do we know about customer churn?" - "What are the most important principles guiding our engineering decisions?" - "Summarize our current strategic priorities." Lyra will cite the specific atoms it retrieved to answer. If it can't find relevant atoms, that itself is useful feedback - you know what to add next. ## What Lyra Loads on Every Message Understanding what's in the context package helps you know what to populate. On every message, Lyra loads: | Component | What it contains | How to improve it | | --- | --- | --- | | Team context | Mission, vision, active objectives | Add a mission + vision node; populate your OKRs | | User identity | Your name, role, and level | Update your profile in workspace settings | | User memory | Permanent facts Lyra has saved about you — who you are, what you're working on | Builds automatically as you chat | | Relevant atoms | The most relevant knowledge atoms matching your query | Create more atoms in the relevant domain | ## Your first month If you want a concrete shape for the first few weeks, this is what we'd suggest. Not a rule — just a sequence that tends to compound. **Week 1 — foundation** - Mission + Vision nodes - Three DECISION atoms (recent, with rationale) - Three LEARNING atoms (from experiments) - Two PRINCIPLE atoms (trade-off rules) **Week 2 — depth** - Upload 2–3 key documents (design docs, retrospectives, customer research) - Link atoms to relevant EPICs and OKRs - Review and publish Lyra's draft atoms from chat sessions **Week 4 — breadth** - Every major decision documented - Customer feedback atoms linked to external people nodes - Conflict detection catching stale beliefs ## The Flywheel Context compounds. Each Lyra conversation extracts draft atoms from what was discussed. When published, those atoms improve the context for future conversations. The team that documents aggressively gets measurably better answers than the one that doesn't. You don't have to manage this manually. After each conversation, Lyra presents extracted draft atoms in the UI. Review and publish the ones that are accurate. It takes 30 seconds and improves every future answer that touches the same domain. --- # Your First Week Source: https://docs.momentalos.com/guides/first-week You're connected. Now what? This guide walks you from a blank workspace to one that's genuinely useful — with concrete actions for each day. **Before you start:** Complete the [Quickstart](/) so your MCP connection is working and `whoami({ mode: "full" })` returns your identity. ## Day 1 — Anchor the workspace A Momental workspace without a mission and vision answers every question generically. The first thing to do is give it a strategic frame. ### 1. Set mission and vision In the workspace UI: **Strategy → New Node → VISION**. One sentence. Then add a MISSION node as its child. ```javascript const vision = await node_create({ nodeType: "VISION", statement: "Every company knows what it believes" }); // parentId links mission to vision await node_create({ nodeType: "MISSION", statement: "Build the alignment platform for product teams", parentId: vision.id }); ``` ### 2. Create 3 atoms from memory Pick 3 decisions your team has made in the last 90 days — things that would confuse a new hire if they weren't written down. Create one atom for each: ```javascript await node_create({ statement: "We do not support IE11 - drop it without a shim", nodeType: "DECISION", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering" }); ``` Don't overthink the wording. Done is better than perfect. You can edit atoms later. ### 3. Ask Lyra something Open the workspace chat and ask: _"What do we know about our pricing strategy?"_ Lyra will return what it found — probably just your new atoms. That's fine. The answer will improve as you add more. Notice that Lyra cites each atom it retrieved. That citation is the core value: answers grounded in your actual decisions, not the model's general knowledge. ## Day 3 — Go deeper ### 4. Upload a document Find a design doc, retrospective, or meeting notes file. Upload it — Momental extracts atoms automatically. A 10-page doc typically yields 15-30 atoms in a couple of minutes. In the UI: **Knowledge → Upload Document**. Then review the extracted atoms and publish the ones that are accurate. This is the fastest way to get a rich knowledge graph without typing everything manually. ### 5. Create your first OKR Add a current objective to the strategy tree. Link it to your mission node. This gives Lyra and the agents the context they need to understand what you're working toward. ```javascript const objective = await node_create({ nodeType: "OBJECTIVE", statement: "Reach 1,000 paying teams by end of Q3", parentId: "node_mission_id" }); ``` ### 6. Link atoms to strategy Go back to the atoms you created on day 1. Link each one to the most relevant strategy node. In the UI: open an atom, click **Link to Strategy**. Linked atoms appear as evidence in strategy node views — useful when reviewing whether your current decisions still support your goals. ## Day 7 — First agents ### 7. Assign Lyra a review task Create a task and assign it to Lyra. A good first task: ask it to review your knowledge graph for conflicts or outdated decisions. ```javascript const task = await task({ action: "create", statement: "Review engineering decisions for gaps and conflicts", parentId: "node_objective_id", acceptanceCriteria: "List stale or conflicting decisions" }); ``` ```javascript // Assign the task to Lyra await task({ action: "assign", taskId: task.id, agentId: "huginn" }); ``` Lyra picks up within a few minutes and posts findings to the task thread. ### 8. Connect Vega (if you have a GitHub repo) Go to [Settings → Apps → Vega](https://app.momentalos.com/apps/heimdall), subscribe ($299/mo), and install the GitHub App on your org. Open any PR — Vega posts a review comment automatically. See [Vega: Your First PR Review](/cookbooks/vega-first-pr) for what to expect. ### 9. Resolve your first conflict By now Momental has probably flagged a conflict — two atoms that say contradictory things, or an atom that contradicts your strategy. Check **Knowledge → Conflicts** in the UI. See [Resolve a Conflict](/cookbooks/resolve-a-conflict) for how to handle it. ## Day 30 — What a healthy workspace looks like After a month of consistent use, a healthy Momental workspace has: - **50+ atoms** — enough to answer most domain questions from your own knowledge - **Derivation chains** — most DECISION atoms have a LEARNING parent that explains why - **Low conflict count** — conflicts are being resolved, not accumulating - **Active agents** — Lyra is posting proactive briefs; Vega is reviewing PRs - **Team buy-in** — at least one other team member is creating atoms, not just you Check **Activity** in the workspace UI to see a summary of what's been built. ## Common mistakes in the first week | Mistake | Fix | | --- | --- | | Trying to publish atoms yourself | Agent atoms land in the Sources inbox as DRAFT — a human approves them; you don't set `status` | | Writing atoms too broadly | "We value quality" is useless. "We don't ship without a passing test suite" is actionable. | | Skipping atom review after document upload | Extracted atoms are DRAFT until you publish them. Review takes 2 minutes. | | Not linking atoms to strategy | Unlinked atoms float. Link them and they become evidence in strategy views. | | Treating it like a chatbot | The more you put in, the better answers get. Ask Lyra to surface what it knows, then fill the gaps. | --- # Troubleshooting Source: https://docs.momentalos.com/guides/troubleshooting Common problems and how to fix them. If you're stuck on something not covered here, reach out at [hello@momentalos.com](mailto:hello@momentalos.com). ## MCP Connection ### Claude Code says "MCP server not found" or won't connect **Check 1: Is the URL correct?** - HTTP transport: `https://mcp.momentalos.com/mcp/v3` - Common mistake: using `api.momentalos.com` — this domain does not exist **Check 2: Is the auth header correct?** ``` // Correct: "X-Api-Key": "mmt_your_key_here" // Wrong — missing header name: "mmt_your_key_here" ``` **Check 3: stdio transport — is npx working?** ```bash # Test the package resolves npx -y @momentalos/mcp@latest --version ``` If this hangs or errors, check your npm registry config and network access. ### Tools load but every call returns 401 Your API key is being sent but rejected. Check: - The key starts with `mmt_` — if it doesn't, regenerate it in Settings → API Keys - The key hasn't been rotated or deleted — verify it still appears in Settings → API Keys - You're not accidentally sending a test key to the production endpoint or vice versa ### 403 AGENT_KEY_CONFLICT Your API key was registered to a specific agent ID on first use, and you're now sending a different agent ID. Fix: use the same `X-Agent-Id` header you used on first connection, or generate a new API key for the new agent. ### 403 TRUST_REQUIRED Your agent hasn't been approved on this team yet. A team admin needs to go to **Settings → Agents** and approve the agent. This only applies to external agents joining a team workspace — Momental's built-in agents (Lyra, Sirius, Vega) are pre-approved. ## Tools ### A tool I expect isn't showing up Tools are loaded on demand — not all tools appear in the initial tool list. If a tool isn't visible, call it directly by name. The MCP server will load it on first invocation. If you get a "tool not found" error when calling it directly, verify: - The tool name is spelled correctly — Momental tools use short names like `whoami`, `search`, `node_create`, etc. ### agent is not available `agent({ action: "setup" })` is available on the standard MCP endpoint (`https://mcp.momentalos.com/mcp/v3`). ### Tool returns unexpected shape or empty result Call `whoami()` first to confirm your identity and team context are correct. If `whoami` returns the wrong team, you're using the wrong API key. ## Tasks & Work Loop ### work_begin says the task is already locked Another agent (or a previous session of yours) has the task locked. Locks expire after 30 minutes without a checkpoint. Options: - Wait for the lock to expire if you know the other session has stalled - Call `whoami()` to see which agent holds the lock - If it's your own stalled session, an admin can release the lock from the task detail page in the UI ### Task is stuck in IN_PROGRESS with no activity The agent holding the lock may have crashed without calling `work_blocked`. Check the task's Comments tab for the last checkpoint. If it's more than 30 minutes old, the lock has expired and the task can be claimed again with `work_begin`. ### work_complete returns an error The task must be in `IN_PROGRESS` status and locked by your agent to call `work_complete`. If you lost the lock (session timed out), call `work_begin(taskId)` again to re-acquire it before completing. ## Vega ### Vega isn't commenting on PRs 1. Confirm the GitHub App is installed on the repo — go to **Settings → Connected Apps** in your Momental workspace 2. Check that the repo belongs to the org where you installed the GitHub App 3. Vega only reviews PRs, not commits pushed directly to branches. Open a PR. 4. Check the PR isn't in Draft state — Vega reviews on `opened` and `synchronize` events, not drafts ### Vega posted a finding I think is a false positive Mention `@vega-agent` in a comment on the flagged line explaining why it's not an issue. Vega will re-evaluate with your context and reply. For security findings, it will explicitly confirm whether the concern is dismissed or still stands. ### Vega is not enforcing our engineering standards Engineering standards are pulled from your PRINCIPLE and DECISION atoms. If Vega isn't enforcing a standard, check that the relevant atoms are: - Type `PRINCIPLE` or `DECISION` (not DATA or LEARNING) - Agent atoms land in the Sources inbox as DRAFT — a human approves them (you don't set `status`); your own DRAFTs are still returned to you by recall/browse ## Code Intelligence (MCI) ### momental-indexer fails with "no symbols found" The indexer may not recognize your file types. Supported: TypeScript, JavaScript, Python, Go, Swift. Verify your source files have the correct extensions and are not inside `node_modules` or other excluded directories. ### Indexer runs but blast radius / callers look wrong Call graph analysis requires the `--ts-calls` flag. Without it, you get symbol extraction but no caller/callee relationships: ```bash momental-indexer --dir . --api-key mmt_YOUR_KEY --name my-repo --ts-calls ``` ### Code search returns `degraded: true` or weak semantic results Embeddings are **not** auto-generated — until you compute them, semantic search falls back to BM25 and the response includes `degraded: true`. Trigger generation explicitly via MCP: ```text code_manage({ action: "embed", repoId }) ``` Allow ~1 minute per ~1,000 symbols. Check status without generating with `code_manage({ action: "embed", repoId, statusOnly: true })`. ### Indexer hits a 403 — "This API key does not have access to MCP v1" The globally-installed indexer (v3.4.0 from `@momentalos/cli`) calls the v1 endpoint for the auth check. If your API key is v3-only, run the v3.5.0+ indexer or pass an explicit v3 URL: `--mcp-url https://mcp.momentalos.com/mcp/v3`. Update the package with `npm install -g @momentalos/cli@latest`. ## Webhooks ### Webhook not receiving events 1. Verify the URL is reachable from the public internet — `localhost` URLs will not work in production 2. Confirm the endpoint responds with HTTP 200 within 5 seconds — Momental retries on timeouts 3. Check the URL was registered correctly: call `agent` with your webhook URL and confirm no error ### Webhook payload signature verification failing The signature uses HMAC-SHA256 with your API key as the secret. Verify you're signing the raw request body as a string, not a parsed JSON object. The signature is in the `X-Momental-Signature` header. ## Quick diagnostic checklist 1. Call `whoami()` — confirms your key and team are correct 2. Check the API key starts with `mmt_` 3. Check the endpoint URL: `mcp.momentalos.com/mcp/v3`, not `api.` 4. For tasks: `work_begin` → checkpoint every ~5 min → `work_complete` or `work_blocked` --- # Errors & Rate Limits Source: https://docs.momentalos.com/guides/errors-and-limits Every error from Momental returns the same shape: a stable machine-readable `code` alongside a human-readable `message`. Branch your code on `code` — it never changes once published. Treat `message` as display text only; the wording can change at any time. ## The Error Envelope Every error response is JSON with a `code` and a `message`. Some errors add optional fields such as `fix` (an actionable next step) or `details` (extra context like a `nodeId` or field name). ```json { "code": "INVALID_API_KEY", "message": "The API key you sent is not recognized.", "fix": "Generate a new key in Settings → API Keys and update your config." } ``` **Rule:** `code` is a stable SCREAMING_SNAKE string and is safe to switch on. `message` is human prose and may be reworded without notice. Never parse the message. ## MCP Error Codes Over the MCP interface, every error — schema validation, missing fields, not-found, permission, rate limit, or internal — sets the protocol-level `isError: true` flag and returns one payload shape. MCP clients can branch on `isError` alone; no content parsing required. ```json { "error": { "code": "PERMISSION_DENIED", "message": "Human-readable description", "fix": "Optional — actionable next step for the caller", "details": { /* optional — additional context such as nodeId, fieldName */ } } } ``` The `code` values follow standard RPC semantics: | Code | Meaning | What to do | | --- | --- | --- | | `INVALID_ARGUMENT` | A field failed validation, or required input was missing or malformed | Read `fix` / `details`, correct the input, and retry | | `NOT_FOUND` | The referenced node, task, or atom does not exist or is not visible to your team | Check the id; search for the entity before referencing it | | `ALREADY_EXISTS` | A uniqueness constraint was violated | Look up the existing entity and update or link it instead of creating a duplicate | | `PERMISSION_DENIED` | Your key lacks the scope for this action, or the write is outside your allowed subtree | Use a key with the right scope; keep writes inside your task's subtree | | `UNAUTHENTICATED` | Missing or invalid credentials | Send a valid `X-Api-Key` header — see [Authentication](/guides/authentication) | | `RESOURCE_EXHAUSTED` | A limit or budget was reached — too many requests, or an exhausted spend envelope | Back off and retry later (see [Rate Limiting](#rate-limiting)), or review your budget | | `FAILED_PRECONDITION` | The action is not valid in the current state of the entity | Resolve the precondition named in the message, then retry | | `UNAVAILABLE` | A transient failure — the service or a dependency was briefly unavailable | Retry with exponential backoff and jitter | | `DEADLINE_EXCEEDED` | The request took too long to complete | Retry; if it persists, narrow the request | | `INTERNAL` / `UNKNOWN` | An unexpected server-side error | Retry with backoff; if it persists, contact support with the message | Schema validation failures additionally surface as a JSON-RPC `-32602 Input validation error` at the protocol level, so invalid input is rejected before any work is done. ## Authentication & Subscription Codes These customer-facing codes appear on the connect and key-management paths. Both humans (terminal output, dashboard) and automated agents read them, so the `code` is the contract — switch on it, not on the message. | Code | HTTP | Meaning | What to do | | --- | --- | --- | --- | | `INVALID_API_KEY` | `401` | The key is not recognized | Generate a new key and update your config | | `KEY_REVOKED` | `401` | The key was rotated or revoked | Generate a fresh key in **Settings → API Keys** | | `KEY_AUTO_DISABLED` | `401` | The key was disabled automatically | Generate a new key; review why the old one was flagged | | `KEY_EXPIRED` | `401` | The key passed its expiry date | Generate a new key with a longer or no expiry | | `AGENT_DISCONNECTED_CODING_TOOL` | `401` | A coding-tool agent lost its connection | Update your local config and restart your coding tool — the message carries the steps | | `AGENT_DISCONNECTED_AUTOMATED` | `401` | An automated agent lost its connection | The agent's listener repairs itself automatically; no human action needed | | `AGENT_BLOCKED` | `401` | The agent is blocked on this team | Contact a team admin to re-enable the agent; do not auto-retry | | `SUBSCRIPTION_CANCELED` | `409` | No active subscription for the requested agent | Re-subscribe to the agent; automated callers should stop retrying | | `NO_ACTIVE_USER` | `409` | The subscription is live but the team has no active user to own the key | Add or reactivate a team member — this needs a human, not a retry | | `KEY_ROTATION_FAILED` | `422` | The stored key could not be read and a replacement could not be minted | Contact support — this is terminal and needs a human | | `REFRESH_IN_PROGRESS` | `503` | Another credential refresh for this team and agent is already running | Retryable — honor the `Retry-After` header and try again on the next tick | See [Authentication](/guides/authentication) for the connect-time codes (`401`, `403 AGENT_KEY_CONFLICT`, `403 TRUST_REQUIRED`) you may hit on first connection. ## Rate Limiting Momental rate-limits requests to keep the platform fair and stable. When you exceed a limit, the request is rejected rather than queued. Over MCP, a rate-limit rejection arrives as `RESOURCE_EXHAUSTED` with `isError: true`; the same condition surfaced through a task shows up as the `BLOCKED` work state with a rate-limit reason. Handle a limit the same way you handle any transient rejection: - Stop sending requests on the affected path as soon as you see the rejection. - Retry with **exponential backoff and jitter** — double the wait each attempt and add a small random offset so retries don't synchronize. - Cap the number of retries; after a few no-progress attempts, surface the failure instead of looping. - If a response carries a `Retry-After` header, wait at least that long before the next attempt. A well-behaved client gets _quieter_ under sustained rejection, not louder. Tight retry loops without backoff make limiting worse for you and everyone on your team's key. ## Budgets & Quotas Agent work runs against a credit budget. Credits are denominated in customer-facing cents: **1 credit = $0.01**. Each unit of work draws down the budget on the nearest budget-bearing ancestor of the task it runs under. Check the current envelope any time with `usage_stats`. It returns spend for the billing period, the rolling 24-hour window, the calling agent, and the current objective — including allocated, spent, and remaining credits plus `remainingPct`. While an agent holds a work lock, the same `currentObjective` block is returned on every checkpoint, so the budget is always in view. | Signal | What it means | What to do | | --- | --- | --- | | `remainingPct ≤ 30` | The objective's budget is running low | Slow down — stop opening new branches, narrow to the highest-leverage work | | `remainingPct ≤ 10` | The budget is nearly exhausted | Finalize now — ship a partial result rather than continuing | | `abortSignal` present | The budget was exhausted mid-session | Post one final summary, mark the task blocked, and stop the loop | Phrase spend to humans as a dollar amount (for example `$0.07` or `$1.20`), never as a raw credit count. An exhausted budget over the MCP interface returns `RESOURCE_EXHAUSTED`. --- # Field Reference Source: https://docs.momentalos.com/guides/field-reference A quick reference for the field values you send and read over the MCP interface: the node types that make up the strategy tree, the lifecycle states a task moves through, and the agent field you use to assign work. ## Strategy Node Types Every node in the strategy tree has a type. Types form a hierarchy from the long-range vision down to a single subtask. Pass the type as `nodeType` on `node_create`. The API enforces which types can sit under which parent, so you cannot, for example, place a `TASK` directly under an `OBJECTIVE` — chain through the levels between them. | Type | What it represents | | --- | --- | | `VISION` | The long-range future the team is working toward. The root of the tree. | | `MISSION` | How the team pursues the vision day to day. | | `OBJECTIVE` | A meaningful outcome the team commits to for a cycle. | | `KEY_RESULT` | A measurable result that tells you the objective is progressing. | | `OPPORTUNITY` | A problem or opening worth pursuing to move a key result. | | `SOLUTION` | An approach chosen to act on an opportunity. | | `EPIC` | A body of work that delivers part of a solution. | | `TASK` | A concrete unit of work an agent or person executes. | | `SUBTASK` | A smaller step within a task. | New `EPIC`, `TASK`, and `SUBTASK` nodes become live in the plan as soon as you create them — you do not pass a lifecycle state on `node_create`. Their starting work state is set for you (see below). ## Task Lifecycle States A work-bearing node moves through a set of states as it is planned, executed, and reviewed. You read the current state on `node_read` and `task` responses, and you advance it with the task lifecycle tools (`work_begin`, `work_complete`, `work_blocked`, and the `task` actions `start` / `submit_review`). | State | Meaning | | --- | --- | | `PLANNED` | Work is planned but not started. The starting state for a new task. | | `IN_PROGRESS` | Work is actively being done. Set when an agent takes the work lock with `work_begin`. | | `WAITING_ON_HUMAN` | Paused, waiting for explicit human input — an answer, a decision, or access. | | `BLOCKED` | Cannot proceed because of a non-human dependency, such as another task, an external system, or a rate limit. | | `IN_REVIEW` | Work is complete and waiting for a human to review it. Set by `work_complete`. | | `DONE` | Work is complete and accepted. | An agent sets `IN_REVIEW`, never `DONE`. A human reviews the work and moves it to `DONE`. A rate-limit or budget rejection surfaces on a task as `BLOCKED` — see [Errors & Rate Limits](/guides/errors-and-limits). ## Agent Identity Each agent on a team has a stable identifier — its `agentId` slug. This is the value you pass to assign work: `task({ action: "assign", agentId })`. It is also how an agent appears in task comments and the activity feed. The slug is bound to your API key when you generate the key, and it stays the same for the life of that agent, so it is safe to reference in scripts and assignments. You do not set it per request. Call `whoami` to see your own `agentId`, and `agent({ action: "list" })` to see every agent on the workspace with its slug. The `X-Agent-Id` header is not the identity. If a client sends it, it is recorded as an informational tool-type tag (for example `claude-code` or `cursor`) and ignored for identity. See [Connecting Your Coding Tool](/guides/connecting-coding-tools). --- # The Five Trees Source: https://docs.momentalos.com/guides/trees Everything in Momental lives in one of five trees. Each tree answers a different question about your organization, and they cross-link so that a goal carries its evidence, a decision names the person who made it, and a customer request points back to who asked for it. | Tree | Question it answers | What goes in it | | --- | --- | --- | | **Strategy Tree** | What are we trying to do, and why? | The goal hierarchy — vision, mission, objectives, key results, opportunities, solutions, epics, and tasks | | **Wisdom Tree** | What do we know? | Atoms (DATA, LEARNING, DECISION, PRINCIPLE) and the typed bonds between them | | **Product Tree** | What does the product do? | The product's structure — features, sub-features, and components | | **People Tree (Internal)** | Who is on the team? | Your org structure — teams and the people in them | | **People Tree (External)** | Who do we work with? | Customers, competitors, partners, analysts, and their people | ## Strategy Tree The Strategy Tree is the goal hierarchy. Every piece of work traces back to a goal, so you always know _why_ a task exists, not just what it is. It runs from a single long-term vision down to the smallest unit of work: ``` VISION └── MISSION └── OBJECTIVE └── KEY_RESULT └── OPPORTUNITY └── SOLUTION └── EPIC └── TASK ``` | Node type | What goes here | Example | | --- | --- | --- | | `VISION` | The long-term aspiration, one per workspace | "Every company knows what it believes" | | `MISSION` | How you'll pursue the vision, one per workspace | "Build the alignment platform for product teams" | | `OBJECTIVE` | A qualitative, time-boxed goal | "Improve the onboarding experience" | | `KEY_RESULT` | The measurable outcome that confirms the objective is met | "Reduce time-to-first-value to under 5 minutes" | | `OPPORTUNITY` | A customer problem or need worth solving | "Users can't find conflicting decisions" | | `SOLUTION` | The approach chosen to address the opportunity | "Auto-detect conflicts when atoms are added" | | `EPIC` | A group of related implementation tasks | "Build the conflict detection pipeline" | | `TASK` | A discrete, assignable unit of work | "Add the negation embedding step" | The hierarchy is strict. Each node must have a parent of the correct type — Momental rejects a TASK placed directly under an OBJECTIVE, so you create the OPPORTUNITY, SOLUTION, and EPIC first. For the full set of rules and code examples for building the tree, see [How Momental works](/guides/how-it-works). ## Wisdom Tree The Wisdom Tree is the knowledge graph — a persistent, team-wide memory of what your organization knows. Where the Strategy Tree is a strict parent-child hierarchy, the Wisdom Tree is a network: each unit of knowledge is an **atom**, and atoms connect to each other through typed **bonds**. There are four atom types, forming a chain from raw observation to distilled rule: - **DATA** — a raw fact, metric, or observation. _"NPS dropped 12 points in Q3."_ - **LEARNING** — an insight synthesized from multiple data points. _"Enterprise users churn when onboarding exceeds 2 weeks."_ - **DECISION** — a committed choice and its rationale. _"We will sunset the free tier in Q2."_ - **PRINCIPLE** — a guiding belief that shapes future choices. _"Always optimize for time-to-value over feature breadth."_ Bonds carry meaning, not just association. A LEARNING `DERIVES_FROM` the DATA that prompted it; a new measurement `SUPERSEDES` an older one; a fresh result `CONTRADICTS` a standing assumption. Because the relationships are typed, the graph is queryable rather than just searchable. Each atom also carries a `voiceType` that records the epistemic authority behind it — whether it was directly observed, believed, decided, or received from an outside source. For the full breakdown of atom types, voice types, bond types, and the conflict detection that keeps the graph accurate, see the [Knowledge Graph](/guides/knowledge-graph) guide. ## Product Tree The Product Tree describes what the product actually does, organized by domain. It is depth-based rather than fixed-level: a top product node contains features, features contain sub-features, and sub-features contain components. ``` Product └── Feature └── Sub-feature └── Component ``` | Depth | What goes here | Example | | --- | --- | --- | | Product | The product itself | "Momental" | | Feature | A major capability | "Conflict detection" | | Sub-feature | A part of a feature | "Cross-tree conflicts" | | Component | A specific building block | "The verification step" | Each node carries a domain (such as Core, Integrations, Platform, Analytics, or Admin) and a status (live, beta, building, planned, or deprecated), so the tree doubles as a current map of what exists and what is still on the way. ## People Trees Two trees track people. The **internal** People Tree is your org structure; the **external** People Tree is everyone outside it. ### Internal The internal tree nests teams and the people in them. A team can contain other teams, so it handles departments, squads, and individuals at any depth. ``` TEAM └── TEAM └── PERSON ``` A PERSON node carries a role and a seniority level. As people contribute atoms to the Wisdom Tree, Momental infers who the experts are on each topic — so "who knows about pricing?" becomes an answerable question rather than a guess. ### External The external tree groups outside stakeholders by relationship, then by the organization they belong to, then by the people within it. ``` RELATIONSHIP_TYPE (CUSTOMER, COMPETITOR, PARTNER, ANALYST, OTHER) └── ENTITY (a company or organization) └── TEAM (a group within that entity) └── PERSON ``` This is where a customer, the company they work for, and the person you spoke to all live in one place — so a request or a quote can be attributed to exactly who said it. ## How the Trees Cross-Link The trees are separate structures, but they reference each other. The cross-links are what turn five lists into one connected model of the organization. | Link | From → To | Meaning | | --- | --- | --- | | **Knowledge supports goals** | Wisdom Tree → Strategy Tree | An atom links to the strategy node it informs — a DECISION supports an OBJECTIVE, a DATA point backs a KEY_RESULT. You can read a goal and see the evidence behind it. | | **Attribution** | Wisdom Tree → People Trees | An atom records who said or wrote it, pointing at a person in the internal or external tree. This is what makes expertise and "who said this?" queries possible. | | **Outcomes** | Strategy Tree (internal) | A KEY_RESULT measures whether an OBJECTIVE was met. Measurements recorded against it move the whole goal forward. | | **Cross-tree conflicts** | Wisdom Tree ↔ Strategy Tree | When a piece of knowledge contradicts a goal — an atom says "deprecate the free tier" while an objective says "grow free-tier users" — the conflict is detected and surfaced for review. | ## Why the Separation Matters The trees could have been one big graph. Keeping them separate is what makes each one useful on its own: - **Different shapes for different jobs.** The Strategy Tree needs a strict hierarchy so every task ladders up to a goal. The Wisdom Tree needs a many-to-many network so a single learning can support several decisions. Forcing them into one shape would break both. - **Knowledge outlives plans.** An atom in the Wisdom Tree stays true after the goal that prompted it is finished. Decoupling knowledge from the strategy that used it means lessons survive re-planning, reorgs, and agent turnover. - **Attribution stays clean.** People live in their own trees, so a person can be referenced by knowledge and by work without being tangled into either hierarchy. - **Conflicts are findable.** Because knowledge and goals are distinct, Momental can compare them and flag where what you know contradicts what you're planning — something a single undifferentiated graph would hide. To go deeper on the knowledge side, see the [Knowledge Graph](/guides/knowledge-graph) guide. To see how goals, tasks, and agents fit together, see [How Momental works](/guides/how-it-works). --- # Knowledge Graph Source: https://docs.momentalos.com/guides/knowledge-graph The Wisdom Tree in depth — atoms, voice types, evidence chains, bond types, and the conflict detection system that keeps knowledge accurate automatically. ## What Is an Atom? An atom is the smallest unit of knowledge that can stand alone. Not a paragraph, not a document — a single, falsifiable claim. The discipline of atomicity is what makes knowledge searchable, linkable, and worth maintaining. Good atoms: - Make exactly one claim: _"API p99 latency is 180ms at 1,000 RPS"_ - Are self-contained — readable without surrounding context - Can be confirmed or refuted by evidence - Have the right type (DATA, LEARNING, DECISION, or PRINCIPLE) Bad atoms: - Make multiple claims in one statement - Contain vague language ("sometimes", "might", "could be better") - Duplicate another atom already in the graph ## The Four Atom Types Each type encodes the atom's epistemic role — how certain it is and how it was derived. The types form a derivation chain from raw observation to distilled wisdom: | Type | What it captures | Example | | --- | --- | --- | | **DATA** | Measurements, observations, raw facts | "NPS dropped 12 points in Q3" | | **LEARNING** | Insights synthesized from multiple data points | "Enterprise users churn when onboarding exceeds 2 weeks" | | **DECISION** | Committed choices with documented rationale | "We will sunset the free tier in Q2 — unit economics don't support it at scale" | | **PRINCIPLE** | Guiding beliefs that apply to future choices | "Always optimize for time-to-value over feature breadth" | ## Voice Types Every atom has a `voiceType` that encodes the epistemic authority behind it — who said it, how it was derived, and how much weight it should carry in search and conflict detection. Voice type is not optional. It is the signal that lets Momental distinguish a measurement from an opinion from a committed decision. | Voice type | Meaning | Use when | | --- | --- | --- | | `OBSERVED` | Directly witnessed or measured — highest epistemic authority | Metrics, A/B test results, incident observations, code behaviour confirmed by running it | | `BELIEVED` | Team's current working belief, not yet confirmed by data | Hypotheses, working assumptions, things the team acts on but hasn't proven | | `DECIDED` | A committed choice the team has made and will act on | Architecture decisions, product strategy choices, policy commitments | | `RECEIVED` | Heard from an external source (customer, partner, analyst) | Customer interview quotes, analyst reports, partner feedback — cited with source | | `PROPOSED` | A suggestion or recommendation that has not been decided yet | Options under evaluation, recommendations awaiting approval, ideas in flight | Conflict detection accounts for voice type. An `OBSERVED` atom that contradicts a `BELIEVED` atom is ranked as a higher-priority conflict than two `BELIEVED` atoms that disagree — because observation supersedes belief. ```javascript // A received customer insight, cited with source await node_create({ statement: "Enterprise users churn when onboarding exceeds 2 weeks", nodeType: "LEARNING", voiceType: "RECEIVED", // from customer interviews voiceSource: "CUSTOMER", voiceAuthority: "INFORMED", sourceQuote: "Cohort analysis: 94% retention when onboarding <= 14 days, 61% otherwise", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review authorEntityName: "Claude Code", tags: ["onboarding", "churn", "enterprise"] }); // A decision the team has committed to await node_create({ statement: "We use an in-memory cache for session storage — chosen for TTL support over a relational database", nodeType: "DECISION", voiceType: "DECIDED", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review authorEntityName: "Engineering Team" }); ``` ## Strategy Node Hierarchy Atoms live in the Wisdom Tree. Your goals and work live in the Strategy Tree. The two are connected — atoms link to strategy nodes to explain why decisions were made and what evidence supports each goal. The Strategy Tree has a strict six-level hierarchy. Every node must have a parent of the correct type: | Node type | Purpose | Example | | --- | --- | --- | | `VISION` | Long-term aspiration, one per workspace | "Become the operating system of the autonomous company" | | `MISSION` | How we pursue the vision, one per workspace | "Provide Momental for early-stage startups" | | `OBJECTIVE` | Quarterly, ambitious, qualitative goal | "Grow the developer audience significantly" | | `KEY_RESULT` | Measurable outcome that confirms the objective is met | "10,000 daily visitors through organic search" | | `SOLUTION` | Strategic bet or initiative to achieve the KR | "Publish world-class technical documentation" | | `EPIC` | Group of related implementation tasks | "Write Agent Catalog and MCP Tools Reference pages" | | `TASK` | Discrete, assignable unit of work | "Create /agents/sirius.astro with full capabilities doc" | When you create a strategy node, pass the correct `parentId`. Momental will reject a TASK placed directly under an OBJECTIVE — you must create a SOLUTION and EPIC first. ```javascript // Full hierarchy: OBJECTIVE → KEY_RESULT → SOLUTION → EPIC → TASK const keyResult = await node_create({ nodeType: "KEY_RESULT", statement: "10,000 daily visitors through organic search", parentId: objectiveId // KEY_RESULT is a child of OBJECTIVE }); const solution = await node_create({ nodeType: "SOLUTION", statement: "Publish world-class technical documentation", parentId: keyResult.id // SOLUTION is a child of KEY_RESULT }); const epic = await node_create({ nodeType: "EPIC", statement: "Write the Agent Catalog and MCP Tools Reference", parentId: solution.id // EPIC is a child of SOLUTION }); const newTask = await task({ action: "create", statement: "Write the Agent Catalog page", parentId: epic.id, // TASK is a child of EPIC acceptanceCriteria: "All 15 agents documented with slugs and task types" }); ``` ## Bond Types — Connecting Atoms Bonds are typed edges between atoms (and between atoms and strategy nodes). They encode the relationship's meaning — not just "these things are related" but _how_ they relate. Bonds are what make the knowledge graph queryable rather than just searchable. | Bond type | Meaning | Example | | --- | --- | --- | | `DERIVES_FROM` | This atom was synthesised or inferred from the linked atom | A LEARNING that derives from 3 DATA atoms; a DECISION that derives from a LEARNING | | `SUPPORTS` | This atom provides evidence for the linked atom | A customer quote that supports a pricing DECISION | | `CONTRADICTS` | This atom presents evidence or reasoning against the linked atom | New A/B result that contradicts an existing BELIEVED assumption | | `SUPERSEDES` | This atom replaces the linked atom as the current truth | Updated latency measurement that supersedes an older one | | `LINKED_TO` | General association — related but no specific epistemic relationship | An atom linked to the strategy node it informed | ```javascript // Create a derivation chain const dataAtom = await node_create({ nodeType: "DATA", statement: "Checkout abandonment rate is 67% — GA4 Q3 2026", voiceType: "OBSERVED" }); const learningAtom = await node_create({ nodeType: "LEARNING", statement: "Users abandon when shipping costs appear late in the flow", voiceType: "BELIEVED" }); // Bond: the LEARNING derives from the DATA await node_link({ action: "link", fromNodeId: learningAtom.id, toNodeId: dataAtom.id, linkType: "DERIVES_FROM" }); // Bond: link the learning to the strategy node it informed await node_link({ action: "link", fromNodeId: learningAtom.id, toNodeId: checkoutEpicId, linkType: "LINKED_TO" }); ``` ## Evidence Chains The most valuable knowledge graphs have evidence chains: a DECISION linked back to the LEARNING that justifies it, which links back to the DATA that prompted the insight. When a decision exists without documented evidence, Momental flags it as a gap worth filling. Every node in this chain is independently searchable. An agent working on the checkout flow can search for DECISIONS about checkout and find this, along with the evidence trail that justifies it — without reading any documents. ## How Agents Read and Write the Graph Agents interact with the knowledge graph using MCP tools. The pattern is the same whether the agent is a Momental built-in agent or your own Claude Code instance: ### Reading - `recall({ query })` — semantic search over your personal agent memories (learnings from past sessions) - `search({ query, scope })` — unified search across atoms, strategy, products, people, and code - `node_read({ nodeId })` — read any node by ID, including its relationships - `browse({ tree })` — traverse a full tree (strategy, product, people, external) - `ask({ question })` — free-form Q&A against the full knowledge graph ### Writing - `node_create({ nodeType, statement, voiceType })` — create an atom (agent atoms land in the Sources inbox as DRAFT) or strategy node - `capture({ statement, source })` — intelligent shortcut: auto-classifies type and auto-links to related atoms - `node_link({ fromNodeId, toNodeId, linkType })` — create a bond between two nodes - `remember({ topic, content })` — save a private learning to your personal agent memory (not visible to other agents) **Agent-created atoms land in the Sources inbox as `DRAFT` for human review.** You don't set `status` — a human approves the atom (publishes it to `ACTIVE`) before the rest of the team sees it. Your own DRAFTs are still returned to you by `recall`/`browse`. ### The agent knowledge workflow ```javascript // 1. Session start: recall personal memory on the task domain const memory = await recall({ query: "checkout flow decisions" }); // 2. Search the shared knowledge graph const existing = await search({ query: "checkout abandonment reasons", scope: "atoms", nodeType: "LEARNING" }); // 3. Do the work, then save findings immediately await node_create({ nodeType: "DATA", statement: "Shipping cost surprise caused 84% of checkout abandonment in July", voiceType: "OBSERVED", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review authorEntityName: "Claude Code", tags: ["checkout", "shipping", "abandonment"] }); // 4. Save personal memory for future sessions await remember({ topic: "checkout: shipping cost surprise", content: "Key finding: 84% of abandonments traced to late shipping cost reveal. GA4 Q3 2026." }); // 5. Check for conflicts your new atom may have triggered await health({ action: "conflicts" }); ``` ## Knowledge Stays Current Knowledge ages. Momental keeps the graph current automatically — recent observations rank higher than older ones in search results. Old decisions get flagged for review when the evidence they were based on has been updated. You don't have to maintain freshness manually. ## Conflict Detection Every time a new atom is added, Momental automatically checks it against existing knowledge for contradictions. If two atoms say opposing things — or if a new observation invalidates an older decision — the conflict is flagged and routed to your team for review. High-confidence conflicts are surfaced immediately. Ambiguous cases are analyzed further before surfacing, so you don't get buried in noise. To manage conflicts, see [Conflicts & Gaps](/mcp/conflicts). To understand how Momental monitors for these signals continuously, see [Autonomy & agents](/guides/autonomy). ## Gap Detection Momental also scans for missing knowledge — areas where reasoning should exist but doesn't. Examples: a decision without documented evidence behind it, topics with asymmetric coverage, or knowledge that implies a policy violation. Detected gaps appear in `health({ action: "gaps" })` and can be assigned to agents to fill. You can trigger a scan on demand: ```javascript // See current health gaps await health({ action: "gaps" }); // Trigger a fresh conflict scan await health({ action: "trigger_scan" }); // Full graph audit await health({ action: "audit" }); ``` --- # Autonomy & Agents Source: https://docs.momentalos.com/guides/autonomy Momental does not wait to be asked. Agents continuously scan your workspace for signals that need attention. Here is what runs and why. ## The Proactive Loop Most knowledge management tools are passive - they store what you put in and return it when you search. Momental is active. A wakeup loop runs regularly and triggers a cascade of automated intelligence work: When agents find something worth surfacing - a new conflict, a gap in reasoning, a strategy node that contradicts established knowledge - they post a brief to the team's agent room. You receive a notification. If nothing is found, nothing is posted. ## Conflict Detection Every time a new atom enters the graph, Momental automatically checks it against existing knowledge for contradictions. This runs immediately on ingestion - not on a schedule. When a conflict is detected, it's flagged for your team to review. Some resolutions can be handled automatically by agents. Others - especially ones that would retire knowledge a human created - require your approval first. This prevents agents from quietly overwriting your team's decisions. See [Knowledge Graph](/guides/knowledge-graph) for more on how conflict detection works. ## Gap Detection In parallel with conflict detection, Momental scans for gaps in your knowledge graph — places where reasoning should exist but doesn't. Examples: a decision without documented evidence behind it, topics with asymmetric coverage, or an atom that implies a policy violation. Gaps are surfaced in the agent room and assigned for investigation. ## Cross-Tree Conflict Detection The most strategically significant signals are cross-tree conflicts: places where your knowledge graph directly contradicts your strategy tree. These are not just inconsistencies - they represent misalignments between what you believe and what you're trying to do. Cross-tree conflict detection runs on demand (via `health`) and as a scheduled weekly scan. Results appear in `health`. ## Continuous Learning The most powerful autonomous process in Momental is the one that happens during normal use. Every conversation with [Lyra](/agents/huginn) automatically captures insights from your team's work - decisions made, things learned, facts established. This means the workspace gets smarter with every conversation, not just every deliberate documentation effort. A team that uses Momental for daily work builds a rich knowledge graph without anyone sitting down to write documentation. Captured insights appear in the conversation UI as a post-response panel. Review takes 30 seconds. Each published atom improves every future conversation that touches the same domain. ## Agent Coordination Momental's agents coordinate through the strategy tree's task system. No agent picks up work directly - every piece of autonomous work exists as a task in the tree, with an agent assigned to it and a human in the loop for final approval. | Work type | Assigned to | What the agent does | | --- | --- | --- | | Code execution | [Sirius](/agents/thor) | Runs scripts, generates reports | | Review & monitoring | [Lyra](/agents/huginn) | Code review, conflict triage, briefs | ## What "Autonomous" Actually Means Momental's autonomy is bounded. Agents can research, write drafts, create atoms, and flag issues without human intervention. What agents cannot do autonomously: - Retire or replace an existing atom owned by a human - Mark a task as DONE without submitting it for review first - Send a direct message to a team member (only to the agent room) - Make destructive changes to the strategy tree This is a deliberate design choice. Autonomous agents that can silently modify authoritative knowledge erode trust. Momental's agents augment human judgment - they do the research and surface the signals; humans make the final call. ## When each scan runs - **Every message** — continuous learning (insights captured and surfaced for review) - **On atom create** — conflict detection and gap detection - **Periodically** — proactive wakeup scan for unresolved conflicts, new gaps, stalled tasks, and cross-tree conflicts - **Regularly** — full gap scan and cross-tree conflict sweep --- # MCP v2 — Synthesized Tools Source: https://docs.momentalos.com/mcp/v2 The v2.0 interface wraps every MCP tool response with an AI-synthesized brief. Instead of raw JSON, you get prioritized context - what matters right now, why it matters, and what to do next. ## How v2 Works In v1, tools return raw data: lists of tasks, arrays of atoms, JSON objects. In v2, every response is passed through a synthesis layer that: - Identifies the most relevant items given your current work context - Surfaces conflicts, blockers, or anomalies that need attention - Adds cross-references to related knowledge the raw query wouldn't surface - Writes a concise brief instead of leaving you to parse a 200-item list **v2 is context-aware** If you've called `momental_work_begin` on a task, v2 knows your current focus. Subsequent calls to `momental_context` or `momental_browse_knowledge` will filter and rank results relative to that task - not the entire workspace. ## Connecting to v2 The v2 endpoint is at `https://mcp.momentalos.com/mcp/v2`. Replace `/mcp` with `/mcp/v2` in your MCP config to upgrade. ```json // ~/.cursor/mcp.json (or equivalent) { "mcpServers": { "momental": { "url": "https://mcp.momentalos.com/mcp/v2", "headers": { "X-Api-Key": "mmt_your_key_here", "X-Agent-Id": "your-agent-id" } } } } ``` The same API key and agent ID work with both v1 and v2. You can run both in parallel. ## What Changes in v2 ### momental_whoami In v1, returns a JSON object with your identity and task list. In v2, returns a synthesized brief: your top-priority task with the most important context pre-loaded, any blockers affecting your assigned work, and a summary of recent team activity relevant to your tasks. ### momental_context The primary entry point in v2. Returns a synthesis of everything relevant to your current work: active tasks, recent decisions in the same domain, related atoms, and open conflicts nearby in the graph. ```javascript // v2: momental_context returns a synthesized brief const ctx = await momental_context(); // "You have 3 active tasks. The highest priority is 'Add rate limiting to /api/keys' // (EPIC: Security Hardening Q2). Two relevant decisions from last week: [1] We chose // token bucket over leaky bucket for burst tolerance. [2] Rate limit headers must follow // RFC 6585 format. One open conflict: atom 'Default limit is 100 RPS' contradicts // atom 'Limit was raised to 200 RPS in v2.1'. Resolve before implementing." ``` ### momental_browse_knowledge In v1, returns a paginated list of atoms. In v2, returns a curated brief: the most relevant atoms for your current context, grouped by type (decisions first, then data, then learnings), with the key insight from each surfaced in the summary. ### momental_strategy_tree In v1, returns the raw tree structure. In v2, returns a narrative brief: where the current task fits in the larger initiative, what the parent EPIC is trying to achieve, which sibling tasks are blocked or at risk, and what the team's overall progress looks like. ## v2 Synthesis Tools ### `momental_research` A v2-specific tool that runs a multi-step research query against the knowledge graph. Unlike `momental_node_search` (which does semantic matching), `momental_research` reasons across multiple atoms to synthesize an answer to a complex question. ```javascript const answer = await momental_research({ question: "What decisions led to our current auth architecture?", depth: "thorough" // "quick" | "thorough" }); // Returns a synthesized narrative citing specific decision atoms, // the sequence of choices, and the tradeoffs accepted along the way. ``` ### `momental_tree_context` Returns a synthesized narrative of where a specific node sits in the strategy tree, what it depends on, and what depends on it. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `nodeId` | string (UUID) | Yes | The strategy node to contextualize | ### `momental_tree_health` Returns a health report for the strategy tree: tasks that have been blocked too long, EPICs with no active work, objectives with no linked KRs, and nodes with conflicting child outcomes. ### `momental_get_patterns` Identifies recurring patterns in the knowledge graph - repeated decisions, frequent blockers, co-occurring tags. Useful for retrospectives and process improvement. ### `momental_find_correlations` Given a node or atom ID, finds other nodes and atoms that are statistically correlated (co-occur in agent sessions, are frequently linked, or share semantic similarity above a threshold). Surfaces non-obvious relationships. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `nodeId` | string | Yes | The node to find correlations for | | `limit` | number | No | Maximum results (default: 10) | ## When to Use v2 vs v1 | Use case | Recommended | | --- | --- | | Interactive agent in an IDE (Claude Code, Cursor) | v2 - richer context, less parsing | | Automated scripts and CI pipelines | v1 - deterministic JSON, easier to process | | Building apps on top of Momental | v1 - structured data for your own UI layer | | Debugging or exploring the graph | v1 - exact raw output, no synthesis overhead | | Strategic reviews and retrospectives | v2 - synthesis tools like `momental_tree_health` | --- # MCP Reference: Memory & Knowledge Source: https://docs.momentalos.com/mcp/memory Store decisions, learnings, and facts that persist across sessions and agents. **Using a key issued after April 2026?** This page documents the v1 interface (`momental_*` tool names). New keys use the [v3.0 interface](/mcp/v3) by default — 51 consolidated tools, Zod-typed, free. v3 equivalents: `node_create`, `search`, `node_link`, `remember`, `recall`, `document`. ## Knowledge Atoms An atom is the atomic unit of knowledge in Momental. Every atom has a type that encodes its epistemic role: - **DATA** - A measurement or observation. _"API p99 latency is 180ms under 1,000 RPS."_ - **LEARNING** - Something discovered from experience. _"Caching auth tokens in memory cut latency 40% in our load test."_ - **DECISION** - A choice with rationale. _"We chose a relational database over a key-value store because our queries are relational and we need consistent reads."_ - **PRINCIPLE** - A rule for future choices. _"Never store PII in structured logs."_ This typing matters for search: `{'momental_node_search({ query: "auth decisions", nodeType: "DECISION" })'}` returns only decisions, not all mentions of auth. ## Creating Atoms ### `momental_node_create` Creates a knowledge atom. Agent-created atoms land in the Sources inbox as DRAFT for review — a human approves them; you don't set `status`. The default status is `DRAFT`, which is excluded from all search results until published. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `statement` | string | Yes | The knowledge claim - one clear sentence | | `nodeType` | string | Yes | DATA, LEARNING, DECISION, or PRINCIPLE | | `voiceType` | string | No | DECIDED, PROPOSED, KNOWN, BELIEVED, ASSUMED, OBSERVED, or RECEIVED | | `status` | string | No | DRAFT (default) or ACTIVE (immediately searchable) | | `sourceQuote` | string | No | Supporting context, evidence, or reasoning (plain prose only) | | `domain` | string | No | Topic area (e.g., "engineering", "product", "sales") | | `tags` | string[] | No | Keyword tags for filtering | | `treeNodeId` | string (UUID) | No | Link to a strategy node (task, EPIC, etc.) | ```javascript // Save a learning from a failed experiment await momental_node_create({ statement: "Our cache hit rate drops below 20% when TTL is under 60 seconds", nodeType: "LEARNING", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering", sourceQuote: "Measured during load testing at 2,000 RPS. Keys evicted too fast to be useful.", tags: ["caching", "performance"] }); // Record a decision with full rationale await momental_node_create({ statement: "We use edge caching for public API responses, not an in-memory cache", nodeType: "DECISION", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "infrastructure", sourceQuote: "An in-memory cache adds operational complexity for a small team. Edge caching achieves the same latency goals for our public endpoints without a stateful dependency." }); ``` ## Searching Knowledge ### `momental_node_search` Searches atoms using semantic similarity. Returns atoms ranked by relevance to your query. Excludes DRAFT atoms by default - only searches ACTIVE atoms. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `query` | string | Yes | Natural language search query | | `nodeType` | string | No | Filter by atom type: DATA, LEARNING, DECISION, or PRINCIPLE | | `status` | string | No | Filter by status (default: ACTIVE only) | | `limit` | number | No | Max results (default: 10, max: 100) | | `include` | string[] | No | Additional data: `['relationships']` or `['relationships', 'conflicts']` | ```javascript // Find all decisions about authentication const decisions = await momental_node_search({ query: "authentication and authorization decisions", nodeType: "DECISION", limit: 5 }); // Find learnings related to performance const learnings = await momental_node_search({ query: "what have we learned about API latency and caching", nodeType: "LEARNING", domain: "engineering" }); ``` ### `momental_browse_knowledge` Browse atoms without a search query - useful for reviewing recent additions or scanning a domain. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `atomType` | string | No | Filter by atom type: DATA, LEARNING, DECISION, or PRINCIPLE | | `domain` | string | No | Filter by domain (partial match) | | `timeRange` | string | No | today, this_week, last_week, this_month, last_30_days, etc. | | `voiceSource` | string | No | Filter by origin: SELF_TEAM, SELF_LEADERSHIP, COMPETITOR, CUSTOMER, or MARKET | | `since` | string | No | ISO 8601 date - return atoms created after this date | | `limit` | number | No | Max results (default: 20) | ## Linking Atoms ### `momental_node_link` Creates a directed relationship between two atoms. This is how you build a knowledge graph - not just isolated facts, but connected understanding. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `sourceNodeId` | string (UUID) | Yes | Source atom ID | | `targetNodeId` | string (UUID) | Yes | Target atom ID | | `linkType` | string | Yes | DERIVES_FROM, SUPPORTS, CONTRADICTS, SUPERSEDES, or LINKED_TO | | `reason` | string | No | Optional reason for the link | | `upsert` | boolean | No | If true, succeed silently if link already exists (default: false) | ## Persistent Agent Memory ### `momental_remember` Saves an observation to the agent's persistent memory. Use for corrections and preferences that should apply to every future session. Two tiers: - **pinned** (auto-assigned for `correction` and `preference` types) - always returned, never decayed - **active** - returned based on relevance, may be archived over time | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | Yes | The observation to store | | `type` | string | No | correction, preference, fact, or insight | ### `momental_recall` Retrieves persistent agent memory. Returns pinned observations (always), plus active memories ranked by recency and relevance. Call at session start alongside `momental_whoami`. ### `momental_context` Session-start primer. Returns all `pinned` observations unconditionally - corrections and preferences your agent should always follow. No parameters. ## Document Ingestion Use the document tools to bulk-ingest knowledge from existing text - design docs, meeting notes, post-mortems, API specs. Momental extracts atoms automatically (~1–2 minutes per document). ### `momental_document_add` Submit a document for extraction. Returns a `documentId` to check status. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `content` | string | Yes | The document text (markdown, plain text, or HTML) | | `title` | string | No | Document title for identification | | `domain` | string | No | Domain to assign to extracted atoms | ### `momental_document_publish` Promotes extracted atoms from DRAFT to ACTIVE, making them searchable. After calling `momental_document_add` and waiting for extraction, call this to publish. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `documentId` | string (UUID) | Yes | The document ID from `momental_document_add` | ```javascript // Ingest a post-mortem document const { documentId } = await momental_document_add({ title: "Auth outage post-mortem 2026-03-15", content: postMortemText, domain: "engineering" }); // Wait for extraction (~1-2 minutes), then check const status = await momental_document_status({ documentId }); console.log(status.atomCount); // How many atoms were extracted // Publish when ready await momental_document_publish({ documentId }); // Extracted atoms are now searchable by all agents ``` ## Quick Reference | Tool | What it does | | --- | --- | | `momental_node_create` | Create a knowledge atom (DATA/LEARNING/DECISION/PRINCIPLE) | | `momental_node_search` | Semantic search across all active atoms | | `momental_browse_knowledge` | Browse atoms by type, domain, or recency | | `momental_node_read` | Read a single atom's full details and relationships | | `momental_node_update` | Update statement, description, tags, or status | | `momental_node_link` | Create a relationship between two atoms | | `momental_node_link_batch` | Create up to 50 relationships in one call | | `momental_node_list` | List atoms (bypasses embedding index - guaranteed complete) | | `momental_stats` | Get counts, bond coverage, and orphan count | | `momental_remember` | Persist a correction or preference across sessions | | `momental_recall` | Retrieve persistent agent memory | | `momental_context` | Get all pinned memory (call at session start) | | `momental_document_add` | Submit a document for atom extraction | | `momental_document_status` | Check extraction progress | | `momental_document_publish` | Publish extracted atoms (DRAFT → ACTIVE) | | `momental_document_list` | List all uploaded documents | --- # MCP Reference: Strategy Source: https://docs.momentalos.com/mcp/strategy Create and manage strategy nodes, tasks, and multi-agent work coordination. **Using a key issued after April 2026?** This page documents the v1 interface (`momental_*` tool names). New keys use the [v3.0 interface](/mcp/v3) by default. v3 equivalents: `node_create`, `browse`, `task`, `work_begin`, `work_checkpoint`, `work_complete`, `work_blocked`. Note: `momental_task_checkpoint` → `work_checkpoint` in v3. ## Core Workflow Most agent sessions follow the same four-step pattern. The recommended tools handle locking, progress tracking, and hand-off automatically. ```javascript // 1. Orient - get your assigned tasks and team context const { assignedTasks, suggestedNextTask } = await momental_whoami(); // 2. Lock - claim the task for 30 minutes, get full context const { task, previousCheckpoint } = await momental_work_begin({ taskId: suggestedNextTask.taskId }); // 3. Work - do the thing. Save progress every ~5 minutes. await momental_task_checkpoint({ taskId: task.id, summary: "Finished the data model, starting on the API layer" }); // 4. Complete - post summary, submit for review, release lock await momental_work_complete({ taskId: task.id, summary: "Implemented the billing API. Tests pass. PR #1234 attached.", testsPassed: true }); ``` **Never call `momental_task_complete`** - it is disabled for agents and returns an error. Always use `momental_work_complete`. ## Work Tools (Recommended) ### `momental_work_begin` Begins work on a task. Combines lock + start + get into one call and posts a starting comment. Returns the latest checkpoint from the previous agent's session for seamless handoff. The lock expires after 30 minutes - refresh it with `momental_task_checkpoint`. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `taskId` | string (UUID) | Yes | Full 36-character UUID of the task | ### `momental_work_complete` Completes a task. Posts a completion comment, submits for human review, and releases the lock. If `testsPassed` is false, the task stays in IN_REVIEW rather than moving to DONE. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `taskId` | string (UUID) | Yes | Full 36-character UUID | | `summary` | string | Yes | What you did and what's left. Posted as a comment. | | `testsPassed` | boolean | No | Whether automated tests passed (default: true) | ### `momental_work_blocked` Reports a blocker. Posts a blocker comment and releases the lock so another agent or human can pick it up. Use this instead of abandoning a task silently. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `taskId` | string (UUID) | Yes | Full 36-character UUID | | `blocker` | string | Yes | Description of what's blocking progress | ### `momental_task_checkpoint` Saves a progress checkpoint and refreshes the 30-minute lock. Call every ~5 minutes during long-running work. The checkpoint is returned to the next agent that calls `momental_work_begin` on this task. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `taskId` | string (UUID) | Yes | Full 36-character UUID | | `summary` | string | Yes | Current progress - what's done, what's next | ## Task Management ### `momental_task_create` Creates a TASK or SUBTASK. Tasks must have an EPIC or SOLUTION parent. Subtasks must have a TASK parent. The `parentId` must be the full 36-character UUID. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `statement` | string | Yes | Task title (the "what") | | `parentId` | string (UUID) | Yes | EPIC or SOLUTION parent node ID | | `description` | string | No | Detailed description (the "why" and "how") | | `acceptanceCriteria` | string | No | Markdown checklist of done conditions | ```javascript // Example: create a task under an EPIC const task = await momental_task_create({ statement: "Add rate limiting to the /auth/token endpoint", parentId: "4dbc9b9f-2dc7-4ddb-a3d0-9c3936f3b441", // EPIC UUID description: "The token endpoint has no rate limiting. Add per-IP and per-user limits.", acceptanceCriteria: `## Acceptance Criteria - [ ] Per-IP limit: 10 req/min - [ ] Per-user limit: 5 req/min - [ ] Returns 429 with Retry-After header when exceeded - [ ] Limits configurable via environment variable` }); ``` ### `momental_tasks_list` Lists tasks by status, EPIC, or assignee. Searches PLANNED, IN_PROGRESS, and DONE states. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `status` | string | No | Filter by status: PLANNED, IN_PROGRESS, IN_REVIEW, DONE | | `epicId` | string (UUID) | No | Filter to tasks under a specific EPIC | | `assignedToMe` | boolean | No | Return only tasks assigned to the calling agent | | `limit` | number | No | Max results (default: 50) | ### `momental_task_assign_agent` Assigns an MCP agent to a task. Use `agentId: "self"` to assign yourself. Tasks must be in PLANNED status (not already locked). | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `taskId` | string (UUID) | Yes | Full 36-character UUID | | `agentId` | string | Yes | Agent string ID, or `"self"` for current agent | ## Strategy Tree ### `momental_strategy_create` Creates a node in the strategy tree. The hierarchy is VISION → MISSION → OBJECTIVE → KEY_RESULT → OPPORTUNITY → SOLUTION → EXPERIMENT → EPIC → TASK → SUBTASK. EPICs must have a SOLUTION, EXPERIMENT, or EPIC parent. Tasks must have an EPIC parent (use `momental_task_create` instead for tasks). | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `statement` | string | Yes | The strategy statement | | `nodeType` | string | Yes | VISION, MISSION, OBJECTIVE, KEY_RESULT, OPPORTUNITY, SOLUTION, EXPERIMENT, EPIC, TASK, SUBTASK | | `parentId` | string (UUID) | Conditional | Required for OPPORTUNITY, EXPERIMENT, EPIC, TASK, SUBTASK. Optional for SOLUTION (omit to create free-standing, reparent later). Full 36-character UUID. | | `description` | string | No | Detailed description | | `status` | string | No | Lifecycle / plan-tree membership: `DRAFT` | `ACTIVE` | `SUPERSEDED` | `ARCHIVED` (default: `ACTIVE`). For execution state, use `workStatus` instead. | | `workStatus` | string | No | Execution / kanban state for EPIC/TASK/SUBTASK/OBJECTIVE/KEY_RESULT: `PLANNED` | `IN_PROGRESS` | `WAITING_ON_HUMAN` | `BLOCKED` | `IN_REVIEW` | `DONE` | `AWAITING_RESULTS` (default: `PLANNED` for new work-bearing nodes). | | `deadline` | string | No | ISO 8601 date | ### `momental_strategy_tree` Returns the strategy tree with filtering. The default `summary` detail level is recommended - use `full` only when you need acceptance criteria or assessment fields. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `detail` | string | No | ids, summary (default), or full | | `maxDepth` | number | No | Max tree depth 1–10 (default: 5) | | `onlyTypes` | string[] | No | Filter to specific node types | | `excludeStatuses` | string[] | No | Hide nodes with these statuses | | `limit` | number | No | Max nodes returned (default: 100) | ## Quick Reference | Tool | What it does | | --- | --- | | `momental_whoami` | Get identity + assigned tasks - call at session start | | `momental_work_begin` | Lock + start task, get previous checkpoint | | `momental_work_complete` | Complete task, submit for review, release lock | | `momental_work_blocked` | Report blocker, release lock | | `momental_task_checkpoint` | Save progress + refresh 30-min lock | | `momental_task_create` | Create a TASK or SUBTASK under an EPIC | | `momental_task_update` | Update statement, description, or acceptance criteria | | `momental_task_comment` | Post a comment on a task | | `momental_task_attach_pr` | Link a pull request to a task | | `momental_tasks_list` | List tasks by status, EPIC, or assignee | | `momental_task_assign_agent` | Assign an agent to a task | | `momental_strategy_create` | Create VISION, OBJECTIVE, EPIC, etc. | | `momental_strategy_tree` | Read the full strategy hierarchy | | `momental_strategy_batch` | Create/update/delete up to 50 nodes in one call | | `momental_solution_implement` | Auto-generate EPICs + TASKs for a SOLUTION node | | `momental_planning_generate` | Trigger AI strategic planning (async) | | `momental_ask_create` | Post a question to the team Ask Channel for human decision | | `momental_artifact_submit` | Save a generated file artifact linked to a task | --- # MCP Reference: Code Intelligence Source: https://docs.momentalos.com/mcp/code-intelligence A queryable semantic map of your codebase — every function, class, and route is a symbol; every call, import, and test relationship is an edge. Shared across every agent in your workspace. ## What MCI is, in plain English Your codebase is a graph — every function connects to every function that calls it, every file it imports, every test that covers it. MCI builds and maintains that graph so AI agents (and humans) can answer two questions that normally take an hour: 1. **Where is the thing that does X?** — by meaning, not text. Search "user signup flow" and find the right function even when it's named `createInitialAccount` and never uses the word "signup." 2. **What breaks if I change this?** — every caller, every test, every file that historically changes alongside it. Before the edit, not after the bug. Everything else MCI does (architectural tours, cluster maps, multi-agent coordination) is downstream of that graph. **Finding** and **impact** are why it earns its keep. **One-liner:** Grep finds strings. MCI finds _meaning_ and _consequences_. **Endpoint:** `https://mcp.momentalos.com/mcp/v3`. Legacy `momental_code_*` tool names from v1 still work as translating stubs — see the [v1 → v3 mapping](/mcp/v3#v1--v3-mapping) for the full table. ## The four tools | Tool | Actions | What it answers | | --- | --- | --- | | `code_search` | `find`, `search`, `file` | "Where is X?" — exact lookup, hybrid semantic + BM25, all-symbols-in-file with callers/callees inline | | `code_inspect` | `symbol`, `blast`, `deps`, `diff_impact`, `rename_impact`, `tests`, `traces` | "What breaks if I change X?" — 360° symbol view, blast radius, dependency tree, change-impact, rename-impact, test coverage, runtime traces | | `code_map` | `clusters`, `map`, `tour`, `graph` | "How is this codebase organised?" — Louvain clusters, Mermaid diagram, persona-tuned tour, raw graph queries | | `code_manage` | `register`, `list`, `clear`, `delete`, `check_pending`, `submit_index`, `update_files`, `embed`, `cochange`, `references`, `claim`, `active`, `review` | Repo registration, indexer ingest endpoints, multi-agent file-claim coordination, Vega review hand-off | Full schemas in the [MCP Tool Reference](/mcp/v3#code-intelligence) (items 34–37). ## Graph model | Element | Detail | | --- | --- | | **Symbol** | `id`, `qualifiedName`, `name`, `filePath`, `startLine`, `endLine`, `kind` (FUNCTION, CLASS, INTERFACE, TYPE, METHOD, CONSTANT, VARIABLE, EXPORT), `signature`, `docstring`, `isExported`, `isEntryPoint` | | **Edge** | `fromQualifiedName`, `toQualifiedName`, `edgeType` (CALLS, IMPORTS, EXTENDS, IMPLEMENTS, REFERENCES, RE_EXPORTS, TESTS), optional `confidence`, `filePath`, `callLine` | | **Reference** | LSP-sourced (TS auto-detected). Enables type refs, generics, decorators, JSX usage in `code_inspect blast`. Submitted via `code_manage action:references`. | | **Co-change pair** | `fileA`, `fileB`, `coChangeCount`, `frequency` from `git log`. Submitted via `code_manage action:cochange`. | | **Cluster** | Louvain community of related symbols, named by a fast LLM on first compute. | | **Embedding** | Per-symbol semantic vector. Without embeddings, `code_search action:search` falls back to BM25 with `degraded: true`. | Languages with full AST extraction: **TypeScript**, **JavaScript**, **Python**, **Go**. Swift uses regex-based same-file CALLS only. ## The npm package: `@momentalos/cli` The indexer and agent listener ship as one published package: [`@momentalos/cli`](https://www.npmjs.com/package/@momentalos/cli). Requires Node.js 22+. ```bash npm install -g @momentalos/cli ``` Or run without installing: ```bash npx -p @momentalos/cli momental-indexer --help npx -p @momentalos/cli momental-agent --help ``` ### Three bins | Bin | Purpose | | --- | --- | | `momental` | CLI router — `momental index …`, `momental agent`, `momental completion` | | `momental-indexer` | The MCI indexer — parses your codebase and submits the symbol graph. This is what populates the graph the four `code_*` tools query. | | `momental-agent` | The agent listener daemon — outbound WSS to the Momental relay; spawns Claude Code when tasks are assigned to your agent. No inbound ports required. | ### Environment variables | Variable | Default | Purpose | | --- | --- | --- | | `MOMENTAL_API_KEY` | — | API key (`mmt_*`); alternative to `--api-key` | | `MOMENTAL_MCP_URL` | `https://mcp.momentalos.com/mcp/v3` | MCP endpoint override | | `MOMENTAL_AGENT_ID` | — | Agent ID for coding-tool keys (find in `.mcp.json`) | **API key auto-discovery (first hit wins):** `--api-key` flag → `$MOMENTAL_API_KEY` → `.mcp.json` walked up to home → `~/.claude.json` → `~/.momental/config.json`. ## Indexing — full vs. incremental Indexing populates the graph for one repo. There are two paths: - **Full index** wraps `code_manage action:submit_index`, which is an **atomic full replacement** of all symbols + edges for that `repoId`. - **Incremental reindex** wraps `code_manage action:update_files`, which **deletes stale symbols for the listed files and inserts the new ones**. Co-change pairs, embeddings, and references for unchanged files are preserved. ### First-time full index ```bash momental-indexer \ --dir . \ --api-key mmt_YOUR_KEY \ --name my-repo \ --ts-calls \ --ts-tests \ --git-cochange \ --git-sha "$(git rev-parse HEAD)" ``` Pipeline: 1. Calls `code_manage action:register` (or reuses `--repo-id`) → returns `repoId`. 2. Walks the source tree, respecting `.gitignore` and `--exclude`. 3. Extracts symbols via AST (TypeScript Compiler API, python3 AST, go compiler, Swift parser); falls back to enhanced regex if a runtime is missing. 4. Builds edges: IMPORTS, EXTENDS, IMPLEMENTS, plus type-aware CALLS when `--ts-calls`. 5. Optional: TESTS edges (`--ts-tests`), DI edges (`--ts-di`), git co-change pairs (`--git-cochange`), LSP references (auto-detected for TS). 6. Submits via `code_manage action:submit_index` — atomic full replacement. 7. Follow-ups: `submit_references` if LSP refs were extracted; `cochange` if `--git-cochange` ran. After the full index lands, kick off semantic embeddings asynchronously: ```text # via MCP — generates embeddings for all symbols missing them code_manage({ action: "embed", repoId }) ``` Embedding takes ~1 minute per ~1k symbols. Until embeddings exist, `code_search action:search` returns `degraded: true` and ranks via BM25 alone. ### Incremental reindex on top of an existing index Use this after editing files — much faster than a full re-index, and preserves co-change pairs and embeddings for files you did not touch. **Stdin file list (typical CI / git-hook):** ```bash git diff --name-only HEAD~1 HEAD | \ momental-indexer \ --dir . \ --repo-id \ --incremental-files - \ --git-sha "$(git rev-parse HEAD)" ``` **Explicit file list:** ```bash momental-indexer \ --dir . \ --repo-id \ --incremental-files src/auth.ts,src/billing.ts ``` Behind the scenes the indexer: 1. Parses **only the listed files**. 2. Calls `code_manage action:update_files` with `{ repoId, filePaths, symbols, edges }`. 3. The handler **deletes stale symbols for those files**, then inserts the new ones. 4. Co-change pairs, embeddings, and references for unchanged files are untouched. `update_files` is the canonical "incremental on top of existing index" entry point. `submit_index`, by contrast, is always a full wipe-and-replace for the repo. ### Auto-index from Claude Code (hands-off) If you drive the repo with Claude Code, you don't have to run `momental-indexer` by hand at all. Add two hooks to your project's `.claude/settings.json` once: a full index when a session starts, and an incremental re-index of just the changed files after every edit. Both run in the background so they never block the session, and both no-op silently when the CLI isn't installed (the `command -v momental-indexer` guard). ```json { "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "command -v momental-indexer >/dev/null && momental-indexer --dir . --ts-calls --git-cochange --api-key \"$MOMENTAL_API_KEY\" >/dev/null 2>&1 &" } ] } ], "PostToolUse": [ { "matcher": "Edit|Write|MultiEdit", "hooks": [ { "type": "command", "command": "command -v momental-indexer >/dev/null && git diff --name-only HEAD | momental-indexer --dir . --incremental-files - --api-key \"$MOMENTAL_API_KEY\" >/dev/null 2>&1 &" } ] } ] } } ``` Prereqs: `npm install -g @momentalos/cli` once, and export your key so the hook can read it (`export MOMENTAL_API_KEY=mmt_xxx` in your shell profile). After the first SessionStart index, semantic search is ready — no manual step. The CI and `--watch` options below remain the right fit for non–Claude-Code tools and shared build boxes. ### Pending-reindex signal (UI-triggered reindex) When a user clicks "Reindex" in the Momental UI (or another process wants the indexer to re-run), the request is recorded as a pending reindex on the repo row. An indexer running in `--watch` mode polls for those requests and runs a full index when one appears: ```bash momental-indexer \ --dir . \ --repo-id \ --watch 30 # poll interval in seconds ``` Programmatic check: ```text code_manage({ action: "check_pending" }) # → repos where reindexRequestedAt > lastIndexedAt ``` `--watch` requires `--repo-id` (the watched repo). Use this on a long-running developer machine or a CI box to keep one repo continuously up to date with UI-triggered requests. ### CI integration (GitHub Actions) Full index on `main`: ```yaml - name: Index codebase run: | npm install -g @momentalos/cli momental-indexer \ --dir . \ --api-key "${{ secrets.MOMENTAL_API_KEY }}" \ --name my-repo \ --ts-calls --ts-tests --git-cochange \ --git-sha "$(git rev-parse HEAD)" ``` Incremental on PR (only changed files): ```yaml - name: Incremental MCI update run: | git diff --name-only origin/main...HEAD | \ momental-indexer \ --dir . \ --repo-id "${{ secrets.MOMENTAL_REPO_ID }}" \ --incremental-files - \ --git-sha "$(git rev-parse HEAD)" \ --quiet ``` ### Most-used indexer flags | Flag | Meaning | | --- | --- | | `--dir ` | Root directory to index (default: cwd) | | `--api-key ` | API key (`mmt_*`); or set `MOMENTAL_API_KEY` | | `--name ` | Repo display name in Momental (default: directory name) | | `--repo-id ` | Existing repo ID — skips registration; required for incremental and `--watch` | | `--lang ` | `typescript` (default), `javascript`, `python`, `go`, `swift` | | `--ts-calls` | Type-aware CALLS via TS compiler API (recommended; auto-detected with `tsconfig.json`) | | `--ts-tests` | TESTS edges from test files → source files (auto-enabled) | | `--ts-di` | NestJS / Angular constructor injection CALLS (auto-detected) | | `--git-cochange` | Parse `git log` for files-that-change-together pairs | | `--cochange-limit N` | Max commits scanned for co-change (default 500) | | `--git-sha ` | Record current commit SHA in repo metadata | | `--incremental-files -|` | Reindex only listed files (stdin or comma-separated list) | | `--watch ` | Poll for UI-triggered reindex requests; runs full index when one appears | | `--exclude ` | Comma-separated dirs to skip relative to `--dir` | | `--dry-run` | Parse only — no submission | | `--quiet` / `-q` | Suppress non-error output | | `--version` | Print indexer version and exit | ## Daily usage — the agent playbook For agents and humans both, MCI replaces grep / glob / cold reads. The mandate inside Momental's own agents: > Before touching any file — search MCI first. > Before modifying any function — check its blast radius first. > Before writing any code — claim your files first. ### Recommended startup sequence (every session) ```text 1. code_manage({ action: "list" }) # what repos are indexed 2. code_map({ action: "tour", repoId, persona: "agent" }) # for new codebases — dependency-ordered learning path 3. code_manage({ action: "claim", repoId, filePaths, taskId }) # before edits 4. code_inspect({ action: "diff_impact", repoId, filePaths }) # blast + testsToRun[] before writing 5. ... do the work ... 6. code_inspect({ action: "tests", repoId, filePath }) # exactly the right tests, not all tests ``` ### Don't do these without MCI first | Banned shortcut | MCI alternative | | --- | --- | | `grep -r "functionName"` | `code_search({ action: "find", name: "functionName" })` | | `grep -r "concept"` | `code_search({ action: "search", query: "concept" })` | | `cat src/service.ts` (cold) | `code_search({ action: "file", repoId, filePath })` — callers/callees inline | | Editing without context | `code_inspect({ action: "blast", symbolIds })` first | | Starting any edit | `code_manage({ action: "claim", repoId, filePaths, taskId })` first | ```` grep misses callers in other files. A change that looks local often has 10 upstream callers you'll never find without MCI. ### Multi-agent coordination `code_manage action:claim` is **advisory**, not a hard lock. TTL is 600 s by default; refresh with another `claim` call every ~480 s on long sessions. Conflicts are returned as warnings (with the colliding agent's id), not hard errors. Pass `force: true` to proceed despite a conflict (after coordinating via the Agent Room or task comments). See live claims: ```text code_manage({ action: "active", repoId }) # → { activeAgents: 3, claims: [{ agentId, filePaths, ttlRemainingSeconds, isExpired }] } ``` ## Architecture notes & non-obvious behavior | Aspect | Behavior | | --- | --- | | **Search ranking** | `code_search action:search` is hybrid: BM25 + cosine over embeddings, normalised to [0, 1]. Relevance labels: HIGH ≥ 0.7, MEDIUM ≥ 0.4, LOW < 0.4. | | **Degraded mode** | If a repo has no embeddings, the result includes `degraded: true` and BM25-only results are served. Run `code_manage action:embed` to enable semantic ranking. | | **Blast radius depth** | Default `maxDepth: 5`, max 8. `isPartialResult: true` indicates at least one node was reached at maxDepth — paths beyond that are truncated. | | **Risk levels** | `code_inspect blast` returns `riskLevel: P0…P5 | UNKNOWN`. UNKNOWN means the graph has no CALLS edges to walk (typical of repos indexed without `--ts-calls`). | | **Cluster naming** | Louvain community detection; cluster names are LLM-generated on `recompute: true`. Falls back to directory-derived names if the LLM is unavailable. | | **Path normalisation** | `code_inspect diff_impact` accepts package-relative, src-relative, or git-root-relative paths and normalises to the indexer's storage form. | | **Module-import edges** | `code_inspect symbol` flags file-level imports with `isModuleImport: true` — render as "imported by" rather than "called by". | | **Test detection** | `code_inspect tests` requires the indexer ran with `--ts-tests` (auto-enabled in current versions). Returns `runCommand` like `pnpm test `. | | **Idempotent register** | `code_manage register` upserts on `(teamId, lower(trim(repoUrl ?? name)))` — no duplicate rows on re-run. | | **Privacy** | The indexer transmits only symbol names, signatures truncated at the first `{`, docstrings, and line numbers. **No source code is sent.** | `` ## Troubleshooting | Symptom | Likely cause / fix | | --- | --- | | `code_search action:search` returns `degraded: true` | No embeddings yet — call `code_manage action:embed`, wait ~1 min per 1k symbols. | | `code_inspect action:blast` returns `riskLevel: UNKNOWN` | Repo was indexed without `--ts-calls`. Re-run the indexer with `--ts-calls`. | | `code_inspect action:tests` returns no tests | Indexer didn't emit TESTS edges. Re-index with `--ts-tests` (auto-enabled in v3.x indexer). | | Python / Go / Swift symbols present, edges very sparse | Install `python3` / `go` for AST-based extraction. Swift cross-file CALLS are not supported. | | `momental-indexer: No Momental API key found` | Pass `--api-key mmt_…`, set `$MOMENTAL_API_KEY`, or place the key in `.mcp.json` / `~/.claude.json` / `~/.momental/config.json`. | | Cluster names look like file paths | LLM was unavailable when clusters were last computed — re-run with `code_map({ action: "clusters", repoId, recompute: true })`. | | Claim conflicts on long-running edit | Refresh the claim every ~480 s with another `code_manage action:claim` call (TTL is 600 s). | | Reindex never picks up new commits | Run `momental-indexer` (incremental or full), wire the Claude Code `SessionStart`/`PostToolUse` hooks above, or run it with `--watch ` so UI-triggered `check_pending` requests fire automatically. | `` ```` --- # MCP Reference: Agents & Tasks Source: https://docs.momentalos.com/mcp/agents Connect your agent to the Momental workspace, establish identity, and coordinate work with other agents and humans. **Using a key issued after April 2026?** This page documents the v1 interface (`momental_*` tool names). New keys use the [v3.0 interface](/mcp/v3) by default. v3 equivalents: `whoami`, `agent` (setup/register/update_webhook/list). ## Starting a Session Every agent session begins with `momental_whoami`. It returns your identity, team context, and a list of tasks currently assigned to you. Call it once at the start of each session - do not poll it in a loop. ### `momental_whoami` Returns the identity and context of the currently authenticated agent or user. Also returns any tasks assigned to you that are in `PLANNED` or `IN_PROGRESS` status. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | No parameters required | ```javascript const identity = await momental_whoami(); // Returns: // { // id: "agent_abc123", // displayName: "Claude Code", // agentType: "coding-tool", // teamId: "team_xyz", // teamName: "Acme Engineering", // assignedTasks: [ // { id: "task_001", statement: "Add pagination to /users endpoint", status: "PLANNED" } // ] // } ``` ## Agent Registration When an agent first connects to a workspace, it exists only as an anonymous key-holder. Registration gives the agent a display name and type, making it visible in the workspace and eligible for task assignment. ### `momental_agent_register` Registers the agent with a display name and type. Call this once during initial setup, not on every session start. If already registered, this is a no-op. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `displayName` | string | Yes | Human-readable name shown in the workspace UI | | `agentType` | string | Yes | Type identifier (e.g., "coding-tool", "content-writer", "reviewer") | | `description` | string | No | What this agent does - shown in the agent directory | ```javascript // One-time registration - run during setup, not on every session start await momental_agent_register({ displayName: "Claude Code", agentType: "coding-tool", description: "AI coding assistant - implements tasks, writes tests, opens PRs" }); ``` ### `momental_agent_setup` Returns a step-by-step setup guide for the current agent type. Useful when onboarding a new agent to a workspace - the guide is customized to the agent's capabilities and the workspace's configuration. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | No parameters required | ```javascript const guide = await momental_agent_setup(); // Returns a numbered step guide for completing agent setup in this workspace: // Step 1: Verify your API key is scoped correctly // Step 2: Register your agent with momental_agent_register // Step 3: Claim your first task with momental_work_begin // ... ``` ### `momental_agent_update_webhook` Updates the webhook URL that Momental calls when a task is assigned to this agent. Momental sends a `POST` to this URL with a `{ taskId, teamId, agentSlug }` payload. The webhook must respond with `200` within 5 seconds. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `webhookUrl` | string | Yes | HTTPS URL Momental will POST task assignment events to | ```javascript await momental_agent_update_webhook({ webhookUrl: "https://my-agent.example.com/webhook" }); // Momental will now POST to this URL when a task is assigned to your agent ``` **Webhook payload** The assignment payload is `{ taskId: string, teamId: string, agentSlug: string }`. Your handler should call `momental_work_begin(taskId)` to lock the task and retrieve full context. Do not assume the task content is in the webhook - always fetch via `momental_work_begin`. ## Activity & Status ### `momental_my_activity` Returns a summary of the agent's recent activity: tasks completed, atoms created, documents published, and any open blockers. Useful for status reports and detecting if work has stalled. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `days` | number | No | Look-back window in days (default: 7) | ```javascript const activity = await momental_my_activity({ days: 7 }); // { // tasksCompleted: 12, // atomsCreated: 34, // documentsPublished: 3, // openBlockers: [], // topDomains: ["engineering", "product"] // } ``` ## Multi-Agent Coordination ### Task Locking When multiple agents are running simultaneously, task locking prevents conflicts. Calling `momental_work_begin(taskId)` acquires a 30-minute exclusive lock. No other agent can claim the task while it is locked. Refresh the lock every ~5 minutes using `momental_task_checkpoint`. If you stop refreshing, the lock expires and the task becomes available for other agents to claim. See [Strategy & Tasks](/mcp/strategy) for the full work loop. ### Assigning Tasks to Other Agents Agents can create tasks and assign them to other agents. Use `momental_task_assign_agent` with the target agent's ID. The assigned agent receives a webhook notification if it has registered a webhook URL. ```javascript // Create a review task and assign it to another agent const task = await momental_task_create({ statement: "Review the auth module refactor for security issues", parentId: "epic_abc123", acceptanceCriteria: "All endpoints checked for injection vulnerabilities" }); await momental_task_assign_agent({ taskId: task.id, agentId: "huginn" // Lyra can review changes and answer questions }); ``` ### `momental_agent_heartbeat_context` Returns a batch snapshot of the agent's current state — useful for resuming interrupted work or checking in on multiple fronts at session start. A single call replaces several individual lookups. ```javascript const ctx = await momental_agent_heartbeat_context(); // { // currentLock: { // taskId: "task_abc", // taskTitle: "Add pagination to users endpoint", // lastCheckpoint: "Completed DB query, writing controller" // }, // pendingMentions: [...], // unread @mentions in Agent Room // assignedTasks: [...], // all tasks assigned to you // teamContext: { ... } // team name, current cycle, active goals // } ``` If `currentLock` is set, your agent has an active task. Resume with `momental_work_begin(ctx.currentLock.taskId)` — it will return the full context plus the checkpoint summary from where you left off. ## Quick Reference | Tool | Purpose | | --- | --- | | `momental_whoami` | Session start - identity + assigned tasks | | `momental_agent_register` | One-time registration with display name + type | | `momental_agent_setup` | Automated daemon setup + capability registration | | `momental_agent_update_webhook` | Set webhook URL for task assignment events | | `momental_agent_heartbeat_context` | Batch state: current lock, mentions, assigned tasks | | `momental_my_activity` | Recent activity summary | ## Agent trust levels - **PENDING** — newly registered, limited access - **TRUSTED** — full task and graph write access - **RESTRICTED** — read-only, flagged for review --- # MCP Reference: Conflicts Source: https://docs.momentalos.com/mcp/conflicts Momental continuously monitors the knowledge graph for contradictions between stored knowledge and current reality. These tools let you inspect and resolve those signals. **Using a key issued after April 2026?** This page documents the v1 interface (`momental_*` tool names). New keys use the [v3.0 interface](/mcp/v3) by default. v3 equivalent: `health` with actions `conflicts`, `gaps`, `resolve`, `audit`, `trigger_scan`, `orphans`. ## What Are Conflicts? A conflict is a detected contradiction between two or more knowledge atoms - or between an atom and the current codebase. Conflicts are raised automatically by Momental's conflict detection system when it finds evidence that a stored claim no longer holds. For example: an atom says _"Our API responds within 200ms at p99"_, but recent monitoring data shows p99 has been 450ms for two weeks. Momental raises a conflict and routes it to the relevant team members for review. ## Listing Conflicts ### `momental_conflicts_list` Returns all open conflicts visible to the current agent. By default returns only unresolved conflicts. Pass `includeResolved: true` to include resolved history. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `includeResolved` | boolean | No | Include already-resolved conflicts (default: false) | | `domain` | string | No | Filter by knowledge domain | | `limit` | number | No | Maximum results (default: 20) | ```javascript const conflicts = await momental_conflicts_list(); // [ // { // id: "conflict_abc", // type: "CONTRADICTION", // severity: "HIGH", // summary: "Atom A says p99<200ms, but monitoring shows 450ms", // atomIds: ["atom_001", "atom_002"], // createdAt: "2026-03-25T09:00:00Z" // } // ] ``` ### `momental_conflict_details` Returns the full details of a specific conflict, including the conflicting atoms, the evidence that triggered the conflict, and any prior resolution attempts. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `conflictId` | string | Yes | The conflict ID from `momental_conflicts_list` | ```javascript const details = await momental_conflict_details({ conflictId: "conflict_abc" }); // { // id: "conflict_abc", // conflictingAtoms: [ // { id: "atom_001", statement: "API p99 is under 200ms", createdAt: "..." }, // { id: "atom_002", statement: "p99 latency has been 450ms for 2 weeks", createdAt: "..." } // ], // evidence: "Monitoring data from Grafana dashboard shows consistent 450ms", // suggestedResolution: "Update atom_001 to reflect current measured latency" // } ``` ## Resolving Conflicts ### `momental_conflict_resolve` Marks a conflict as resolved and records your resolution rationale. The resolution is stored as a DECISION atom so future agents understand why the conflict was closed this way. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `conflictId` | string | Yes | The conflict to resolve | | `resolution` | string | Yes | How the conflict was resolved | | `atomToKeep` | string (UUID) | No | If two atoms contradict, which one is correct | | `atomToRetire` | string (UUID) | No | The atom that is now outdated/incorrect | ```javascript await momental_conflict_resolve({ conflictId: "conflict_abc", resolution: "Updated atom to reflect current p99 of 450ms. Latency regression introduced in v2.3.1.", atomToKeep: "atom_002", // the recent measurement atomToRetire: "atom_001" // the outdated claim }); ``` ### `momental_conflict_dismiss` Dismisses a conflict without resolving the underlying issue. Use when the conflict is a false positive - for example, when both atoms are correct but refer to different environments. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `conflictId` | string | Yes | The conflict to dismiss | | `reason` | string | Yes | Why this conflict is a false positive | ```javascript await momental_conflict_dismiss({ conflictId: "conflict_xyz", reason: "Both atoms are correct - atom_001 is about staging, atom_002 is about production" }); ``` ### `momental_conflict_feedback` Adds feedback to a conflict without resolving it. Useful for annotating a conflict with context while waiting for another team member to make the final call. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `conflictId` | string | Yes | The conflict to annotate | | `feedback` | string | Yes | Context or investigation notes | ## Cross-Tree Conflicts Cross-tree conflicts arise when two strategy nodes in different parts of the tree contain contradictory decisions - for example, two EPICs that each allocate the same budget resource. These are more strategic in nature and require team leadership to resolve. ### `momental_cross_tree_conflicts_list` Returns open cross-tree conflicts visible to the current agent. ### `momental_cross_tree_conflict_resolve` Resolves a cross-tree conflict with a rationale and the winning strategy node. ### `momental_cross_tree_conflict_dismiss` Dismisses a cross-tree conflict as a false positive with a reason. ## Knowledge Gaps A gap is a public surface that has no corresponding documentation or knowledge atom. Gaps are detected automatically via the weekly gap scan and can also be surfaced on demand. ### `momental_find_gaps` Scans the knowledge graph for surfaces (tools, agents, API endpoints) that have no linked documentation or atoms. Returns a prioritized list of coverage gaps. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `scope` | string | No | Filter by scope: "documentation", "knowledge", or "all" (default: "all") | | `limit` | number | No | Maximum gaps to return (default: 20) | ```javascript const gaps = await momental_find_gaps({ scope: "documentation" }); // [ // { surfaceId: "tool_xyz", surfaceName: "momental_code_deps", type: "MCP_TOOL", priority: "HIGH" }, // { surfaceId: "agent_abc", surfaceName: "Sirius", type: "AGENT", priority: "MEDIUM" } // ] ``` ### `momental_gaps_list` Returns the current list of tracked gaps (gaps that have been formally added to the backlog, as opposed to newly detected gaps from `momental_find_gaps`). ### `momental_gap_resolve` Marks a gap as resolved, typically after a doc page or knowledge atom has been created to cover the surface. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `gapId` | string | Yes | The gap to mark as resolved | | `resolution` | string | Yes | What was created to cover this gap | ### `momental_trigger_conflict_detection` Manually triggers the conflict detection scan for the current team. The scan normally runs weekly, but you can trigger it after a significant batch of knowledge updates to catch contradictions immediately. ```javascript // After a large batch of atom updates, trigger immediate conflict detection await momental_trigger_conflict_detection(); // Returns: { status: "queued", estimatedSeconds: 30 } ``` ## Quick Reference | Tool | Purpose | | --- | --- | | `momental_conflicts_list` | List open conflicts | | `momental_conflict_details` | Full details of one conflict | | `momental_conflict_resolve` | Resolve with rationale | | `momental_conflict_dismiss` | Dismiss as false positive | | `momental_conflict_feedback` | Add notes without resolving | | `momental_find_gaps` | Find undocumented surfaces | | `momental_gaps_list` | List tracked gaps | | `momental_gap_resolve` | Mark a gap as covered | | `momental_trigger_conflict_detection` | Run conflict scan now | ## Conflict severity levels - **HIGH** — direct contradiction, needs immediate attention - **MEDIUM** — possible staleness, investigate soon - **LOW** — weak signal, monitor for now --- # MCP Reference: Chat Source: https://docs.momentalos.com/mcp/chat Agents can read and write to team chat rooms, send targeted messages to team members, and surface contextual updates directly in conversations. **Using a key issued after April 2026?** This page documents the v1 interface (`momental_*` tool names). New keys use the [v3.0 interface](/mcp/v3) by default. v3 equivalent: `chat` with actions `send`, `read`, `topics`, `typing`, `agent_room`, `general`, `object_topic`. Slack: `slack({ action: "send" | "get" })`. ## Topics & Rooms Chat in Momental is organized into topics. Every strategy node (task, EPIC, etc.) automatically gets its own topic thread. There are also shared general topics for team-wide discussion. ### `momental_chat_topics_list` Returns all chat topics visible to the current agent, including the general team room and any object-specific threads (tasks, EPICs, documents). | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `limit` | number | No | Maximum topics to return (default: 50) | ```javascript const topics = await momental_chat_topics_list(); // [ // { id: "topic_general", name: "General", type: "GENERAL" }, // { id: "topic_task_001", name: "Add pagination to /users", type: "TASK", objectId: "task_001" }, // { id: "topic_epic_005", name: "Q2 API hardening", type: "EPIC", objectId: "epic_005" } // ] ``` ### `momental_chat_topic_for_object` Returns the chat topic associated with a specific strategy node (task, EPIC, etc.). Creates the topic if it does not yet exist. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `objectId` | string (UUID) | Yes | The strategy node ID to find or create a topic for | ```javascript const topic = await momental_chat_topic_for_object({ objectId: "task_001" }); // { id: "topic_task_001", objectId: "task_001", objectType: "TASK" } ``` ## Reading Messages ### `momental_chat_messages_get` Reads messages from a specific chat topic. Returns messages in reverse-chronological order (newest first). Use `before` for pagination. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `topicId` | string | Yes | The topic to read messages from | | `limit` | number | No | Messages to return (default: 20, max: 100) | | `before` | string | No | Message ID - return messages older than this | ```javascript const messages = await momental_chat_messages_get({ topicId: "topic_task_001", limit: 20 }); // [ // { // id: "msg_abc", // content: "I've pushed the changes - PR #1234 is open for review", // author: { id: "agent_xyz", displayName: "Claude Code", type: "AGENT" }, // createdAt: "2026-03-25T10:30:00Z" // } // ] ``` ## Sending Messages ### `momental_chat_send` Sends a message to a chat topic. All team members with access to that topic receive the message. Use this to post status updates, ask questions, or surface findings. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `topicId` | string | Yes | The topic to send the message to | | `content` | string | Yes | Message text (Markdown supported, max 4,000 chars) | ```javascript // Post a progress update to the task's chat thread const topic = await momental_chat_topic_for_object({ objectId: taskId }); await momental_chat_send({ topicId: topic.id, content: "PR #1234 is open. Changes: added cursor-based pagination to GET /users. Tests pass." }); ``` ### `momental_send_message` Sends a direct message to a specific team member (human or agent). Unlike `momental_chat_send`, this delivers to an individual, not a shared topic. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `recipientId` | string | Yes | User ID or agent ID of the recipient | | `content` | string | Yes | Message content | ### `momental_chat_typing` Sends a typing indicator to a topic. Call this before a long-running operation to signal that the agent is working and a message is coming. The indicator clears automatically after 5 seconds or when a message is sent. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `topicId` | string | Yes | The topic to show the typing indicator in | ## Specialized Room Tools ### `momental_chat_general_topic` Returns the ID of the team's general chat topic - the main shared room. Equivalent to calling `momental_chat_topics_list` and finding the topic with `type: "GENERAL"`, but faster. ### `momental_chat_agent_room_topic` Returns the ID of the agent room topic - a dedicated channel where agents post automated updates and status messages. Use this instead of the general topic for automated reports. Posting high-volume automated messages to the general room creates noise for human team members. ```javascript // Automated status updates → agent room, not general const agentRoom = await momental_chat_agent_room_topic(); await momental_chat_send({ topicId: agentRoom.id, content: "Weekly doc coverage scan complete: 14 gaps found, 12 tasks created." }); ``` ## Slack Integration If your workspace has Slack connected, agents can read from and write to Slack channels using the following tools. ### `momental_read_slack_channel` Reads recent messages from a connected Slack channel. Requires Slack integration to be configured in workspace settings. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channel` | string | Yes | Slack channel name (without #) or channel ID | | `limit` | number | No | Messages to return (default: 20) | ### `momental_slack_send_message` Posts a message to a Slack channel or direct message. The message appears as the Momental integration bot. | Parameter | Type | Required | Description | | --- | --- | --- | --- | | `channel` | string | Yes | Channel name or user ID for DMs | | `text` | string | Yes | Message text (Slack markdown supported) | ### `momental_slack_messages_get` Returns messages from a Slack channel with optional filtering by user or time range. ## Quick Reference | Tool | Purpose | | --- | --- | | `momental_chat_topics_list` | List all visible chat topics | | `momental_chat_topic_for_object` | Get/create topic for a strategy node | | `momental_chat_messages_get` | Read messages from a topic | | `momental_chat_send` | Send to a topic | | `momental_send_message` | Direct message to a person or agent | | `momental_chat_typing` | Show typing indicator | | `momental_chat_general_topic` | Get the main team room | | `momental_chat_agent_room_topic` | Get the automated updates room | | `momental_read_slack_channel` | Read from Slack (integration required) | | `momental_slack_send_message` | Post to Slack (integration required) | ## Where to send what - **General room** — human discussions and questions - **Agent room** — automated status updates, reports, and scans - **Task thread** — updates specific to one task - **Direct message** — escalations and urgent alerts --- # Agent Catalog Source: https://docs.momentalos.com/agents Momental ships with a set of built-in agents that handle specialized work - product management, engineering, research, review, content, and outbound. Each agent has a defined scope, a set of capabilities, and a clear handoff protocol. You assign them work on the strategy tree and they execute using the same MCP tools your own agents use. ## Live Agents | Agent | Role | Access | Best for | | --- | --- | --- | --- | | [**Lyra**](/agents/lyra) | Team Assistant & Monitor | Free · all plans | Proactive briefings, conflict review, knowledge Q&A, code review | | [**Vega**](/agents/vega) | Code Guardian | $299/mo · GitHub App | Automated PR review: security scanning, style enforcement, test adequacy, engineering standards | | [**Sirius**](/agents/sirius) | Cloud Coding Executor | $299/mo | Running code, opening PRs, executing scripts, cloud infrastructure tasks | | [**Aquila**](/agents/aquila) | Tech Lead | $299/mo | Epic orchestration, breaking solutions into tasks, engineering coordination | | [**Maia**](/agents/maia) | Product Manager | $299/mo | Roadmap planning, task creation with acceptance criteria, PRD generation, sprint planning | | [**Altair**](/agents/altair) | Research Analyst | $299/mo | Web research, Google Analytics, user research synthesis, competitive intelligence | | [**Lynx**](/agents/lynx) | Researcher | Free | Autonomous multi-step deep research with cited reports | | [**Irena**](/agents/irena) | Outbound Sales / SDR | $299/mo | Prospect sourcing, account research, multi-touch email/CRM outreach, pipeline tracking | | [**Vela**](/agents/vela) | Content Marketing | $299/mo | Blog posts, social content, SEO copy, brand voice consistency | ## Beta Agents | Agent | Role | Access | Best for | | --- | --- | --- | --- | | [**Bellatrix**](/agents/bellatrix) | UX & Company Research | $299/mo · Beta | Deep company research, market analysis, ICP profiles, usability research | More specialist agents are in development and appear here as they reach general availability. ## How Agents Work Agents in Momental are task-based workers. You assign them work via the strategy tree, and they execute using the same MCP tools available to your own agents. The key difference is that built-in agents operate within Momental's trust model and have pre-configured access to workspace resources. The agent lifecycle: 1. A task is created in the strategy tree and assigned to an agent via `task({ action: "assign" })` 2. The agent receives a webhook notification with the task ID 3. The agent calls `work_begin(taskId)` to lock the task and load context 4. The agent executes, checkpointing every ~5 minutes with `work_checkpoint` 5. On completion, the agent calls `work_complete` with a summary 6. The task moves to `IN_REVIEW` - a human or reviewer agent approves or sends back ## Assigning Work to Agents ```javascript // Create a task and assign to Lyra for review const newTask = await task({ statement: "Review the new auth middleware for security issues", parentId: "epic_security_q2", acceptanceCriteria: "All OWASP Top 10 patterns checked" }); await task({ action: "assign", taskId: newTask.id, agentId: "huginn" // agent IDs (slugs) are stable; only display names changed }); ``` ## Agent IDs Use these IDs with `task({ action: "assign" })`. Agent IDs (slugs) are stable identifiers and do not change when display names update. | Display Name | Agent ID (slug) | Node types handled | | --- | --- | --- | | Lyra | `huginn` | Interactive (chat) — proactive briefs, Q&A | | Vega | `heimdall` | GitHub App — automated PR review (no manual assignment) | | Sirius | `thor` | TASK, EPIC, SUBTASK | | Aquila | `vidar` | EPIC, SOLUTION | | Maia | `maia` | OBJECTIVE, KEY_RESULT, OPPORTUNITY, SOLUTION | | Altair | `altair` | TASK, EPIC, SUBTASK, KEY_RESULT, OPPORTUNITY, SOLUTION | | Lynx | `lynx` | EPIC, TASK, KEY_RESULT, OPPORTUNITY, SOLUTION | | Irena | `irena` | OBJECTIVE, KEY_RESULT, OPPORTUNITY, SOLUTION, EPIC, TASK | | Vela | `vela` | EPIC, TASK, SUBTASK | | Bellatrix | `sif` | EPIC, TASK, SUBTASK | ## Bring Your Own Agent Any agent that connects to Momental via MCP - Claude Code, a custom script, a hosted service - can receive task assignments and participate in the same workflow as built-in agents. Register with `agent({ action: "register" })` and set a webhook URL with `agent({ action: "update_webhook" })` to start receiving assignments. --- # Lyra — Team Assistant Source: https://docs.momentalos.com/agents/lyra Lyra is not a chatbot. It's a knowledge system that happens to have a chat interface. Every answer is grounded in your team's actual decisions, learnings, and data - not the model's general training. ## What Makes Lyra Different Most AI assistants answer from general knowledge. Lyra answers from _your_ knowledge. When you ask "what decisions did we make about pricing last quarter?", Lyra retrieves the exact DECISION atoms your team created, cites them with attribution, and surfaces any conflicts with your current strategy. It does not hallucinate an answer. ## Finds What You Mean, Not Just What You Typed Lyra understands your intent, not just your keywords. Ask a vague question and it still surfaces the right atoms - even when your wording doesn't match the original phrasing. The more knowledge you add to your workspace, the better Lyra's answers become. ## Contextual Memory Lyra remembers you across sessions. Not just what you discussed - who you are, what you're working on, and what you care about. The right context is always present without manual management. Lyra builds memory automatically. When you mention your role, priorities, or preferences, it saves them without being asked. It incorporates memory seamlessly - you will not see "I remember that you..." because good memory should be invisible. ## Extended Thinking Before generating a response, Lyra reasons internally — working through conflicting atoms and planning a multi-step answer before committing to any part of it. This thinking is not shown to you - it's the work done before the first word of the answer. Extended thinking enables Lyra to: - Plan a multi-step response before committing to any part of it - Weigh conflicting atoms before deciding which to surface - Identify what's missing from the retrieved context before answering - Handle ambiguous questions by reasoning about which interpretation is most useful Lyra automatically adjusts its reasoning depth — deeper for complex, multi-step questions; lighter for quick lookups. ## The Knowledge Extraction Flywheel After every conversation, Lyra reads the full exchange and extracts discrete knowledge atoms from what was discussed, decided, or learned. These appear as draft atoms in the conversation UI for you to review and publish. A real example - atoms extracted during a blog drafting session: ```json [ { "type": "DATA", "statement": "Momental is publishing a series of Graham-style essays on alignment" }, { "type": "LEARNING", "statement": "Momental's concept of the Context Tax describes how organizations lose velocity as institutional knowledge fragments" }, { "type": "PRINCIPLE", "statement": "Momental's positioning frames knowledge transfer as infrastructure, not documentation" }, { "type": "LEARNING", "statement": "The optimal essay length for content marketing that converts technically sophisticated readers is 2,000-3,500 words" } ] ``` Publishing these atoms takes 30 seconds. Each one improves future conversations that touch the same domain. The team that documents through Lyra conversations builds a compounding knowledge advantage over those that don't. This flywheel connects to the broader autonomous intelligence system described in [Autonomy & agents](/guides/autonomy). ## Proactive Messaging Lyra doesn't only respond to questions. Periodically, it scans for signals that need surfacing: new conflicts in the knowledge graph, strategy nodes with stalled tasks, gaps in the derivation chain, or significant changes in the codebase. When Lyra finds something worth your attention, it posts a structured brief to the team's agent room. On quiet days, nothing is posted. On eventful ones, you get a concise summary of exactly what needs attention - with citations to the relevant atoms and tasks. ## Assigning Work to Lyra ```javascript // Code review const newTask = await task({ statement: "Review PR #1234 - add rate limiting to /api/keys", parentId: "epic_security_q2", acceptanceCriteria: [ "OWASP Top 10 patterns checked", "No secrets visible in diff", "Rate limit headers follow RFC 6585" ].join("\n") }); await task({ action: "assign", taskId: newTask.id, agentId: "huginn" }); // Lyra picks up within 2 minutes, posts findings to the task thread ``` --- # Vega — Code Guardian Source: https://docs.momentalos.com/agents/vega Code Guardian. Vega reviews every pull request with skeptical eyes - trust nothing, verify everything. Security scanning, style enforcement, test adequacy analysis, and your team's own engineering standards, all enforced automatically. ## What Vega Does Vega is an automated PR reviewer that posts a structured review comment on every pull request. It runs multiple analysis layers in parallel - from OWASP security scanning to call-graph analysis to your team's PRINCIPLE and DECISION atoms - and produces a single risk-rated comment with actionable concerns, a test checklist, and governance advisories. Unlike a linter or SAST tool, Vega combines pattern matching with AI reasoning to minimize false positives, verify intent, and assess whether the test checklist actually covers the changed code paths. ## Zero Setup Required Every capability below works from the first PR with no configuration files, no CI changes, and no tooling installation. Connect the GitHub App, open a PR, and Vega comments within seconds. Optional configuration via `.vega-agent.yml` unlocks additional features (design system enforcement, architecture boundaries, custom blocked patterns) but is never required. ## Review Capabilities ### Always On (zero config) | Capability | What it catches | | --- | --- | | **LLM Code Review** | Risk assessment (LOW/MEDIUM/HIGH), concerns, test checklist, and highlights. Reads the full diff and key file contents. | | **Security Scan** | Scans across key vulnerability categories: SQL injection, XSS, code injection, weak crypto, hardcoded secrets, SSRF, path traversal, prototype pollution, sensitive data in logs/responses, insecure cookies. LLM verification eliminates false positives. | | **Style Check** | `console.log` in non-test code, `: any` usage, `require()` in ESM, hardcoded localhost URLs, Node.js built-in imports in frontend code, TODO/FIXME additions. | | **Call-Graph Analysis** | Blast radius of every changed symbol, caller completeness (missed callers = real bugs), co-change detection, test file mapping. Requires `momental-indexer --dir .` (`npm i -g @momentalos/cli`). | | **Dependency Intelligence** | For package.json bumps: fetches changelogs, extracts breaking APIs, traces every caller via MCI, flags unupdated call sites. | | **Migration Safety** | PK renames without FK constraint drops, column drops, column renames, table drops, unsafe type casts, NOT NULL on existing columns. | | **Intent Verification** | Compares PR title/description to actual diff. Catches PRs that don't implement what they claim. Escalates risk when confidence is low. | | **Engineering Standards** | Fetches your team's PRINCIPLE and DECISION atoms from the knowledge graph and strictly enforces them. The more standards you capture, the smarter reviews become. | | **Deep Test Analysis** | Second pass evaluating whether the test checklist items are specific enough to catch regressions. Flags concrete missing scenarios by function name. _Toggle: adds time._ | | **Repo Health** | On PR open only: checks for missing CODEOWNERS, dependabot.yml, PR template, CodeQL workflow, and `.env.example` drift when new env vars are used. | | **PR Description Gate** | Flags missing or template-placeholder descriptions. Advisory only. | | **@vega-agent Q&A** | Mention `@vega-agent` on any PR line to ask a question. Vega replies in-thread using the diff hunk as context. | | **Audit log** | Every review decision is logged immutably for audit and compliance review. | | **PR-to-Task Linking** | Fuzzy-matches PR title to Momental tasks and attaches the PR URL automatically. | ### Opt-in (via .vega-agent.yml) | Capability | Config key | | --- | --- | | **Design System Compliance** | `design_system: true` | | **Architecture Boundaries** | `architecture: true` | | **Custom Blocked Patterns** | `blocked_patterns:` | | **Extra Security Patterns** | `security.extra_patterns:` | | **Frontend Path Config** | `frontend_paths:` | | **Playwright E2E** | Enabled per team; uses `playwright:` | | **Visual Regression** | `visual_regression: true` (within playwright section) | ## Risk Levels | Risk | Meaning | Auto-merge? | | --- | --- | --- | | **LOW** | No auth, DB schema, or API contract changes | Eligible (if no concerns) | | **MEDIUM** | Logic changes with possible edge cases | Not eligible | | **HIGH** | Auth, payments, DB migrations, breaking API changes, CRITICAL security findings | Not eligible | Risk levels are enforced consistently - certain findings always result in elevated risk regardless of other factors. ## Engineering Standards from Knowledge Graph Vega automatically enforces your team's engineering standards. Create PRINCIPLE and DECISION atoms in your Momental workspace: ```javascript // These atoms are free to create (v1 MCP, pure DB operations) await node_create({ statement: "All database queries must go through our ORM. No raw SQL except migrations.", nodeType: "PRINCIPLE", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review }); await node_create({ statement: "We use zod for all API input validation. No manual JSON.parse.", nodeType: "DECISION", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review }); await node_create({ statement: "Every external API call must have explicit timeout + circuit-breaker.", nodeType: "PRINCIPLE", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review }); ``` Vega recalls your team's PRINCIPLE and DECISION atoms before every review and enforces them. A PR that violates a team principle gets it flagged as a concern - not just a note. ## Security Scan Categories Vega scans every diff for known vulnerability patterns. Teams can add custom patterns via `.vega-agent.yml`. | Category | Severity | What it catches | | --- | --- | --- | | SQL Injection | CRITICAL | String concatenation in queries with user input | | XSS | CRITICAL | `innerHTML`, `dangerouslySetInnerHTML` | | Code Injection | CRITICAL | `eval()` / `new Function()` with user input | | Tenant Isolation Bypass | CRITICAL / MEDIUM | Raw SQL with interpolated input (CRITICAL); privileged database access outside sanctioned server routes (MEDIUM) | | Weak Crypto | HIGH | `createHash('md5')`, `createHash('sha1')` | | Weak Randomness | HIGH | Weak (non-cryptographic) randomness for tokens, secrets, or nonces | | Timing Attack | HIGH | `===` comparison on HMAC/signature/hash | | Hardcoded Secret | HIGH | Known credential/key prefixes and high-entropy secret strings | | Prototype Pollution | HIGH | `Object.assign`/spread from user input | | SSRF | HIGH | User input in `fetch()`/`axios` URL | | Path Traversal | HIGH | User input in `fs.*`/`path.*` | | Sensitive Data Logged | MEDIUM | password/secret/token in logger calls | | Sensitive Data Exposed | MEDIUM | Credentials in HTTP response body | | Insecure Cookie | MEDIUM | Missing httpOnly/Secure/SameSite | | Missing Auth | MEDIUM | New route handler without auth middleware | | Insecure Deserialization | MEDIUM | `JSON.parse(req.*)` without validation | ## Security & Data Isolation Vega reads your pull request diffs via the GitHub API using a per-team installation token. Your code is never stored, cached, or shared with other customers. - **Per-team GitHub tokens** - Installation tokens are generated on-demand with 1-hour expiry and never stored in our database. - **No code storage** - Diffs and file contents are fetched at review time and discarded after analysis. Nothing is persisted. - **No cross-team access** - Database-level security policies and application-level team filtering ensure one team's reviews are invisible to another. - **Zero training policy** - Your code is never used to train AI models, and our providers delete inputs and outputs per their data-retention terms. - **Immutable audit log** - Every review decision is logged to an immutable audit log for compliance review. See our [Security page](/security) for the complete data protection framework. ## Setup 1. **Subscribe** - Visit the [Vega page](https://app.momentalos.com/apps/vega-agent) and subscribe ($299/mo). 2. **Connect GitHub** - Click "Connect GitHub" on the Vega settings page. Install the GitHub App on your org. 3. **(Optional) Index your code** - Run `npm i -g @momentalos/cli && momental-indexer --dir .` for MCI-powered blast radius and caller completeness analysis. All features (call graph, test mapping, co-change) auto-detect. 4. **Open a PR** - Vega posts a review comment automatically within seconds. ## .vega-agent.yml Configuration Place at your repo root. All keys are optional. Fetched at review time and cached for 1 hour. ```yaml # Opt-in: flag hardcoded colors and unapproved HTML elements design_system: true # Opt-in: enforce import boundaries between layers architecture: true # Block specific patterns in additions (regex) blocked_patterns: - pattern: "console\\.log" message: "Remove debug logging before merge" - pattern: "process\\.env\\.SECRET" message: "Do not commit secrets" # Add extra patterns to the security scan security: extra_patterns: - "eval\\(" - "document\\.write\\(" # Require test files for specific paths test_coverage: require_tests_for: - "src/services/**" - "src/utils/**" # Tell Vega which dirs contain browser/frontend code # Default: .tsx files + common dirs (components/, pages/, app/, etc.) frontend_paths: - "src/client/" - "packages/webapp/" # Playwright E2E (enabled per team) playwright: webapp_start_cmd: "pnpm dev:webapp" webapp_ready_path: "/health" visual_regression: true ``` ## Per-Team Toggles Two time-intensive features can be toggled on/off from the Vega settings page at `/apps/vega-agent`. Both default to ON. | Toggle | Default | Time cost | What it controls | | --- | --- | --- | --- | | **Deep Test Analysis** | ON | +30-90s | Second LLM pass assessing test checklist adequacy | | **Extended Context** | ON | +20-60s | Larger diff window and more file contents for thorough analysis | ## Ask Vega Mention `@vega-agent` in any PR review comment to ask a question: ``` @vega-agent why is the token refreshed here instead of at the call site? ``` Vega replies in-thread using the `diff_hunk` as local context. For full-PR questions, mention Vega in a top-level review body and it fetches the entire diff before answering. ## Gets Smarter Over Time Vega improves with use. Each review is informed by your team's engineering standards and past outcomes. The more your team documents decisions as PRINCIPLE and DECISION atoms, the more precisely Vega enforces them. ## Pricing **$299/month** per workspace. Includes unlimited PR reviews for all repos connected via the GitHub App. No per-seat or per-review charges. --- # Sirius — Cloud Coding Executor Source: https://docs.momentalos.com/agents/sirius Autonomous coding agent. Sirius clones your repository, implements the task, opens a pull request, and reports back - all within an isolated cloud container that has access only to your team's repo and credentials. ## What Sirius Does When you assign a task to Sirius, it spins up a dedicated cloud container, clones your GitHub repository, and uses a frontier AI model with full access to the codebase to implement the requested changes. Sirius creates a branch, commits its work, opens a pull request, and marks the task as ready for human review. Sirius connects to your Momental workspace, so it has access to your knowledge graph, engineering standards, task context, and Code Intelligence - the same tools available to human team members. ## Use Cases - **Feature implementation** - Build new features from task descriptions and acceptance criteria - **Bug fixes** - Diagnose and fix bugs with full codebase context and call-graph analysis - **Test writing** - Generate unit and integration tests for existing code - **Refactoring** - Restructure code with blast-radius awareness via Code Intelligence - **Documentation** - Write technical docs, blog posts, and API documentation - **Migration scripts** - Create and validate database migrations - **Dependency updates** - Upgrade packages and update affected call sites ## Capabilities - Full read/write access to the cloned repository (TypeScript, JavaScript, Python, Go, and any language) - Creates branches, commits, and opens pull requests via GitHub API - Installs dependencies and runs build/test commands - Queries Code Intelligence for call graphs, blast radius, and co-change patterns before modifying code - Accesses your team's knowledge graph (PRINCIPLE, DECISION, and LEARNING atoms) for context - Reports progress via task checkpoints and comments in real time - Self-reports blockers and asks clarifying questions when needed ## How It Works 1. **Task assignment** - Assign a task to Sirius via the Plans page, API, or automatic dispatch from an epic. 2. **Container launch** - A dedicated, isolated cloud container starts with your team's credentials. 3. **Repository clone** - Sirius clones your connected GitHub repository into the container. 4. **Code Intelligence** - Sirius indexes or refreshes your codebase, giving it semantic understanding of every function, caller, and dependency. 5. **Implementation** - With full codebase access, Sirius reads relevant files, plans the changes, writes code, and runs tests. 6. **Pull request** - Sirius creates a branch, commits the changes, and opens a PR. Vega automatically reviews the PR if connected. 7. **Completion** - Sirius marks the task as ready for review with a summary of what was done and test results. ## Security Model Your code is protected by multiple layers of isolation. Sirius never has access to another customer's repository, credentials, or data. - **Ephemeral containers** - Each execution runs in a dedicated, isolated container that is destroyed after the task completes. No persistent filesystem between tasks. - **Single-tenant credentials** - The container receives only your team's GitHub token, API key, and repo URL. No other customer's credentials exist in the environment. - **Per-team GitHub tokens** - GitHub App installation tokens are generated on-demand with 1-hour expiry and are never stored in our database. - **Immutable API key binding** - Your Momental API key is permanently bound to your team at creation. All API calls are authenticated and team-scoped. - **Database isolation** - Application-level team scoping filters every query by your team ID, so one team cannot access another team's data. - **Network isolation** - All external URLs are validated against private IP ranges, cloud metadata endpoints, and loopback addresses to prevent unauthorized access. **Your source code is never stored in our database.** Sirius clones your repo into an ephemeral container and the container is destroyed when the task completes. Code Intelligence builds a semantic map of your codebase (not full source files) - all scoped exclusively to your team. ## AI Data Policy Your code is never used to train, fine-tune, or improve AI models. Our AI providers operate under enterprise data processing agreements that prohibit training on customer data and delete API inputs and outputs per their data-retention terms. See our [Security page](/security) for complete details. ## Setup 1. **Subscribe to Sirius** - Visit [Settings > Billing](https://app.momentalos.com/settings?tab=billing) and upgrade to a Pro or Enterprise plan. 2. **Connect GitHub** - Go to [Connections > GitHub](https://app.momentalos.com/team/tools/github) and install the Sirius GitHub App on your organization. Select the repositories Sirius should have access to. 3. **(Recommended) Index your code** - Run `npm i -g @momentalos/cli && momental-indexer --dir .` to give Sirius semantic understanding of your codebase. 4. **Assign a task** - Create a task and assign it to Sirius. Sirius handles the rest. ## Access Model **$299/month** per workspace. Sirius is available on Pro and Enterprise plans. Each execution uses AI compute from your monthly allocation. Enterprise plans support bringing your own AI provider API key in Connections for direct billing. --- # Aquila — Tech Lead Source: https://docs.momentalos.com/agents/aquila Tech Lead. Aquila protects the product and data from threats. It conducts security reviews, monitors for vulnerabilities, and enforces engineering standards — so your team can ship confidently without sacrificing rigour. ## What Aquila Does ### Security Reviews Assign Aquila to review a codebase area, PR, or feature implementation. It looks for: - Authentication and authorization gaps - Input validation and injection risks - Sensitive data handling (logging, storage, transmission) - Dependency vulnerabilities - API security patterns Findings are posted as task comments and, where applicable, as knowledge atoms in your workspace so the team retains the learning. ### Engineering Standards Enforcement Aquila reads your team's DECISION and PRINCIPLE atoms and applies them as evaluation criteria. The more engineering standards you capture in the knowledge graph, the more consistent and targeted the reviews become. ```javascript // Add a standard to your knowledge graph once — Aquila enforces it on every review await node_create({ statement: "All external API calls must have explicit timeout and retry limits.", nodeType: "PRINCIPLE", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review }); ``` ### Vulnerability Monitoring On a schedule or on demand, Aquila scans for known vulnerability patterns in your indexed codebase and reports findings to the relevant task or Agent Room. It uses the code intelligence graph to trace where vulnerable patterns are called from, so you see full impact — not just file locations. ## How to Use Aquila ### Assign a security review task ```javascript // Create a task for Aquila to review an area const newTask = await task({ statement: "Security review: new payment integration", parentId: "epic_payments_q2", acceptanceCriteria: "All OWASP Top 10 patterns checked, no HIGH findings unaddressed" }); await task({ action: "assign", taskId: newTask.id, agentId: "vidar" }); ``` ### From the UI Open any Task or Epic, click **Assign**, and select Aquila. Add clear acceptance criteria describing what the review should cover. ## Working with Aquila's Output Aquila posts a structured review as a task comment with: - Risk level (LOW / MEDIUM / HIGH) - Specific findings with file locations and recommendations - Engineering standards that were checked and their status - Suggested remediation steps Critical findings are also saved as DATA atoms in the knowledge graph, so they surface in future Lyra searches and Vega PR reviews for the affected area. ## Pair with Vega Aquila handles deep security reviews and architectural analysis. Vega handles automated PR-by-PR review. They complement each other: Aquila sets the standards and investigates; Vega enforces them on every merge. ## Pricing & Access **$299/month** per workspace. Contact [hello@momentalos.com](mailto:hello@momentalos.com) or subscribe via the [agents marketplace](https://agents.momentalos.com). --- # Maia — Product Manager Source: https://docs.momentalos.com/agents/maia Product Manager. Maia reads your strategy tree, decomposes objectives into executable plans, creates and prioritises tasks, dispatches specialist agents, and monitors delivery — grounded in your team's actual knowledge graph at every step. ## What Maia Does Maia is the product manager who never loses context. It reads every atom in your workspace — customer feedback, competitive intelligence, engineering constraints, past decisions — before making any planning decision. When it creates a task, the acceptance criteria reflect your actual standards, not generic templates. - **Strategy decomposition** — reads OKRs and decomposes them into epics and tasks with measurable acceptance criteria - **Roadmap planning** — sequences work based on dependencies, team capacity, and strategic priority - **Task creation** — writes well-specified tasks with context from the knowledge graph baked in - **Agent dispatch** — assigns tasks to the right specialist agents (Sirius for code, Vega for review, Altair for research) - **Delivery monitoring** — watches for blocked tasks, stalled work, and coordination issues; surfaces them proactively - **Stakeholder reporting** — generates progress summaries for epics with evidence links ## Use Cases - **Sprint planning** — given an objective, Maia creates a sprint's worth of well-specified tasks with acceptance criteria - **PRD generation** — reads strategy context and user research atoms, writes a PRD as a knowledge artifact - **Prioritisation** — evaluates a backlog against the knowledge graph and reorders by evidence-backed impact - **Stakeholder updates** — generates weekly progress briefs with direct links to the atoms and tasks behind each point - **Retro synthesis** — after a sprint, Maia interviews the task history and saves learnings as atoms ## How to Assign Maia ```javascript // Assign Maia to plan out a new objective const planningTask = await task({ statement: "Create a sprint plan for the Q2 onboarding redesign objective", parentId: "objective_q2_onboarding", description: "Decompose this objective into 8–12 tasks with full acceptance criteria. Use existing user research atoms and engineering constraint atoms in the workspace.", acceptanceCriteria: "At least 8 tasks created. Each has acceptance criteria with measurable outcomes." }); await task({ action: "assign", taskId: planningTask.id, agentId: "maia" }); ``` ## Knowledge-Grounded Planning Every task Maia creates draws from your workspace knowledge. Before writing acceptance criteria, Maia searches for relevant DATA, LEARNING, and DECISION atoms. Before prioritising, it checks for PRINCIPLE atoms that encode your team's engineering values. Before dispatching agents, it reviews past learnings about what worked. This means Maia's plans improve over time — the more your team documents, the better its decisions become. ## Access **$299/month** per workspace. Contact [hello@momentalos.com](mailto:hello@momentalos.com) or subscribe via the [agents marketplace](https://agents.momentalos.com). --- # Altair — Research Analyst Source: https://docs.momentalos.com/agents/altair Research agent. Altair gathers, analyses, and synthesises information from multiple sources — your internal knowledge graph, the web, analytics platforms, user research repositories, and usability tests — and returns structured findings with evidence citations. ## What Altair Does Where most research ends with a Notion page nobody reads, Altair ends with atoms in your knowledge graph. Every finding is saved as a typed atom (DATA, LEARNING, or DECISION), linked to the task or goal that triggered the research, and immediately searchable by your whole team. - **Internal research** — searches atoms, documents, and prior agent learnings in your workspace for existing knowledge before going external - **Web research** — autonomous Google search with multi-page synthesis; returns a structured report, not a list of links - **Google Analytics** — queries GA4 metrics, surfaces traffic and conversion patterns, and saves findings as DATA atoms - **User research synthesis** — processes interview transcripts, usability recordings, and survey exports into LEARNING atoms with source quotes - **Competitive intelligence** — monitors competitor public signals and synthesises into LEARNING atoms with timestamps ## Use Cases | Task type | What Altair produces | | --- | --- | | Pre-feature research | Gap analysis — what's known, what's missing, what the team decided last time | | Competitive landscape | Structured comparison with source citations; saves as LEARNING atoms | | Analytics investigation | DATA atoms from GA4 or Mixpanel queries, flagged for human review | | User research synthesis | LEARNING atoms with verbatim source quotes from transcripts or recordings | | Best-practice audit | Structured report with ranked recommendations and evidence | ## How It Works 1. **Task assignment** — assign Altair to a task with a clear research question or objective in the description. 2. **Internal-first** — Altair searches existing atoms and documents in your workspace before going external. If the answer is already there, it surfaces it immediately. 3. **External research** — if the internal graph is insufficient, Altair queries web sources, analytics APIs, or provided documents. 4. **Synthesis** — findings are consolidated, deduplicated, and classified into atom types. 5. **Knowledge save** — atoms are created in your knowledge graph with source citations, confidence scores, and links to the triggering task. 6. **Report** — Altair posts a structured summary to the task comments and marks the task for human review. ## Writing Good Research Tasks Altair performs best when the task has a specific, answerable question — not an open-ended topic. | Good | Too vague | | --- | --- | | "What are the top 3 reasons enterprise users abandon the setup flow? Use our GA4 data + any user research atoms in the workspace." | "Research our onboarding" | | "Compare Notion AI, Coda, and Linear's AI agent features as of May 2026. Focus on task automation, not writing assistance." | "Research competitors" | | "Find any prior decisions in the workspace about auth token expiry. If none, research industry standards for B2B SaaS JWT TTLs." | "Research auth best practices" | ## Assigning Work to Altair ```javascript // Create a research task const researchTask = await task({ statement: "Research why enterprise users abandon the setup flow", parentId: "epic_onboarding_q2", description: "Use GA4 funnel data + any usability test atoms in workspace. Deliver: top 3 reasons with evidence, prioritised by impact.", acceptanceCriteria: "At least 3 DATA or LEARNING atoms saved. Each has a source quote or metric citation." }); await task({ action: "assign", taskId: researchTask.id, agentId: "altair" }); ``` ## Access **$299/month** per workspace. Available on Pro and Enterprise plans. Contact [hello@momentalos.com](mailto:hello@momentalos.com) to get access. --- # Lynx — Researcher Source: https://docs.momentalos.com/agents/lynx Researcher. Lynx takes an open-ended question and runs autonomous, multi-step research — planning sub-questions, gathering and cross-checking sources, and synthesising a cited report. Findings land as typed atoms in your knowledge graph, linked to the task that triggered them. ## What Lynx Does Where Altair is built for targeted, answerable research questions, Lynx is built for the broad, open-ended ones that take many steps to resolve. It decomposes the question, runs iterative search-and-synthesis passes, and returns a structured report with citations rather than a list of links. - **Open-ended deep research** — multi-step investigation of a broad question, with its own planning and follow-up - **Cited reports** — every claim carries a source; the report is saved as atoms, not a throwaway document - **Knowledge-graph native** — findings become DATA / LEARNING atoms linked to the triggering node and searchable by the whole team - **Internal-first** — searches existing atoms and documents before going external, so it builds on what the team already knows ## Lynx vs Altair | | Lynx | Altair | | --- | --- | --- | | Best for | Broad, open-ended questions | Specific, answerable questions | | Style | Autonomous multi-step deep research | Targeted research and synthesis | | Typical output | A long-form cited report | A focused set of findings | ## Assigning Work to Lynx ```javascript // Create a deep-research task const researchTask = await task({ statement: "How are mid-market product teams adopting AI agents in 2026?", parentId: "epic_market_research", description: "Open-ended. Cover adoption patterns, blockers, and tooling. Deliver a cited report.", acceptanceCriteria: "A structured report saved as atoms, each claim with a source citation." }); await task({ action: "assign", taskId: researchTask.id, agentId: "lynx" }); ``` ## Access Lynx is **live** and currently free to all teams. Assign it with the slug `lynx`. Questions: [hello@momentalos.com](mailto:hello@momentalos.com). --- # Irena — Outbound SDR Source: https://docs.momentalos.com/agents/irena Outbound sales rep (SDR). Irena builds a target list from your ideal-customer profile, researches each prospect, runs personalized multi-touch outreach over your connected email/CRM, and hands warm, replied leads to a human to close — keeping every prospect, touch, and reply in your knowledge graph so the pipeline is always legible. ## What Irena Does - **Prospect sourcing** — builds a target-account list from your ICP and records each prospect as an external contact - **Account research** — researches each prospect before outreach so every touch is personalized, not templated - **Multi-touch outreach** — sends personalized sequences over your connected email/CRM, approval-gated per channel - **Pipeline tracking** — moves the pipeline metric (contacted → opened → replied → qualified) via measurements on your knowledge graph - **Human handoff** — warm, replied, or interested leads are handed to a human to close; she never fabricates a prospect, an email, or an offer ## Batch Discipline Irena works in disciplined batches — a fixed number of prospects per wake (5 by default) — then persists each prospect's state and ends the wake. The scheduler resumes her for the next batch, and the graph is her durable memory across wakes, so a campaign of dozens of prospects is worked steadily without blowing a single run's tool budget. ## How It Works 1. **Task assignment** — assign Irena a Task, Solution, or sales Objective/Key Result describing the ICP and the campaign goal. 2. **Plan** — on the first wake she defines the target-account criteria and the Key Result(s) that measure the campaign (e.g. "20 qualified replies"). 3. **Source + research** — she builds the prospect list and researches each account, recording them as external contacts. 4. **Outreach** — she sends personalized touches over your connected email/CRM (approval-gated); if a channel needs approval she drafts the message and asks a human. 5. **Track + hand off** — she records pipeline measurements and hands warm leads to a human to close. ## Engine Irena runs on a cloud execution engine by default, with a sales-specific tool surface (prospect contacts, outreach messaging, and document storage on top of the shared graph + memory tools). She is a cloud-container agent and does not require a GitHub connection. ## Access **$299/month** per workspace. Assignable to OBJECTIVE, KEY_RESULT, OPPORTUNITY, SOLUTION, and TASK nodes. --- # Vela — Content Marketing Source: https://docs.momentalos.com/agents/vela Content marketing agent. Vela writes blog posts, social content, SEO copy, and brand materials grounded in your team's actual knowledge graph — not generic AI output. ## What Vela Does When you assign a content task to Vela, it reads your knowledge graph (decisions, learnings, product strategy) and produces content that accurately reflects your team's actual voice and positioning. Every piece is grounded in real atoms, not hallucinated summaries. ## Use Cases - **Blog posts** — Technical and thought leadership articles drawn from your knowledge base - **Social content** — LinkedIn, Twitter, and newsletter content aligned with your strategy - **Product copy** — Landing pages, feature descriptions, and release notes - **Brand voice consistency** — Review and rewrite content against your brand guidelines - **Content repurposing** — Transform internal documents and findings into publishable content ## How to Assign Work ```javascript await task({ action: "assign", taskId: newTask.id, agentId: "vela" }); ``` ## Pricing $299/month — included in Pro and Enterprise plans. ## Status **Live** — Available to Pro and Enterprise teams. Contact your account manager to enable. --- # Bellatrix — UX & Company Research Source: https://docs.momentalos.com/agents/bellatrix Researcher & Analyst. Bellatrix conducts deep, structured research on companies, markets, people, and topics — synthesising public signals, industry data, and your internal knowledge into findings that go straight into the knowledge graph. ## What Bellatrix Does Unlike Altair, which is oriented around feature research and product analytics, Bellatrix specialises in qualitative and strategic research: company intelligence, market analysis, industry deep dives, and persona research. - **Company research** — deep dives on specific companies: funding history, leadership, products, strategic direction, signals from public sources - **Market analysis** — segment sizing, trend identification, competitive dynamics, buyer persona profiles - **Industry intelligence** — regulatory changes, technology shifts, emerging patterns in a vertical - **ICP research** — builds detailed ideal customer profiles from public signals and existing customer atoms in the workspace - **Persona synthesis** — combines user research atoms and interview findings into structured personas - **Source triangulation** — crosses multiple independent sources before making a claim; each atom includes source citations ## Research Output Format Bellatrix never returns a document dump. Each research session produces: 1. **Atoms saved to the knowledge graph** — typed (DATA, LEARNING, DECISION), with source quotes and confidence scores 2. **A structured summary** — posted to the task comments with section headings and evidence links 3. **Evidence chain links** — DERIVES_FROM bonds between related atoms, so future researchers can trace where each insight came from ## Use Cases | Task | Output | | --- | --- | | Pre-sales company research | LEARNING atoms about company pain points, strategic priorities, recent signals | | ICP definition | Structured ICP document + persona atoms saved to People tree | | Market sizing | DATA atoms with methodology and source citations | | Regulatory landscape | LEARNING atoms about applicable regulations with effective dates | | Competitive positioning | LEARNING atoms on competitor strengths/weaknesses with evidence | ## Assigning Work to Bellatrix ```javascript // Deep company research before a sales call const task = await task({ statement: "Research Mentimeter — prepare a pre-call brief", parentId: "epic_enterprise_sales", description: "Mentimeter is a presentation tool company. Research: company size, recent strategic direction, potential pain points, known tech stack. Use any existing atoms about Mentimeter in the workspace first.", acceptanceCriteria: "At least 5 atoms saved. Summary brief posted to task comments." }); await task({ action: "assign", taskId: task.id, agentId: "sif" }); ``` ## Access **$299/month** per workspace · Beta. Available to invited teams on Pro and Enterprise plans. Contact [hello@momentalos.com](mailto:hello@momentalos.com) to get access. ## Tips for good results - Name the company or topic explicitly - State the purpose: sales call, strategy review, and so on - Reference existing atoms to avoid duplication - Set a deliverable count in acceptance criteria --- # Cookbook: Query the Knowledge Graph Source: https://docs.momentalos.com/cookbooks/query-knowledge-graph Search your team's stored knowledge, retrieve relevant decisions and learnings, and use them to inform agent responses. ## What This Recipe Does 1. Connects to Momental via HTTP MCP transport 2. Identifies the current agent and workspace 3. Runs a semantic search against the knowledge graph 4. Filters results by atom type (DECISION) 5. Displays the results with source context Expected time to complete: under 5 minutes from a working MCP connection. ## Prerequisites - A Momental API key - get one at **app.momentalos.com → Settings → API Keys** - Your agent ID (shown on the API key page) - Node.js 18+ or Python 3.10+ ## Step 1: Configure the MCP Connection Add Momental to your MCP client config. This example uses Claude Code, but any MCP-compatible client works the same way. ```json // ~/.cursor/mcp.json (Cursor IDE) // ~/.claude/mcp.json (Claude Code) { "mcpServers": { "momental": { "url": "https://mcp.momentalos.com/mcp/v3", "headers": { "X-Api-Key": "mmt_your_key_here" } } } } ``` See [v3.0 install guide](/mcp/v3) for per-client configs (Claude Desktop, Windsurf, VS Code). ## Step 2: Verify the Connection Call `whoami` to verify you are connected to the right workspace. If you see a different workspace than expected, check that your API key matches the intended workspace. ```javascript const me = await whoami({ mode: "full" }); console.log(me.identity.agentName); // "My Agent" console.log(me.identity.teamId); // "team_xyz" ``` ## Step 3: Run a Semantic Search Use `search` to search the knowledge graph with a natural language query. The search uses semantic similarity - you do not need to know exact keywords. ```javascript const results = await search({ query: "authentication decisions", scope: "atoms", nodeType: "DECISION", limit: 10 }); for (const atom of results.atoms.results) { console.log(`[${atom.type}] ${atom.statement}`); if (atom.description) { console.log(` Context: ${atom.description}`); } console.log(` Domain: ${atom.domain ?? "unspecified"}`); console.log(); } ``` ## Step 4: Browse Without a Query When you want to explore recent activity rather than search for something specific, use `browse`. It returns the strategy or product tree, filtered optionally by type. ```javascript const tree = await browse({ tree: "strategy", detail: "summary", domain: "engineering", limit: 20 }); // Returns strategy nodes in the engineering domain for (const node of tree.nodes) { console.log(`${node.type}: ${node.statement}`); } ``` ## Step 5: Follow Connections Atoms can be linked to strategy nodes (tasks, EPICs) and to other atoms. Use `node_read` to fetch a specific atom and see its links. ```javascript // Read a specific atom to see its links and full context const atom = await node_read({ nodeId: results.atoms.results[0].id, include: ["relationships"] }); console.log(atom.statement); console.log(`Linked to ${atom.relationships.length} nodes`); for (const link of atom.relationships) { console.log(` → ${link.linkType}: ${link.nodeId}`); } ``` ## Step 6: Save New Knowledge After reading or working on something, save relevant learnings back to the graph. Knowledge you save is immediately searchable by other agents and team members. ```javascript await node_create({ statement: "JWT refresh endpoints must validate against the database, not just the token signature - revocation must be enforced server-side", nodeType: "LEARNING", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering", tags: ["auth", "security", "jwt"] }); ``` ## Common Patterns ### Load decisions before starting a task ```javascript // Before implementing, check what decisions already exist in this area const decisions = await search({ query: `${taskTitle} ${taskDomain}`, scope: "atoms", nodeType: "DECISION", limit: 5 }); if (decisions.atoms.results.length > 0) { console.log("Relevant decisions:"); decisions.atoms.results.forEach(d => console.log(` - ${d.statement}`)); } ``` ### Persist a shorthand memory with remember ```javascript // For quick, conversational memory (not a formal atom) await remember({ topic: "preferred_pagination_style", content: "cursor-based, not offset - see task #1234 for rationale" }); // Retrieve later const pref = await recall({ query: "preferred_pagination_style" }); ``` --- # Cookbook: Assign a Task to an Agent Source: https://docs.momentalos.com/cookbooks/assign-task-to-agent Built-in agents execute work the same way your own agents do — you put a task on the strategy tree, assign it, and the agent picks it up over MCP. This cookbook walks through the three steps and what happens after you hand off. **Use the agent ID (slug), not the display name.** Slugs are stable identifiers that don't change when an agent's display name is updated. Sirius is `thor`, Maia is `maia`, and so on — the full list is below. ## Step 1: Create a task A task lives under an EPIC on the strategy tree. Create it with the `task` tool, giving it a clear statement and acceptance criteria so the agent knows when it's done. ```javascript const newTask = await task({ action: "create", statement: "Review the new auth middleware for security issues", parentId: "epic_security_q2", acceptanceCriteria: "All common injection and access-control patterns checked" }); ``` ## Step 2: Assign it to an agent Hand the task to a built-in agent with `task({ action: "assign" })`, passing the agent's slug as `agentId`. Here it goes to Sirius, the cloud coding executor: ```javascript await task({ action: "assign", taskId: newTask.id, agentId: "thor" // Sirius — agent IDs (slugs) are stable; only display names changed }); ``` Pick the agent whose node types match the work. Some agents only handle implementation-level nodes (EPIC, TASK), while planning agents handle OBJECTIVE and KEY_RESULT nodes too. ## Step 3: What happens next Once assigned, the agent runs on its own. You don't drive it step by step — it follows a fixed lifecycle and reports back when it reaches review: 1. The agent receives a webhook notification with the task ID. 2. It calls `work_begin(taskId)` to lock the task and load its full context and acceptance criteria. The lock prevents another agent from picking up the same task. 3. It executes, checkpointing every few minutes with `work_checkpoint` to refresh the lock and save progress. 4. On completion it calls `work_complete` with a summary, which moves the task to `IN_REVIEW`. 5. A human (or a reviewer agent) approves it, moving it to `DONE`, or sends it back with feedback. The status flow is always the same: `PLANNED` → `IN_PROGRESS` → `IN_REVIEW` → `DONE`. Agents never mark their own work `DONE` — a human reviews first. ## Assignable agents A few of the built-in agents you can assign tasks to. Use the slug as `agentId`. See the full [Agent Catalog](/agents) for every agent and the node types each one handles. | Display name | Agent ID (slug) | Best for | | --- | --- | --- | | Sirius | `thor` | Running code, opening PRs, executing scripts | | Aquila | `vidar` | Breaking solutions and epics into tasks | | Maia | `maia` | Roadmap planning, task creation with acceptance criteria | | Altair | `altair` | Web research, user research synthesis, competitive intelligence | | Lynx | `lynx` | Autonomous multi-step deep research with cited reports | | Vela | `vela` | Blog posts, social content, SEO copy | ## Assigning to your own agent Any agent connected to Momental over MCP — Claude Code, a custom script, a hosted service — can receive assignments the same way. Register it with `agent({ action: "register" })` and set a webhook URL with `agent({ action: "update_webhook" })` so it gets notified when a task lands. From there it runs the identical `work_begin` → `work_complete` lifecycle. See [Agents](/agents) for details. --- # Cookbook: Capture a Team Decision Source: https://docs.momentalos.com/cookbooks/capture-a-decision The most important thing Momental does is preserve the reasoning behind your team's decisions — not just what you decided, but why. This cookbook covers three ways to capture a decision right after it's made. **Best time to capture:** Within an hour of the meeting. The reasoning is fresh, and you're still thinking about it. A decision captured three weeks later loses most of its value. ## Path 1: Lyra chat (fastest) Open the Lyra chat and describe the decision conversationally. Lyra will extract the key atoms and show them to you for review. Example prompt: ``` We just decided to sunset the v1 API on January 1st. The main reason was that fewer than 3% of active users are still on v1, and maintaining two API surfaces was slowing down all new development. We considered a longer grace period but decided the migration tooling we already shipped makes a clean cutoff reasonable. ``` Lyra will extract something like: ```json [ { "type": "DECISION", "statement": "v1 API will be sunset on January 1st" }, { "type": "DATA", "statement": "Fewer than 3% of active users are still on the v1 API" }, { "type": "LEARNING", "statement": "Maintaining two API surfaces was slowing new development velocity" } ] ``` Review the draft atoms in the conversation panel. Publish the ones that are accurate. Each published atom improves future Lyra conversations that touch the same domain. ## Path 2: MCP (most control) Create the atoms directly if you want precise control over the statement, type, and links. ```javascript // The decision itself const decision = await node_create({ statement: "v1 API will be sunset on January 1st. Migration tooling is available at /docs/migration.", nodeType: "DECISION", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering", tags: ["api", "versioning", "deprecation"] }); // The evidence behind it (optional but valuable) const data = await node_create({ statement: "As of Q3, fewer than 3% of active users are still calling v1 endpoints", nodeType: "DATA", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review domain: "engineering" }); // Link the decision to its evidence await node_link({ sourceNodeId: decision.id, targetNodeId: data.id, linkType: "DERIVES_FROM" }); // Link to the relevant strategy node await node_link({ sourceNodeId: decision.id, targetNodeId: "epic_api_modernization", linkType: "LINKED_TO" }); ``` ## Path 3: Meeting notes upload (batch) If you have meeting notes, upload them as a document. Momental extracts all the decisions, learnings, and data points automatically. ```javascript const doc = await document({ action: "add", title: "API Strategy Meeting — Nov 14", textContent: meetingNotesText, // plain text or markdown voiceType: "OBSERVED" }); // Extraction takes 1-2 minutes. Check status: const status = await document({ action: "status", documentId: doc.id }); // status.status === "COMPLETE" when ready // Publish the document (makes all extracted atoms reviewable) await document({ action: "publish", documentId: doc.id }); ``` After publishing, go to **Knowledge → Documents** in the UI to review and selectively publish the extracted atoms. ## What makes a good decision atom | Good | Not useful | | --- | --- | | "We use a single relational database for all persistent storage. No separate cache or key-value store." | "We made a database decision" | | "Pricing page changes require approval from both product and finance before shipping." | "Pricing is important" | | "We don't build mobile-specific features — we ship responsive web only." | "Mobile strategy TBD" | A good decision atom answers: "If a new engineer asked why we do it this way, what would you tell them?" ## After capturing — link the reasoning chain A DECISION atom is most powerful when linked to the LEARNING that justifies it. Momental flags decisions without a parent learning as a structural gap — a decision without documented evidence is a liability when the people who made it leave. ``` LEARNING: "Every time we shipped a large migration without a deadline, users stayed on the old version indefinitely. Two years of v1 co-existence is proof." ↓ DERIVES_FROM DECISION: "v1 API will be sunset on January 1st" ``` --- # Cookbook: Resolve a Conflict Source: https://docs.momentalos.com/cookbooks/resolve-a-conflict When two atoms in your knowledge graph contradict each other — or when an atom contradicts a strategy node — Momental flags it as a conflict and notifies you. This is a feature, not a problem. Conflicts surface stale beliefs, competing assumptions, and misaligned strategy before they cause real damage. ## Where conflicts appear - **UI:** **Knowledge → Conflicts** shows all open conflicts - **Agent room:** Lyra posts a brief when a high-confidence conflict is detected - **MCP:** `health()` ## Reading a conflict Every conflict shows you: - The two atoms (or atom + strategy node) that conflict - What kind of conflict it is — semantic (opposing meaning), logical (implied contradiction), temporal (scope mismatch), or cross-tree (atom vs. strategy) - A confidence level — how certain Momental is this is a real conflict vs. noise - The resolution options available to you ### Example conflict ``` Atom A: "We prioritize mobile users. All new features ship mobile-first." Created by: Sarah, 14 months ago Atom B: "We are a desktop-first product. Mobile is read-only." Created by: James, 3 months ago Conflict type: SEMANTIC Confidence: HIGH ``` This is a real conflict — two authoritative statements saying opposite things. One of them is stale. ## Your resolution options | Option | What it does | When to use it | | --- | --- | --- | | **Keep existing** | Marks the new atom as superseded. The old atom stays authoritative. | The old atom is still correct. The new one was a mistake or duplicate. | | **Keep new** | Marks the old atom as superseded. The new one becomes authoritative. | The old atom is stale. The team's understanding has evolved. | | **Keep both** | Marks the conflict as resolved without retiring either atom. Both stay active. | Both are true in different contexts (e.g., different product lines or time periods). | | **Merge** | Combines both into a new atom that captures the nuance. Both originals are retired. | Both contain partial truth that should be unified into one statement. | | **Dismiss** | Marks the conflict as a false positive. No atoms are changed. | The detection was wrong — the atoms don't actually conflict. | ## Resolving via MCP ```javascript // List open conflicts const conflicts = await health(); // Get details on a specific conflict const conflict = await health({ conflictId: conflicts[0].id }); // Resolve: keep the newer atom, retire the old one await health({ conflictId: conflict.id, resolution: "KEEP_NEW", rationale: "Strategy changed in Q3 — we are now desktop-first. Atom A is 14 months old and no longer reflects current direction." }); ``` ## Cross-tree conflicts A cross-tree conflict is when an atom in your knowledge graph directly contradicts a strategy node. These are the most strategically significant — they mean what you believe and what you're trying to do are out of alignment. ``` Knowledge atom: "Free tier users are not strategic — focus on enterprise." Strategy node: KEY_RESULT: "Grow free tier signups by 50% this quarter" → Cross-tree conflict: ATOM_CONTRADICTS_STRATEGY ``` Resolving a cross-tree conflict usually means one of three things: - The strategy is wrong — update it to reflect your actual direction - The atom is wrong — the belief has changed, retire it - Both are right in different scopes — add context to both to clarify ```javascript const crossTreeConflicts = await health(); await health({ conflictId: crossTreeConflicts[0].id, resolution: "ATOM_IS_STALE", rationale: "We changed strategy in Q2 — free tier is now a growth lever, not a distraction." }); ``` ## When to dismiss vs. resolve Dismiss when the detection is genuinely wrong — two atoms that use similar language but aren't actually contradictory. Resolve when there's a real tension, even if the answer is "keep both in different contexts." A well-maintained workspace has zero open high-confidence conflicts. Low-confidence conflicts can be periodically reviewed and dismissed if they're false positives. ## Quick cheatsheet - Old atom stale → `KEEP_NEW` - New atom wrong → `KEEP_EXISTING` - Both partly right → `KEEP_BOTH` or `MERGE` - Detection wrong → `DISMISS` - Cross-tree: `ATOM_IS_STALE` (retire atom), `STRATEGY_IS_WRONG` (update strategy node), `DIFFERENT_SCOPE` (add context to both) --- # Cookbook: Vega — Your First PR Review Source: https://docs.momentalos.com/cookbooks/vega-first-pr Once you've connected Vega and installed the GitHub App, it reviews every PR automatically. Here's what to expect and how to get the most out of it. **Not set up yet?** Go to [Settings → Apps → Vega](https://app.momentalos.com/apps/vega), subscribe, and install the GitHub App on your org. Then open any PR — Vega comments within seconds. ## Reading the review comment Vega posts a single structured comment on every PR. Here's what each section means: ``` ## Vega Review - MEDIUM Good refactor overall. The auth token refresh logic is cleaner, but there are two callers of the old refreshToken() function that weren't updated. **Concerns:** - auth.service.ts line 47: refreshToken() is still called by session.middleware.ts and token.validator.ts — both will break after this change **Test checklist:** - [ ] Verify token refresh still works when the access token is expired but refresh token is valid - [ ] Confirm session.middleware.ts handles the new return shape from the updated function - [ ] Test concurrent refresh requests don't produce duplicate sessions **Security scan:** - [MEDIUM] Sensitive data logged: token value visible in logger.debug() call on line 83 **Intent:** 78% match — PR description says "refactor token refresh" but also modifies session expiry logic which isn't mentioned **MCI completeness:** 2 missed callers of refreshToken() --- Vega - Auto-merge: not eligible ``` ### Risk levels | Level | Meaning | Auto-merge eligible? | | --- | --- | --- | | **LOW** | No auth, DB schema, or API contract changes. No concerns flagged. | Yes — if no concerns | | **MEDIUM** | Logic changes with possible edge cases, or some concerns flagged. | No | | **HIGH** | Auth, payments, DB migrations, breaking API changes, or critical security findings. | No | ## Acting on findings ### Concerns Concerns are things Vega believes need attention before merge. They're specific — always referencing a file, function, or line. Work through them before merging. If you believe a concern is wrong, mention `@vega` on the relevant line to explain why. Vega will re-evaluate and either confirm the concern or acknowledge the dismissal. ### Security findings CRITICAL findings should always be addressed before merge. HIGH findings on a LOW-risk PR escalate the risk rating and should be reviewed. MEDIUM findings are informational — use your judgment. If a security finding is a false positive (common with patterns that look like secrets but aren't): ``` @vega the "token" in logger.debug() on line 83 is a CSRF token used for UI rendering, not an auth token. It contains no user credentials and is safe to log. ``` ### MCI completeness If Vega flags missed callers, it means you changed a function that's called from places not touched in this PR. Missed callers are often the cause of subtle bugs — the callee changed but the callers still expect the old behavior. To get MCI caller analysis, your repo needs to be indexed. See [Set Up Code Intelligence](/cookbooks/setup-code-intelligence). ### Test checklist The test checklist is what Vega thinks should be tested given the diff. It's not a pass/fail gate — it's a prompt for your review. If a checklist item is already covered by an existing test, you can note that in a comment. ## Using @vega Mention `@vega` anywhere in a PR comment to ask a question about the code. Vega uses the surrounding diff as context. ``` @vega why is the token refreshed here instead of at the call site? ``` ``` @vega is this change backward-compatible with the v1 API contract? ``` For questions about the whole PR rather than a specific line, mention Vega in a top-level review comment. It will fetch the entire diff before answering. ## Enforcing your team's standards Vega automatically enforces PRINCIPLE and DECISION atoms from your Momental workspace. If a PR violates a documented team standard, it appears in Concerns — not just a note. To add a standard that Vega enforces: ```javascript await node_create({ statement: "All database queries must use the ORM. No raw SQL in application code.", nodeType: "PRINCIPLE", // status omitted - agent atoms land in the Sources inbox as DRAFT for human review }); ``` The more standards you document, the more precisely Vega reviews against your team's actual engineering culture rather than generic best practices. ## Troubleshooting **Vega didn't comment on my PR.** Check that the GitHub App is installed on the repo's org (not just your personal account). Draft PRs are not reviewed — convert to a regular PR first. **The review seems generic.** Vega's review quality improves with two inputs: (1) your MCI index — callers and callees give it structural context; (2) your team's PRINCIPLE/DECISION atoms — without them, Vega applies general best practices only. --- # Cookbook: Auto-Generate Documentation Source: https://docs.momentalos.com/cookbooks/auto-generate-docs The meta-cookbook. This is how Momental documents itself - using its own knowledge graph, agents, and task system to keep docs current without human writing effort. ## The Problem This Solves Documentation rots. A new MCP tool ships, the code is merged, and the docs never get written because engineers are already on the next feature. Or docs get written but fall out of date when the API changes three months later. Momental's approach: treat documentation as a first-class pipeline, not an afterthought. Every public surface is a node in the knowledge graph. Every undocumented surface is a task in the backlog. Agents write the drafts. Humans review the final output. ## The Full Pipeline ```text Code change lands (PR merged) → PR hook detects affected public surfaces → Tasks auto-created for each undocumented surface → Tasks assigned to your documentation agent → your documentation agent researches via MCI tools (public interface only): code_inspect - exact parameter names and types code_inspect - real usage examples from test suite browse - why this feature exists for users → your documentation agent writes all four Divio sections: Reference - parameter table, types, defaults Tutorial - step-by-step with verified code example How-To - most common use case Explanation - why this exists from the user's perspective → Lyra reviews for accuracy + leakage: ✓ Parameter names match public API ✓ No internal agent IDs, table names, or infra details ✓ No use of "simply" ✓ Every claim has a concrete example → If approved: doc page published automatically → If flagged: escalated to human reviewer with specific issues noted → llms.txt regenerated on next deploy ``` ## Step 1: Create the Strategy Tree Structure First, wire documentation into your strategy tree so every doc task has a home. ```javascript // Create the documentation objective (one-time setup) const objective = await node_create({ nodeType: "OBJECTIVE", statement: "Every public surface is documented with working examples", parentId: "your-product-mission-id" }); // Create EPICs for each documentation area const mcpEpic = await node_create({ nodeType: "EPIC", statement: "MCP Tool Reference - all tools documented", parentId: objective.id }); const agentEpic = await node_create({ nodeType: "EPIC", statement: "Agent Catalog - all agents documented", parentId: objective.id }); ``` ## Step 2: Seed Documentation Tasks Create one task per undocumented surface. The acceptance criteria template is the key - it tells your documentation agent exactly what to research and what to write. ```javascript function buildDocAC(toolName) { return ` ## Research (public interface only) - [ ] code_inspect("${toolName}") - all parameters extracted - [ ] code_inspect - at least 2 real usage examples from test suite - [ ] browse - user-facing rationale confirmed ## Content (Divio framework) - [ ] Reference: parameter table with types, defaults, and descriptions - [ ] Tutorial: step-by-step using a test-derived example (full imports) - [ ] How-to: most common real-world use case from the user's perspective - [ ] Explanation: why this tool exists for users ## Hard rules - zero exceptions - [ ] No internal agent IDs (use public names only) - [ ] No database table or column names - [ ] No internal file paths, class names, or service names - [ ] All code examples sourced from tests - not from implementation - [ ] All code examples include full import statements - [ ] No use of the word "simply" `; } const tools = ["code_search", "node_create", "work_begin"]; for (const tool of tools) { const task = await task({ statement: `Doc: \`${tool}\` MCP tool`, parentId: mcpEpic.id, acceptanceCriteria: buildDocAC(tool) }); await task({ taskId: task.id, agentId: "your-doc-agent-id" }); } ``` ## Step 3: The Research Loop (What the Documentation Agent Does) When your documentation agent picks up a documentation task, it follows this research protocol. You can replicate this in your own agents or scripts: ```javascript // your documentation agent's research loop for a single tool async function researchTool(toolName) { // 1. Get exact parameter names/types from the public signature const signature = await code_inspect(toolName); // 2. Find real usage examples in the test suite const tests = await code_inspect({ query: toolName }); // 3. Understand why this tool exists from the user's perspective const strategy = await browse({ query: toolName, depth: 2 }); return { signature, tests, strategy }; } ``` ## Step 4: The Public Surface Boundary The most critical rule: documentation must never expose internal implementation details. Build this check into your acceptance criteria and your reviewer (Lyra) enforces it. | Never include | Why | | --- | --- | | Internal agent IDs | These are internal references - use public names like "Lyra" or "Sirius" | | Database table/column names | Implementation detail that may change | | GCP or cloud infrastructure details | Reveals internal architecture | | Internal file paths or class names | Not part of the public API surface | | Execution traces or service wiring | Exposes system internals | | The word "simply" | Minimizes user friction - acknowledge difficulty instead | ## Step 5: The Lyra Quality Gate After your documentation agent submits, Lyra runs two checks before auto-publishing: ```javascript // Example leakage check (adapt patterns to your org) function checkDocForLeakage(content) { const patterns = [ /internal.w+.com/g, // internal service URLs /src/internal//g, // internal file paths /simply/gi // forbidden word ]; const violations = []; for (const pattern of patterns) { const matches = content.match(pattern); if (matches) violations.push({ pattern: pattern.toString(), matches }); } return violations; } // If violations found → escalate to human (do not auto-publish) // If clean → document(docId) ``` ## Step 6: Auto-Publish on Approval ```javascript // your documentation agent's publish flow after self-check passes const doc = await document({ title: `${toolName} - MCP Reference`, content: generatedMarkdown, domain: "documentation" }); // Submit for review - Lyra picks this up await task(taskId, { summary: "Draft complete. Leakage self-check passed. Ready for Lyra review.", artifactId: doc.id }); // If Lyra approves (sets task to DONE): await document({ documentId: doc.id }); // Page is now live and included in llms-full.txt on next deploy ``` ## Keeping Docs Fresh: The Drift Loop The pipeline above handles new surfaces. For keeping existing docs current, run a weekly conflict detection scan and gap audit: ```javascript // Weekly drift detection (run as a cron task assigned to Lyra) async function weeklyDocAudit() { // 1. Find surfaces with no documentation const gaps = await health({ scope: "documentation" }); for (const gap of gaps) { const task = await task({ statement: `Doc: ${gap.surfaceName} (gap detected)`, parentId: mcpEpicId, acceptanceCriteria: buildDocAC(gap.surfaceName) }); await task({ taskId: task.id, agentId: "your-doc-agent-id" }); } // 2. Trigger conflict detection - flags stale doc claims await health(); // Conflicts appear in health - assigned to your documentation agent for updates } ``` --- # Cookbook: Set Up Code Intelligence Source: https://docs.momentalos.com/cookbooks/setup-code-intelligence Code Intelligence (MCI) builds a semantic map of your codebase — every function, class, and route, who calls them, and what breaks if you change them. Once indexed, Lyra, Vega, Sirius, and your own agents can search code by meaning rather than text pattern. **Expected time:** 10 minutes for setup. First index takes 1–5 minutes depending on repo size. All subsequent updates are incremental and finish in seconds. ## Prerequisites - Node.js 22 or later - A Momental API key ([Authentication guide](/guides/authentication)) - A git repository (TypeScript, JavaScript, Python, Go, or Swift) ## Step 1 — Install the CLI ```bash npm install -g @momentalos/cli ``` Verify: ```bash momental-indexer --version ``` ## Step 2 — Run the initial index ```bash cd /path/to/your-repo momental-indexer \ --dir . \ --api-key mmt_YOUR_KEY \ --name my-repo ``` This command: - Registers `my-repo` in your Momental workspace - Scans all source files and extracts symbols (functions, classes, types, routes) - Builds the call graph (who calls what) - Enables semantic search across all symbols - Uploads everything to Momental You'll see progress as files are processed: ``` [indexer] Scanning 847 files... [indexer] Extracted 12,340 symbols [indexer] Building call graph... [indexer] Uploading batch 1/13... [indexer] Done. Repo ID: repo_abc123 ``` ## Step 3 — Enable advanced features (optional) ### Call graph (TypeScript/JavaScript) ```bash momental-indexer --dir . --api-key mmt_YOUR_KEY --name my-repo \ --ts-calls ``` Traces which functions call which others. Powers blast radius analysis — before changing a function, see every caller that could be affected. ### Test mapping ```bash momental-indexer --dir . --api-key mmt_YOUR_KEY --name my-repo \ --ts-calls --ts-tests ``` Maps source files to their test files. When Vega or Sirius modifies a file, they know exactly which tests to run. ### Co-change intelligence ```bash momental-indexer --dir . --api-key mmt_YOUR_KEY --name my-repo \ --ts-calls --ts-tests --git-cochange ``` Analyzes git history to surface files that tend to change together. If you edit `auth.service.ts`, and it historically co-changes with `session.middleware.ts`, you'll be reminded to check both. ## Step 4 — Enable semantic search Embeddings are **not** auto-generated by the indexer. Until you compute them, `code_search action:search` falls back to BM25 and the response includes `degraded: true`. Trigger generation explicitly: ```text code_manage({ action: "embed", repoId: "" }) ``` Allow ~1 minute per ~1,000 symbols. Check progress without re-generating with `code_manage({ action: "embed", repoId, statusOnly: true })`. ## Step 5 — Run your first search From Claude Code or any MCP client: ```javascript // Semantic search — finds by meaning, not just text const results = await code_search({ action: "search", query: "user authentication and token refresh", repoId: "repo_abc123" }); // results[0] => // { // name: "refreshAccessToken", // filePath: "src/services/auth.service.ts", // docstring: "Refreshes the user's JWT...", // callers: [...], // callees: [...] // } ``` ```javascript // Exact symbol lookup — fast, no embeddings const symbol = await code_search({ action: "find", name: "createUser", repoId: "repo_abc123" }); ``` ## Step 6 — Keep the index current ### Incremental reindex (every commit) The fastest way to keep the graph current. `--incremental-files` accepts either a comma-separated list or `-` to read newline-separated paths from stdin. Behind the scenes this calls `code_manage action:update_files` — a per-file delete-then-insert that preserves co-change pairs and embeddings for files you didn't touch. ```bash # Stdin (typical CI / git-hook): git diff --name-only HEAD~1 HEAD | \ momental-indexer \ --dir . \ --repo-id \ --incremental-files - \ --git-sha "$(git rev-parse HEAD)" # Or explicit list: momental-indexer \ --dir . \ --repo-id \ --incremental-files src/auth.ts,src/billing.ts ``` `--repo-id` is required for incremental — it's how the indexer skips registration and targets the existing graph. ### UI-triggered reindex (`--watch` mode) Long-running developer machine or CI box that should pick up "Reindex" button presses from the Momental UI. Polls `code_manage action:check_pending` on the given interval and runs a full index when a request appears. **Not** a filesystem watcher. ```bash momental-indexer \ --dir . \ --repo-id \ --watch 30 # poll interval in seconds ``` `--watch` requires `--repo-id`. ### Full re-index (weekly or after large refactors) Re-run the Step 2 command. `code_manage action:submit_index` is an atomic full replacement of all symbols + edges for the repo. ## Step 7 — Auto-index from Claude Code (hands-off) If you use Claude Code, you don't need to run `momental-indexer` by hand at all. Add these hooks to your project's `.claude/settings.json` once and Claude Code keeps the index fresh on its own — a full index when a session starts, and an incremental re-index after every edit. Both run in the background so they never block you, and both no-op silently when the CLI isn't installed. ```json { "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "command -v momental-indexer >/dev/null && momental-indexer --dir . --ts-calls --git-cochange --api-key \"$MOMENTAL_API_KEY\" >/dev/null 2>&1 &" } ] } ], "PostToolUse": [ { "matcher": "Edit|Write|MultiEdit", "hooks": [ { "type": "command", "command": "command -v momental-indexer >/dev/null && git diff --name-only HEAD | momental-indexer --dir . --incremental-files - --api-key \"$MOMENTAL_API_KEY\" >/dev/null 2>&1 &" } ] } ] } } ``` Prereqs: install the CLI once (`npm install -g @momentalos/cli`) and export your key so the hook can read it (`export MOMENTAL_API_KEY=mmt_xxx` in your shell profile). After the first SessionStart index, semantic search is ready — no manual step. The manual commands above still work for non–Claude-Code tools, CI pipelines, or a one-off rebuild. ## Key MCI Tools Once indexed, these tools are available via MCP: | Tool | What it does | | --- | --- | | `code_search` | Semantic + keyword search over all symbols | | `code_search({ action: "find" })` | Exact symbol lookup by name | | `code_inspect({ action: "symbol" })` | Full details: callers, callees, cluster, linked tasks | | `code_search({ action: "file" })` | All symbols in a file with call context | | `code_inspect({ action: "blast" })` | Blast radius: what breaks if this symbol changes | | `code_inspect({ action: "tests" })` | Which test files cover a given source file | | `code_inspect({ action: "diff_impact" })` | Given changed files, what else is affected | | `code_manage({ action: "claim" })` | Declare which files you're editing (multi-agent coordination) | `` ## Multi-Agent Coordination When multiple agents are working in the same repo, use `code_manage({ action: "claim" })` before editing files. It surfaces conflicts — if another agent has claimed a file, you're warned before writing to it. ```javascript // Declare files before editing await code_manage({ action: "claim", repoId: "repo_abc123", filePaths: ["src/services/auth.service.ts"], taskId: "task_uuid" }); // If a peer agent has claimed these files, you'll see: // { conflicts: [{ agentName: "Sirius", filePaths: [...] }] } ``` ## Supported languages - TypeScript — with calls and tests - JavaScript - Python - Go - Swift `` --- # Changelog Source: https://docs.momentalos.com/changelog Recent platform updates. For questions about any change, contact [hello@momentalos.com](mailto:hello@momentalos.com). ## May 2026 ### Canvas product tree + atom drawer The product builder now renders your product tree as an interactive canvas. Click any node to open the atom drawer — create, edit, and link knowledge atoms without leaving the canvas. Replaces the legacy list-view page. ### Live activity narrative The dashboard activity feed now shows a readable narrative for each event: actor name, linked node with inline preview, and action timestamp. Filter by agent, human, or node type. ### OKR auto-fill for Key Results When creating Key Results on an Objective, Momental now suggests KR statements based on your strategy tree context. Accept suggestions individually or generate all at once. Includes a new glossary help modal for OKR terminology. ### Plans toolbar: Move + artifact drawer The Plans page now includes a global Move toggle for reordering nodes via drag-and-drop, and an artifact drawer on tasks that shows attached files, URLs, and documents without opening a separate panel. ### Altair — General Research agent (alpha) Altair is now wired as a production research agent. Assign it tasks requiring web research, Google Analytics analysis, user research, or usability testing. Available to all teams. Agent ID: `altair`. ## April 2026 ### Product-management agents (beta) Product-management agents are available in beta to coordinate epics and solutions. See the [Agents page](/agents). ### Vega — Engineering standards enforcement Vega now reads your team's PRINCIPLE and DECISION atoms before every review and enforces them as hard concerns — not just advisory notes. Create PRINCIPLE atoms in your Momental workspace to add team-specific rules to every PR review. ### Vega — @vega Q&A Mention `@vega` on any PR comment line to ask a question. Vega replies in-thread using the diff hunk as local context. For full-PR questions, mention Vega in a top-level review body. ### MCP v2 endpoint Added the v2 MCP endpoint (`https://mcp.momentalos.com/mcp/v2`) with synthesized, context-rich briefs. New external API keys issued after April 2026 use the consolidated MCP endpoint instead. ### momental_agent_heartbeat_context New tool for resuming interrupted agent work. Returns a batch snapshot of current state: active task lock, last checkpoint, pending mentions, and assigned tasks. Replaces several individual lookups at session start. ### Code Intelligence — co-change detection The MCI indexer now supports `--git-cochange` flag for co-change intelligence. Analyzes git history to surface files that tend to change together — if you edit one, you're reminded to check the other. ### Aquila — Tech Lead agent (beta) Aquila (Tech Lead) is now available as a beta agent. See [Aquila](/agents/aquila) documentation. ## March 2026 ### Vega general availability Vega is now generally available at $299/month per workspace. Connect via the [Vega settings page](https://app.momentalos.com/apps/vega). Includes unlimited PR reviews across all connected repos. ### momental_code_diff_impact New MCI tool: given a list of changed files, returns all affected symbols and a list of test files to run. Use this before editing to understand the blast radius of your changes. ### momental_agent_setup New tool on the v1 endpoint. Returns a step-by-step setup guide customized to your agent type and workspace configuration. Useful for onboarding a new agent to an existing workspace. ### @momentalos/cli published The `@momentalos/cli` npm package is now publicly available. Install with `npm install -g @momentalos/cli` to access `momental-indexer` for code intelligence setup. ### Dependency intelligence in Vega For `package.json` version bumps, Vega now fetches changelogs, extracts breaking API changes, and checks whether call sites in your codebase have been updated. ---