Documentation Index
Fetch the complete documentation index at: https://docs.mengram.io/llms.txt
Use this file to discover all available pages before exploring further.
Installation
Quick Start
const { MengramClient } = require('mengram-ai');
const m = new MengramClient('om-your-api-key');
// Add memories
await m.add([
{ role: 'user', content: 'Fixed the auth bug using rate limiting.' },
]);
// Semantic search
const results = await m.search('auth issues');
// Unified search — all 3 types
const all = await m.searchAll('deployment issues');
// { semantic: [...], episodic: [...], procedural: [...] }
// Cognitive Profile
const profile = await m.getProfile('alice');
// { system_prompt: "You are talking to Alice..." }
TypeScript
import { MengramClient, MengramError, QuotaExceededError } from 'mengram-ai';
const m = new MengramClient('om-...');
const results = await m.search('preferences');
const events = await m.episodes({ query: 'deployment' });
const procs = await m.procedures({ query: 'release' });
Constructor
const m = new MengramClient('om-your-key', {
baseUrl: 'https://mengram.io', // default
timeout: 30000, // 30s default
});
Core Methods
add(messages, options?)
Add memories from a conversation. Extracts all 3 memory types.
const result = await m.add([
{ role: 'user', content: 'We use PostgreSQL and Railway' },
{ role: 'assistant', content: 'Got it.' },
], {
userId: 'alice',
agentId: 'support-bot',
appId: 'production',
expirationDate: '2027-01-01T00:00:00Z',
source: 'slack', // provenance source
metadata: { channel: '#engineering' }, // arbitrary metadata
agentMode: true, // extract from all speakers (user + assistant)
});
// { status: 'accepted', job_id: 'job-...' }
addText(text, options?)
Add memories from plain text.
await m.addText('Meeting notes: decided to use Redis for caching', {
userId: 'alice',
source: 'email',
metadata: { subject: 'Weekly sync' },
});
addFile(file, options?)
Upload a file and extract structured memories. Supports PDF (vision AI), DOCX, TXT, MD. Returns immediately with job_id.
// Node.js — pass a file path
const result = await m.addFile('./meeting-notes.pdf');
// { status: 'accepted', job_id: 'job-...', file_type: 'pdf', page_count: 12 }
// Browser — pass a File object from <input type="file">
await m.addFile(fileInput.files[0]);
// Poll for completion
await m.waitForJob(result.job_id);
Options: userId, agentId, runId, appId, filename (override filename for Blob inputs).
File size limits: Free 10MB, Pro 50MB, Business 100MB.
search(query, options?)
Semantic search with re-ranking.
const results = await m.search('database preferences', {
limit: 10,
graphDepth: 3,
userId: 'alice',
});
searchAll(query, options?)
Unified search across all 3 memory types.
const all = await m.searchAll('deployment issues', { limit: 5 });
// { semantic: [...], episodic: [...], procedural: [...] }
getAll(options?) / getAllFull(options?)
const memories = await m.getAll({ userId: 'alice' });
const full = await m.getAllFull({ userId: 'alice' }); // with full facts
get(name, options?) / delete(name, options?)
const entity = await m.get('PostgreSQL'); // returns null if not found
const ok = await m.delete('PostgreSQL'); // returns true/false
fixEntityType(name, newType, options?)
await m.fixEntityType('React', 'technology');
stats(options?) / graph(options?)
const stats = await m.stats();
const graph = await m.graph(); // { nodes: [...], edges: [...] }
Cognitive Profile
getProfile(userId?, options?)
Generate a ready-to-use system prompt from memory.
const profile = await m.getProfile('alice', { force: true });
console.log(profile.system_prompt);
console.log(profile.facts_used);
Episodic Memory
episodes(options?)
// Search
const events = await m.episodes({ query: 'deployment', limit: 5 });
// List recent
const recent = await m.episodes({ limit: 20 });
// Time range
const jan = await m.episodes({
after: '2026-01-01',
before: '2026-02-01',
});
Procedural Memory
procedures(options?)
const procs = await m.procedures({ query: 'deploy' });
procedureFeedback(id, options?)
await m.procedureFeedback(procId, { success: true });
await m.procedureFeedback(procId, {
success: false,
context: 'Build OOM at step 3',
failedAtStep: 3,
});
procedureHistory(id) / procedureEvolution(id)
const history = await m.procedureHistory(procId);
const evolution = await m.procedureEvolution(procId);
Timeline
timeline(options?)
const facts = await m.timeline({
after: '2026-01-01',
before: '2026-02-01',
limit: 20,
});
Agents
runAgents(options?)
await m.runAgents({ agent: 'curator' });
await m.runAgents(); // runs all agents
agentHistory(options?) / agentStatus(options?)
const history = await m.agentHistory({ limit: 5 });
const status = await m.agentStatus();
Insights & Reflections
await m.reflect();
const insights = await m.insights();
const refs = await m.reflections({ scope: 'cross' });
Memory Management
await m.dedup(); // merge duplicate entities
await m.dedupAll(); // dedup facts across all entities
await m.dedupEntity('PostgreSQL'); // dedup one entity
await m.merge('React.js', 'React'); // merge entities
await m.mergeUser(); // merge "User" into primary
await m.archiveFact('Entity', 'old fact'); // archive a fact
await m.reindex(); // re-embed all entities
feed(options?)
const feed = await m.feed({ limit: 20 });
Webhooks
await m.createWebhook({
url: 'https://your-app.com/hook',
eventTypes: ['memory_add', 'memory_update'],
secret: 'hmac-secret',
});
const hooks = await m.listWebhooks();
await m.updateWebhook(1, { active: false });
await m.deleteWebhook(1);
Teams
const team = await m.createTeam('Engineering', 'Shared memory');
await m.joinTeam('invite-code');
const teams = await m.listTeams();
const members = await m.teamMembers(teamId);
await m.shareMemory('PostgreSQL', teamId);
await m.unshareMemory('PostgreSQL', teamId);
await m.leaveTeam(teamId);
await m.deleteTeam(teamId); // owner only
Smart Triggers
const triggers = await m.getTriggers('alice', { includeFired: true });
await m.processTriggers();
await m.dismissTrigger(triggerId);
await m.detectTriggers('alice');
API Keys
const keys = await m.listKeys();
const newKey = await m.createKey('production');
await m.renameKey(keyId, 'staging');
await m.revokeKey(keyId);
Billing
const billing = await m.getBilling();
const checkout = await m.createCheckout('pro');
const portal = await m.createPortal();
Jobs
const status = await m.jobStatus('job-abc');
const result = await m.waitForJob('job-abc', {
pollInterval: 1000,
maxWait: 60000,
});
Import Data
// ChatGPT export (requires jszip)
await m.importChatgpt('~/Downloads/chatgpt-export.zip', {
chunkSize: 20,
onProgress: (current, total, title) => console.log(`${current}/${total}: ${title}`),
});
// Obsidian vault
await m.importObsidian('~/Documents/MyVault');
// Text/markdown files
await m.importFiles(['notes.md', 'journal.txt']);
Multi-User Isolation
// Each userId gets its own memory space
await m.add([{ role: 'user', content: 'I prefer dark mode' }], { userId: 'alice' });
await m.add([{ role: 'user', content: 'I prefer light mode' }], { userId: 'bob' });
const alice = await m.searchAll('preferences', { userId: 'alice' });
// Only Alice's memories
Error Handling
const { MengramClient, MengramError, QuotaExceededError } = require('mengram-ai');
try {
await m.add(messages);
} catch (e) {
if (e instanceof QuotaExceededError) {
console.log('Upgrade your plan:', e.message);
} else if (e instanceof MengramError) {
console.log(`API error ${e.statusCode}: ${e.message}`);
}
}
Quota Usage
After any API call, check your current quota usage via the .quota property:
await m.search('test');
console.log(m.quota);
// { add: { used: 5, limit: 30 }, search: { used: 12, limit: 100 } }
// Check before hitting the wall
const { search } = m.quota;
if (search && search.used >= search.limit * 0.8) {
console.warn('Warning: approaching search quota limit');
}
The quota is read from response headers (X-Quota-Add-Used, X-Quota-Add-Limit, X-Quota-Search-Used, X-Quota-Search-Limit) and reflects usage at the time of the last API call.