### Install and start Engram via npm Source: https://www.getengram.app/docs/guides/claude-code Install the Engram CLI globally via npm, authenticate with an API key (replace YOUR_KEY), and start the daemon with auto-install. ```shell npm install -g @getengram/cli engram auth login engram_sk_live_YOUR_KEY engram start --install ``` -------------------------------- ### Install and start Engram daemon via Homebrew Source: https://www.getengram.app/docs/guides/claude-code Commands to install Engram using Homebrew, authenticate with an API key (replace YOUR_KEY), and start the daemon as a service. ```shell brew tap get-engram/engram brew install engram engram auth login engram_sk_live_YOUR_KEY brew services start engram ``` -------------------------------- ### engram start command options Source: https://www.getengram.app/docs/cli Starts the Engram daemon. By default it detaches as a background process. Use --foreground to run in the foreground (for debugging or launchd) and --install to also enable auto-start on login. ```bash engram start # Detached background process engram start --foreground # Run in foreground (for debugging or launchd) engram start --install # Start + enable auto-start on login ``` -------------------------------- ### Install @getengram/sdk with npm Source: https://www.getengram.app/docs/sdk Install the SDK package using npm. ```bash npm install @getengram/sdk ``` -------------------------------- ### engram install command Source: https://www.getengram.app/docs/cli Enables auto-start on login (macOS launchd). Writes a LaunchAgent plist so the daemon starts automatically when you log in and restarts if it crashes. ```bash engram install ``` -------------------------------- ### Session 1: Stripe Migration Memory Example Source: https://www.getengram.app/docs/guides/codex Example of a Codex session where it searches Engram for prior context and stores migration details. Shows the interaction format and what gets stored. ```text You: Refactor the payment module to use Stripe's new v2 API. Make sure we keep the webhook signature verification. Codex: [searches Engram — no prior context] Codex: I'll refactor the payment module from Stripe v1 to v2... Codex: [stores in Engram: title: "Stripe v1 → v2 migration for payment module" tags: ["payments", "migration", "stripe"] messages: migration approach, webhook verification requirement] ``` -------------------------------- ### Connection string examples Source: https://www.getengram.app/docs/secret-redaction Examples of database and message broker URIs with embedded credentials that are detected by the redaction engine. ```text postgres://admin:password@db.example.com:5432/mydb mongodb+srv://user:pass@cluster.mongodb.net/db redis://default:secret@cache.example.com:6379 amqps://user:pass@rabbitmq.com ``` -------------------------------- ### Install Engram via Homebrew Source: https://www.getengram.app/docs/getting-started Installs the Engram CLI using Homebrew. Recommended installation method for macOS users. ```bash brew install get-engram/engram/engram ``` -------------------------------- ### API Key Format Example Source: https://www.getengram.app/docs/authentication Example of an Engram API key. It starts with 'engram_sk_live_' followed by 32 random characters, totaling 47 characters. ```text engram_sk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZaBcDeF ``` -------------------------------- ### Start Engram daemon via npm Source: https://www.getengram.app/docs/getting-started Starts the Engram background daemon using the npm-installed CLI. The daemon auto-captures AI conversations and starts on login. ```bash engram start --install ``` -------------------------------- ### Install Engram via npm Source: https://www.getengram.app/docs/getting-started Installs the Engram CLI globally using npm. Alternative installation method for Node.js users. ```bash npm install -g @getengram/cli ``` -------------------------------- ### REST API curl example for storing and searching memories Source: https://www.getengram.app/docs/api-reference Shows how to store a memory via POST /api/v1/messages and search it later with GET /api/v1/search. Uses the base URL https://mcp.getengram.app and requires an API key. ```bash # Store a memory curl -X POST https://mcp.getengram.app/api/v1/messages \ -H "Authorization: Bearer engram_sk_live_..." \ -H "Content-Type: application/json" \ -d '{"messages":[{"role":"user","content":"We chose Postgres over DynamoDB for the billing service."}]}' # Search it later curl "https://mcp.getengram.app/api/v1/search?q=billing+database+choice" \ -H "Authorization: Bearer engram_sk_live_..." ``` -------------------------------- ### Clean install and build with pnpm Source: https://www.getengram.app/docs/troubleshooting Run these commands in order to clean install dependencies, build all packages, and check types. The build order is important: @getengram/shared must build before @getengram/db, which must build before @getengram/mcp-server. Turborepo handles this automatically with pnpm build. ```bash # Clean install rm -rf node_modules pnpm install # Build all packages pnpm build # Check types pnpm typecheck ``` -------------------------------- ### create_conversation example Source: https://www.getengram.app/docs/api-reference Example invocation of create_conversation with title, agent_id, tags, and metadata. ```yaml create_conversation title: "Weekly standup — March 23" agent_id: "support-bot-v2" tags: ["standup", "engineering"] metadata: { "team": "platform" } ``` -------------------------------- ### Start Engram daemon via Homebrew Source: https://www.getengram.app/docs/getting-started Starts the Engram background daemon using Homebrew services. The daemon auto-captures AI conversations and starts on login. ```bash brew services start engram ``` -------------------------------- ### Chunk Format Example Source: https://www.getengram.app/docs/concepts Shows the exact format of a chunk, which is a sequence of messages with roles and content. This example illustrates a 5-message window with roles user, assistant, and tool. ```text [user]: Can you check the logs? [assistant]: Sure, looking at the error logs now. [tool]: {"errors": [{"level": "ERROR", "msg": "connection refused"}]} [assistant]: I see a connection refused error in the logs. [user]: That's the one — when did it start? ``` -------------------------------- ### Session 2: Subscription Management Memory Example Source: https://www.getengram.app/docs/guides/codex Example of a Codex session where it retrieves prior context from Engram to inform new work. Shows how memory is used to maintain consistency. ```text You: Add subscription management to the payment module. Codex: [searches Engram → finds Stripe migration context] Codex: I see we recently migrated to Stripe's v2 API. I'll implement subscription management using the v2 Subscriptions API, consistent with the existing payment module patterns... ``` -------------------------------- ### engram log - Example output Source: https://www.getengram.app/docs/cli Example output from the engram log command showing project name, branch, timestamp, and message count. ```text engram main 2026-04-14 09:32 47 msgs conv_abc123 [auto] my-project feature/auth 2026-04-14 08:15 23 msgs conv_def456 [auto] ``` -------------------------------- ### Shared Memory Example Source: https://www.getengram.app/docs/guides Illustrates how using the same Engram API key across multiple tools enables automatic memory sharing. The example shows three scenarios where actions in one tool are recalled by another. ```text Claude Code stores a decision → Cursor finds it next session Codex investigates a bug → Claude Desktop recalls the resolution Windsurf sets up a project → Claude Code knows the architecture ``` -------------------------------- ### Full Support Agent Example with Memory Source: https://www.getengram.app/docs/guides/custom-agents Complete TypeScript example of a support agent that connects to Engram via MCP, searches customer history, generates responses with Anthropic, and stores interactions. Requires an Engram API key and the MCP SDK. ```typescript import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import Anthropic from "@anthropic-ai/sdk"; // Connect to Engram const transport = new StreamableHTTPClientTransport( new URL("https://mcp.getengram.app/mcp"), { requestInit: { headers: { Authorization: "Bearer engram_sk_live_your_key_here" }, }, } ); const engram = new Client({ name: "support-agent", version: "1.0.0" }); await engram.connect(transport); // Search for customer history async function getCustomerContext(customerId: string, issue: string) { const result = await engram.callTool({ name: "search", arguments: { query: `customer ${customerId} ${issue}`, tags: ["support"], limit: 5, }, }); return JSON.parse(result.content[0].text); } // Store the interaction async function storeInteraction(customerId: string, messages: any[]) { const create = await engram.callTool({ name: "create_conversation", arguments: { title: `Support: ${customerId}`, agent_id: "support-agent", tags: ["support", customerId], }, }); const { conversation_id } = JSON.parse(create.content[0].text); await engram.callTool({ name: "append_messages", arguments: { conversation_id, messages }, }); } // Handle a support request async function handleSupport(customerId: string, message: string) { // 1. Get prior context const history = await getCustomerContext(customerId, message); // 2. Build prompt with memory const anthropic = new Anthropic(); const response = await anthropic.messages.create({ model: "claude-sonnet-4-6", max_tokens: 1024, system: `You are a support agent. Here is the customer's prior history:\n${JSON.stringify(history.results)}`, messages: [{ role: "user", content: message }], }); const reply = response.content[0].text; // 3. Store this interaction await storeInteraction(customerId, [ { role: "user", content: message }, { role: "assistant", content: reply }, ]); return reply; } ``` -------------------------------- ### engram search - Example output Source: https://www.getengram.app/docs/cli Example output from the engram search command showing relevance score, conversation ID, and matched text. ```text [80.4%] conv_Y4KAdWuDUTAobIAi3toSC seq 1–3 [system]: Building Engram Phase 2... [assistant]: Codebase analysis complete... [user]: User wants npm and brew distribution... ``` -------------------------------- ### Searching Engram for prior context Source: https://www.getengram.app/docs/examples Example of an Engram search query to retrieve relevant prior conversation context, used at the start of future sessions to avoid re-explaining preferences and setup. ```yaml search query: "project setup preferences standard config" limit: 3 ``` -------------------------------- ### Behind the scenes: RPC flow for env.DB.prepare().run() Source: https://www.getengram.app/docs/architecture Illustrates the internal RPC steps when calling a binding: serialization, sending to the service, execution, and returning the result. Typical latency is 1-5ms. ```text env.DB.prepare("SELECT ...").run() │ ├── Worker runtime serializes the SQL + bound params ├── Sends internal RPC to D1 service (same data center) ├── D1 executes SQL against SQLite ├── Result serialized back └── Returned to your code as a JavaScript object Total latency: typically 1-5ms ``` -------------------------------- ### Example: Memory in Action - Session 1 Source: https://www.getengram.app/docs/guides/cursor Demonstrates the initial session where Cursor stores a decision in Engram. ```text You: We need to add rate limiting to the API. Use a sliding window algorithm with Redis, not the token bucket approach. Cursor: [searches Engram — no prior context for this] Cursor: I'll implement sliding window rate limiting with Redis... Cursor: [stores in Engram: title: "Rate limiting: sliding window with Redis" tags: ["api", "rate-limiting", "architecture"] messages: decision to use sliding window over token bucket, Redis as backend] ``` -------------------------------- ### Traditional server vs Cloudflare Worker comparison Source: https://www.getengram.app/docs/architecture ASCII diagram comparing a traditional server's boot sequence with a Cloudflare Worker's isolate startup. Shows that Workers skip OS boot, runtime start, dependency loading, and DB connection opening, starting directly at request handling with ~1ms startup. ```text Traditional server: Cloudflare Worker: Boot OS ─── doesn't exist Start runtime (Node, Python) ─── doesn't exist Load dependencies ─── doesn't exist Open DB connections ─── doesn't exist Wait for request Start here ─┐ Handle request Handle request │ ~1ms startup Send response Send response │ ───┘ ``` -------------------------------- ### Example: Memory in Action - Session 2 Source: https://www.getengram.app/docs/guides/windsurf Shows how Windsurf retrieves stored preferences from Engram to inform its response in a later session. ```text You: Style the new dashboard component. Windsurf: [searches Engram → finds CSS preferences] Windsurf: I'll style this with Tailwind v4 utility classes directly, avoiding @apply per our earlier decision. Here's the component... ``` -------------------------------- ### Engram MCP client configuration Source: https://www.getengram.app/docs/whitepaper Add this JSON block to your client configuration to connect to Engram's MCP server. It specifies the server URL and an authorization header with your API key. This is the only setup required to start using Engram. ```json { "mcpServers": { "engram": { "url": "https://mcp.getengram.app/mcp", "headers": { "Authorization": "Bearer engram_sk_live_..." } } } } ``` -------------------------------- ### Creating a conversation and appending messages in first session Source: https://www.getengram.app/docs/examples Example of Engram API calls to create a conversation and append messages, used when the agent needs to remember user preferences and project setup details. The conversation is stored with a title and tags, then messages are appended to the conversation ID. ```yaml create_conversation title: "Project setup preferences" tags: ["preferences", "setup"] append_messages conversation_id: "conv_..." messages: - role: "user" content: "Set up a new Next.js project with our standard config" - role: "assistant" content: "What's your standard config? I'll remember it for next time." - role: "user" content: "Next.js 14 with App Router, TypeScript strict mode, Tailwind, pnpm, src/ directory, import alias @/. ESLint with our custom config from @acme/eslint-config." - role: "assistant" content: "Got it. Setting up now with those preferences..." ``` -------------------------------- ### Migration files list Source: https://www.getengram.app/docs/architecture List of migration files in packages/db/migrations/ with descriptions: 0001_initial_schema.sql creates 5 tables with foreign keys and cascading deletes, and 0002_add_indexes.sql adds 7 indexes for query performance. ```text 0001_initial_schema.sql ── 5 tables with foreign keys + cascading deletes 0002_add_indexes.sql ── 7 indexes for query performance ``` -------------------------------- ### Example: Memory in Action - Session 1 Source: https://www.getengram.app/docs/guides/windsurf Shows how Windsurf stores a user preference about Tailwind v4 in Engram during a session. ```text You: Let's set up the project with Tailwind v4. Don't use the @apply directive — we had issues with it in the last project. Windsurf: [stores in Engram: title: "CSS approach: Tailwind v4 without @apply" tags: ["frontend", "css", "preferences"] messages: use Tailwind v4, avoid @apply due to past issues] ``` -------------------------------- ### Example: Memory in Action - Session 2 Source: https://www.getengram.app/docs/guides/cursor Demonstrates the subsequent session where Cursor recalls the decision stored in Engram. ```text You: Add rate limiting to the new /upload endpoint. Cursor: [searches Engram → finds rate limiting decision] Cursor: I'll add sliding window rate limiting using Redis, consistent with the approach we chose for the other API endpoints. Implementing now... ``` -------------------------------- ### get_conversation request example Source: https://www.getengram.app/docs/api-reference Example request for the get_conversation endpoint, specifying conversation_id, message_limit, and message_offset. ```text get_conversation conversation_id: "conv_V1StGXR8_Z5jdHi6B-myT" message_limit: 50 message_offset: 0 ``` -------------------------------- ### append_messages example Source: https://www.getengram.app/docs/api-reference Example invocation of append_messages with a conversation_id and a list of messages, including a tool message. ```yaml append_messages conversation_id: "conv_V1StGXR8_Z5jdHi6B-myT" messages: - role: "user" content: "Can you look up the customer's billing history?" - role: "assistant" content: "I'll check that now." - role: "tool" content: '{"invoices": [{"id": "inv_123", "amount": 99.00}]}' tool_name: "lookup_billing" tool_call_id: "call_abc" - role: "assistant" content: "They have one invoice for $99.00." ``` -------------------------------- ### Set up MCP server with WebStandardStreamableHTTPServerTransport in src/index.ts Source: https://www.getengram.app/docs/architecture Creates a fresh MCP server per request, connects it to a Web Standard transport, and handles the request. Uses no sessions (stateless) and passes the raw Web Request to get a Web Response. ```typescript // In src/index.ts app.all("/mcp", authMiddleware, async (c) => { // 1. Create a fresh MCP server for this request const server = createMcpServer(c.env, auth); // 2. Create a Web Standard transport (stateless) const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined, // no sessions — fully stateless }); // 3. Connect server to transport await server.connect(transport); // 4. Pass the raw Web Request, get back a Web Response return transport.handleRequest(c.req.raw); }); ``` -------------------------------- ### Run Engram CLI without installing Source: https://www.getengram.app/docs/cli Use npx to run the CLI without a global install. ```bash npx @getengram/cli search "your query" ``` -------------------------------- ### Secret assignment examples Source: https://www.getengram.app/docs/secret-redaction Examples of key-value pairs where the key name suggests a secret, detected by the redaction engine. ```text DATABASE_PASSWORD=hunter2 STRIPE_SECRET_KEY="sk_live_..." api_token: "abc123..." jwt_secret = "my-signing-key" ``` -------------------------------- ### list_conversations request example Source: https://www.getengram.app/docs/api-reference Example request for the list_conversations endpoint, specifying agent_id, tags, sort, order, and limit. ```text list_conversations agent_id: "support-bot-v2" tags: ["engineering"] sort: "message_count" order: "desc" limit: 10 ``` -------------------------------- ### Create and populate a session with engram CLI Source: https://www.getengram.app/docs/cli Creates a conversation, stores build output and test output into it, and adds an assistant message. Uses jq to extract the conversation ID. ```bash CONV=$(engram conversations create --title "Build $(date +%F)" --json | jq -r '.conversationId') npm run build 2>&1 | engram store -c $CONV --file - npm test 2>&1 | engram store -c $CONV --role tool --tool test --file - engram store -c $CONV --role assistant "Build and tests complete" ``` -------------------------------- ### list_conversations response example Source: https://www.getengram.app/docs/api-reference Example JSON response for the list_conversations endpoint, showing a conversations array and total count. ```json { "conversations": [ { "id": "conv_V1StGXR8_Z5jdHi6B-myT", "title": "Weekly standup — March 23", "agent_id": "support-bot-v2", "tags": ["standup"], "message_count": 42, "updated_at": "2026-03-23T10:30:00Z" } ], "total": 1 } ``` -------------------------------- ### Memory in Action: Session 2 Source: https://www.getengram.app/docs/getting-started Example of the agent recalling the stored decision in a later session. Shows the agent finding the prior context and applying it. ```text User: "Set up the database for the new service" Agent: [searches Engram → finds Monday's decision] Agent: "Setting up Postgres — we decided on Monday to use it instead of MySQL because of the JSONB support for the catalog schema." ``` -------------------------------- ### PEM private key example Source: https://www.getengram.app/docs/secret-redaction Example of a PEM private key block that is detected and removed in full by the redaction engine. ```text -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWp... -----END RSA PRIVATE KEY----- ``` -------------------------------- ### get_conversation response example Source: https://www.getengram.app/docs/api-reference Example JSON response for the get_conversation endpoint, showing a conversation object with metadata and a messages array. ```json { "conversation": { "id": "conv_V1StGXR8_Z5jdHi6B-myT", "title": "Weekly standup — March 23", "agent_id": "support-bot-v2", "tags": ["standup", "engineering"], "metadata": { "team": "platform" }, "message_count": 42, "created_at": "2026-03-23T10:00:00Z", "updated_at": "2026-03-23T10:30:00Z" }, "messages": [ { "id": "msg_xyz", "role": "user", "content": "Let's start with blockers...", "sequence": 1, "created_at": "2026-03-23T10:00:01Z" } ] } ``` -------------------------------- ### Conversation metadata JSON example Source: https://www.getengram.app/docs/patterns Example of the metadata field on conversations, which accepts arbitrary JSON. Useful for storing user, session, source, and environment information. ```json { "user_id": "user_123", "session_id": "sess_abc", "source": "claude-desktop", "environment": "production" } ``` -------------------------------- ### Initialize Engram client Source: https://www.getengram.app/docs/sdk Import the Engram class and create a new instance with an API key. Optional baseUrl and timeout settings are commented out. ```typescript import { Engram } from '@getengram/sdk' const engram = new Engram({ apiKey: process.env.ENGRAM_API_KEY!, // baseUrl: 'http://localhost:8787', // optional — for local dev // timeout: 30000, // optional — request timeout (ms) }) ``` -------------------------------- ### Custom MCP Client (Python) Source: https://www.getengram.app/docs/integrations Use the `mcp` Python package to connect a custom client to Engram. The example initializes a session and calls the `search` tool with a query and limit. ```python from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client async def main(): headers = { "Authorization": "Bearer engram_sk_live_your_key_here" } async with streamablehttp_client( "https://mcp.getengram.app/mcp", headers=headers ) as (read, write, _): async with ClientSession(read, write) as session: await session.initialize() result = await session.call_tool( "search", arguments={"query": "billing issue", "limit": 5} ) print(result) ```