Engram is a standard + toolchain that turns a codebase into a portable, agent-agnostic semantic context artifact ("Context Pack") plus a query interface that any consumer can use (UI features like smart context menus, integrations, CI bots, IDE plugins, and AI agents).
Instead of every tool re-discovering meaning by scraping code differently, Engram makes meaning explicit, versioned, validated, and queryable.
A Context Pack is a build artifact produced from a repo (or monorepo) at a specific commit. It contains structured datasets describing:
- Navigation: routes → pages → components
- Capabilities: actions/commands users can trigger
- Domain model: entities + relationships
- Interfaces: APIs, events, jobs, webhooks
- Rules: permissions, feature flags, environment constraints
- Provenance: where each fact came from in code/config
Key property: it's agent-agnostic. Nothing in the pack is "prompt-shaped." It's a neutral semantic model.
A runtime (library + optional local server) loads a context pack and answers queries like:
- "What actions are relevant on this page for this user and this selection?"
- "Where is this API implemented and what permissions guard it?"
- "What code + tests + configs are relevant to this error?"
- "What integrations exist for this entity?"
- In-app UI: context menus, command palette, onboarding hints, admin consoles
- Integrations: automation tools that want safe, validated operations
- AI agents: tool calling against a stable action surface
- IDE/CI: "impact analysis," policy checks, change summaries
Today, "context" is rebuilt ad-hoc:
- agents grep or embed files
- plugins parse partial ASTs
- each integration hardcodes app knowledge
- permissions/flags/side effects drift from docs
Engram centralizes this into a single, reproducible semantic contract:
- consistent behavior across tools
- deterministic queries
- governance/security before anything executes
- easier evaluation/debugging ("why did it suggest this?")
npm install -g @engram/cliOr use directly with npx:
npx @engram/cli buildAdd @engram:action annotations to your code:
/**
* @engram:action
* id: customer.open_ticket
* title: Open support ticket
* category: Support
* when:
* pages: [page.customer_detail]
* permissions_all: [ticket.create]
* feature_flags_all: [support_center_enabled]
* inputs:
* - name: subject
* type: string
* required: true
* - name: priority
* type: enum(low, normal, high)
* required: false
* invoke:
* - kind: http
* method: POST
* path: /api/tickets
*/
export async function createTicket(req, res) {
// Implementation
}npx engram buildThis generates a .engram/ directory containing:
manifest.json- Pack metadatagraph/- Structured datasets (actions.jsonl, pages.json, routes.json, etc.)provenance/- Build info and source tracking
# Start local server
npx engram serve
# Or use programmaticallyimport { loadPack } from '@engram/cli';
const runtime = await loadPack('.engram');
const actions = await runtime.queryRelevantActions({
query: 'relevant_actions',
page: { path: '/customers/123' },
user: { permissions: ['ticket.create'] },
runtime: { feature_flags: ['support_center_enabled'] },
});Build Context Pack from codebase.
npx engram buildThe Context Pack is generated in the .engram/ directory in your project root.
Validate Context Pack structure and references.
npx engram validateOptions:
-p, --pack <path>: Path to Context Pack (default:.engram)
Start local daemon serving Context Pack queries.
npx engram serveThe server exposes a POST endpoint at /query that accepts JSON query objects.
Example request:
curl -X POST http://localhost:3001/query \
-H "Content-Type: application/json" \
-d '{"query":"relevant_actions","page":{"path":"/customers/123"},"user":{"permissions":["ticket.create"]}}'Options:
-p, --pack <path>: Path to Context Pack (default:.engram)--port <port>: Port to listen on (default:3001)
Compare two Context Packs.
npx engram diff --pack-a .engram --pack-b .engram.oldQuery Context Pack from command line (for testing).
npx engram query --query-type relevant_actions --data '{"page":{"path":"/customers/123"}}'Supported query types:
relevant_actions- Get actions relevant to current contextpage_context- Get entities, components, and data sources for a page
Options:
-p, --pack <path>: Path to Context Pack directory (default:.engram)-q, --query-type <type>: Query type (relevant_actions,page_context)-d, --data <json>: Query data as JSON string
@engram:action— user-visible capability- (soon)
@engram:entity— domain type declaration - (soon)
@engram:route— route/page metadata - (soon)
@engram:policy— permission/guard definitions
/**
* @engram:action
* id: customer.open_ticket
* title: Open support ticket
* category: Support
* when:
* pages: [page.customer_detail]
* permissions_all: [ticket.create]
* feature_flags_all: [support_center_enabled]
* inputs:
* - name: subject
* type: string
* required: true
* - name: priority
* type: enum(low, normal, high)
* required: false
* invoke:
* - kind: http
* method: POST
* path: /api/tickets
*/
export async function createTicket(req, res) {}Condition operators:
permissions_all- User must have ALL listed permissionspermissions_any- User must have ANY of the listed permissionsfeature_flags_all- ALL listed feature flags must be enabledfeature_flags_any- ANY of the listed feature flags must be enabledruntime_env- Runtime environment must match (e.g.,["prod", "staging"])entities- Entity type must match (for entity-specific actions)
Design principle: the annotation expresses what it does and when it applies. The compiler resolves how it's wired.
Get actions relevant to current context.
{
query: "relevant_actions",
page: { path: "/customers/123" },
user: { roles: ["support_agent"], permissions: ["ticket.create"] },
runtime: { env: "prod", feature_flags: ["support_center_enabled"] },
selection: { entity: "entity.customer", id: "123" }
}Returns:
{
actions: [
{ id: "customer.copy_email", title: "Copy email address", category: "Quick" },
{ id: "customer.open_ticket", title: "Open support ticket", category: "Support", needs_input: ["subject"] }
],
explanations: [
{ action_id: "customer.open_ticket", matched: ["page", "permission", "feature_flag"] }
],
citations: [
{ action_id: "customer.open_ticket", source: "actions.jsonl:line:1881" }
]
}Get entities, components, and data sources for a page.
{
query: "page_context",
page: { path: "/customers/123" }
}Get definition and references for a symbol.
{
query: "symbol_definition",
symbol_id: "src/api/tickets.ts:createTicket"
}Get what would be affected by changing a file/symbol.
{
query: "impact_analysis",
file: "src/api/tickets.ts",
symbol: "createTicket"
}Get where permissions are enforced.
{
query: "permission_map",
permission_id: "ticket.create"
}The Context Pack is stored in .engram/ directory:
.engram/
manifest.json
graph/
routes.json
pages.json
components.jsonl
actions.jsonl
entities.jsonl
apis.jsonl
events.jsonl
policies.json
integrations.jsonl
provenance/
build.json
sources.jsonl
search/
lexical.idx (optional)
semantic.idx (optional)
- JSONL for large appendable datasets (actions, symbols, components)
- JSON for small registries (routes, policies)
- Optional SQLite or DuckDB backend for faster querying
- Optional embeddings index (but not required for MVP)
Every record carries:
- source file + line range
- symbol id (if applicable)
- generator plugin + version
- confidence (declared vs inferred)
- timestamp + commit SHA
This enables "Explain why this action appeared."
Everything needs stable IDs:
page.customer_detailentity.customeraction.customer.open_ticket
Make inference optional and always labeled:
- declared actions: high trust
- inferred suggestions: separate list or low confidence
The standard supports:
- "read-only action"
- "destructive action"
- "requires confirmation"
- "requires elevated permission"
- "requires secrets/integration availability"
So agents/integrations don't do stupid things.
Currently, all functionality is available in the @engram/cli package:
- CLI commands -
engram build|validate|serve|diff|query - Compiler - Annotation parser, discovery, binding, resolution, inference, validation, emission
- Runtime - Load pack, query engine, condition evaluation
Future packages (planned):
@engram/compiler-core- Core compiler functionality (extracted from CLI)@engram/plugins-nextjs/@engram/plugins-react-router- Framework plugins@engram/runtime- Standalone runtime library (extracted from CLI)@engram/adapters-mcp(optional) - Agent tool adapter
Engram is a compiler + standard that turns a repo into a portable semantic context pack and a queryable capability layer, enabling UIs, integrations, and AI agents to discover and execute the right actions in the right context—consistently and safely.
Contributions welcome! Please open an issue or submit a pull request.
MIT