Thoughts & Captures
Every piece of knowledge in Cortexa is a thought -- a unit of captured text enriched with structured metadata. Thoughts are encrypted at rest (AES-256-GCM), embedded as semantic vectors, and indexed for both keyword and meaning-based retrieval.
Thought Types
Each thought has a type that tells Cortexa (and your AI agents) what kind of knowledge it represents. When agents call cortexa_context, results are grouped by type with the most actionable types first.
| Type | When to use | Priority in context briefs |
|---|---|---|
decision | A choice you made and why. "Switched from Redis to DragonflyDB for caching because..." | 1st |
architecture | System design, data flow, component responsibilities | 2nd |
pattern | Reusable approaches, code patterns, conventions | 3rd |
debug | Root causes, stack traces, things that broke and why | 4th |
todo | Work to be done, follow-ups, reminders | 5th |
discovery | Something you learned or found that was surprising | 6th |
question | Open questions that need answers | 7th |
note | Everything else -- freeform, no particular structure | 8th |
Choosing the right type
Types matter most when agents consume your vault. A decision tagged thought surfaces ahead of a note with the same relevance score, because decisions are more likely to be actionable in a coding session. If you are not sure, use note -- you can always change it later.
When capturing via the app popup, thoughts default to note. When capturing via MCP with cortexa_capture, the thought_type field is required -- agents should pick the most specific type they can.
Capture via MCP
{
"content": "Switched from brute-force cosine to HNSW index for O(log N) search",
"thought_type": "decision",
"project": "Cortexa",
"confidence": "high",
"tags": ["performance", "hnsw"]
}Capture via CLI
cortexa-cli capture "Switched to HNSW for O(log N) search" \
--thought-type decision \
--project Cortexa \
--tag performance --tag hnswMetadata Fields
Structured captures (via cortexa_capture or the CLI capture command) support rich metadata that improves search relevance and context injection.
| Field | Type | Purpose |
|---|---|---|
agent | string | Which AI agent captured this: claude-code, cursor, gemini, cli, etc. |
project | string | The project or repo name. Items from the same project get a +15% boost in cortexa_context |
file_context | string | Comma-separated file paths relevant to this thought. Items mentioning the same files get a +10% boost |
language | string | Programming language, if relevant |
session_id | string | Groups captures from the same work session (see below) |
confidence | enum | high, medium, or low. Helps agents weight conflicting information |
tags | string[] | Additional tags beyond any auto-extracted ones |
All metadata fields are optional. The more you provide, the better Cortexa can surface the right context later.
Example: fully attributed capture
{
"content": "The auth middleware was rewritten to use JWT with RS256 instead of HS256. The public key lives in /etc/app/jwt.pub and is loaded at startup. Session tokens are now stateless -- no Redis dependency for auth.",
"thought_type": "architecture",
"agent": "claude-code",
"project": "backend-api",
"file_context": "src/middleware/auth.rs, src/config.rs",
"language": "rust",
"session_id": "2025-06-15-auth-rewrite",
"confidence": "high",
"tags": ["auth", "jwt", "security"]
}Session Grouping
The session_id field lets you group related captures from a single work session. This is useful when an AI agent produces multiple insights during one task -- you can later retrieve the full session with cortexa_recent.
# Agent captures multiple thoughts during one session
cortexa_capture({ content: "...", session_id: "refactor-2025-06-15", ... })
cortexa_capture({ content: "...", session_id: "refactor-2025-06-15", ... })
# Later, retrieve everything from that session
cortexa_recent({ session_id: "refactor-2025-06-15" })Session IDs are free-form strings. A good convention is <task>-<date> or <project>-<ticket>, but anything works as long as it is consistent within a session.
Tags
Tags are free-form labels attached to thoughts. They come from three sources, all additive:
1. Inline #hashtags
Write #hashtag anywhere in your capture content and Cortexa extracts it automatically:
Discovered that #postgres JSONB queries are 10x faster than
separate table joins for our #analytics use caseThis auto-extracts postgres and analytics as tags. The rules:
- Case-insensitive --
#Bug,#bug, and#BUGall becomebug - 2-32 characters -- single-char tags like
#aare ignored, as are tags longer than 32 chars - Alphanumeric + underscore + hyphen --
#foo-barand#baz_quxare valid - Boundary-aware --
word#hashdoes NOT extract a tag; the#must be at the start of text or after whitespace - Deduplicated -- writing
#bugthree times produces onebugtag
2. Template tags
When you capture with a slash template like /idea:, the template's configured tags are applied automatically. The default /idea template adds the idea tag.
3. Explicit tags
Pass tags directly via the API, CLI, or MCP:
# CLI
cortexa-cli capture "some thought" --tag architecture --tag important
# MCP
cortexa_capture({ content: "...", tags: ["architecture", "important"] })Or add tags to any existing thought from the UI by clicking the tag chip area on an expanded item.
Filtering by tag
In the main item list, each thought shows its tag chips. Click any chip to add it to the filter bar. The filter bar also supports Archived and Trash toggles.
Via the API:
# List items with a specific tag
curl "http://127.0.0.1:7373/api/items?tag=architecture&tag=decision" \
-H "Authorization: Bearer $TOKEN"
# CLI
cortexa-cli list --tag architecture --limit 20Capture Paths
Thoughts enter Cortexa through multiple paths. Each identifies itself so per-source defaults can apply different automation:
| Source | Identifier | How to capture |
|---|---|---|
| App popup | manual | Press your hotkey (default Ctrl+Shift+P) |
| CLI | cli | cortexa-cli ingest "..." or cortexa-cli capture "..." --thought-type ... |
| MCP | mcp | cortexa_ingest or cortexa_capture from any MCP agent |
| HTTP API | api | POST /api/ingest with bearer auth |
| Browser extension | extension | Ctrl+Shift+L or right-click menu from any webpage |
| Telegram | telegram | Send a message to your Cortexa bot |
Per-source action defaults are configured in Settings > Notifications > Per-source defaults. For example, you can auto-summarize all Telegram captures while leaving MCP captures unenriched.
Action priority
When a thought is captured, its automation actions (Summarize, Deep Think, Research) are determined in this order:
- Slash template -- if the content starts with
/trigger:, the template's actions win - Explicit options -- if the capture UI or API passes explicit toggles, those win
- Source defaults -- otherwise, the defaults for the capture source are used
What Happens After Capture
Every captured thought triggers a pipeline:
- Encrypt -- content is encrypted with AES-256-GCM and written to
blobs/<id>.bin - Index -- a preview is written to SQLite and the FTS5 full-text index
- Extract tags -- inline
#hashtagsare parsed and stored - Embed -- the embedding provider generates a semantic vector (queued as a background job)
- Auto-link -- once embedded, the knowledge graph finds and links related thoughts
- Actions -- if enabled: summarize, Deep Think, research
The embedding and action jobs run asynchronously in a background worker queue. You can monitor progress in Settings > Activity.
What's Next
- Search -- how hybrid search finds your thoughts by meaning and keywords
- Deep Think -- the expand, critique, synthesize pipeline
- Templates -- slash-command shortcuts for common capture patterns