TypeScript SDK · pre-release
Build around current state.
Use ConceptmemClient to propose changes and read accepted records from your application. The examples below describe the public SDK contract.
Prepare your application
Use TypeScript in a server environment with fetch support, such as Node.js 20 or later. After public release, install the SDK and types:
npm install @conceptmem/sdk @conceptmem/types
npm install --save-dev tsx typescriptFrom your database’s Connections page, copy the hosted base URL and workspace key. Set CONCEPTMEM_URL and CONCEPTMEM_API_KEY in your server environment. The base URL is the service origin, without an API route suffix.
A complete write, read, and history cycle
Use a fresh database for this example. Save the code as memory.ts and, once the packages are available, run npx tsx memory.ts. Existing schema and policy can change the outcome.
import { ConceptmemClient } from '@conceptmem/sdk';
import type { Observation } from '@conceptmem/types';
const baseUrl = process.env.CONCEPTMEM_URL;
const apiKey = process.env.CONCEPTMEM_API_KEY;
if (!baseUrl || !apiKey) throw new Error('Set your hosted URL and workspace key.');
const memory = new ConceptmemClient({ baseUrl, apiKey, timeoutMs: 30_000 });
const entityRef = 'customer:crm_1042';
async function main() {
// Use a fresh database with its default policy for this example.
for (const channel of ['phone', 'email']) {
const observation: Observation = {
entityType: 'customer',
entityRef,
data: { contact_channel: channel },
provenance: {
source: 'support',
actor: 'support-agent',
confidence: 0.97,
extractionMethod: 'structured_import',
},
};
// The hosted service records the authenticated principal as the actor.
const result = await memory.add(observation);
console.log('Applied:', result.operations);
console.log('Skipped:', result.skipped);
console.log('Violations:', result.violations);
console.log('Pending review:', result.pendingReview);
if (result.skipped.length || result.pendingReview.length ||
result.violations.some((violation) => violation.blocking)) {
throw new Error('Inspect the write result before continuing.');
}
}
const current = await memory.get(entityRef);
const history = await memory.getFactHistory(current.entity.id);
const changes = await memory.getChangelog(current.entity.id);
console.log('Current:', current.facts.map(({ predicate, value }) => ({ predicate, value })));
console.log('History:', history.map(({ value, status }) => ({ value, status })));
console.log('Sources:', changes.map(({ provenance }) => provenance));
}
main().catch((error) => { console.error(error); process.exitCode = 1; });Expected result
Current: [{ predicate: "contact_channel", value: "email" }]
History: phone (superseded), email (current)
Sources: source "support", actor assigned from authenticated accessHistory order is not assumed in this summary. The actual results include identifiers and timestamps. The service records the authenticated principal as the actor, overriding the actor supplied in the observation. Read every write result, including warnings and pending reviews, before relying on the proposed value.
Client configuration
| Option | Contract |
|---|---|
baseUrl | Required hosted service origin. Use the value provided by Connections. |
apiKey | Workspace access key. Keep it in a trusted server environment. |
timeoutMs | Optional positive integer timeout covering the request and response body. Omitted means no timeout. |
headers | Optional additional request headers. Do not override authorization unintentionally. |
fetch | Optional compatible fetch implementation for your application’s transport requirements. |
Common methods
| Method | Result and use |
|---|---|
add(observation) | Returns ConsolidationResult. Inspect operations, skipped, violations and pendingReview. |
validateObservation(observation) | Returns ObservationCheck without writing. Validation does not reserve state or predict every policy decision. |
addMany(observations) | Returns a result or error per observation. A failed item does not undo successful items. |
get(reference) | Returns EntityView: entity, current facts and relations. Accepts an entity ID or canonical reference. |
getMany(references, options?) | Reads up to 20 references and reports missing entities per item. |
search(query, options?) | Returns ranked text-search results. Scores are ranking signals, not confidence. |
getFactHistory(entityId) | Returns facts across their lifecycle states, including earlier values. |
getChangelog(entityId, options?) | Returns change events with recorded provenance. |
getEntityAt(entityId, asOf) | Reads an entity at a Date. Facts use valid time; entity metadata is not a historical snapshot. |
vocabulary(options?) | Reads declared and in-use vocabulary for your integration to reuse. |
listClasses() / getClass(name) | Reads schema definitions and their public constraints. |
review.listPending() / review.decide(id, decision) | Lists pending proposals or submits an authorized review decision. |
exportState() / exportMarkdown() | Returns a derived export; this is not a full restorable backup. |
Handle failures deliberately
import { ConceptmemHttpError } from '@conceptmem/sdk';
try {
const customer = await memory.get('customer:crm_1042');
console.log(customer.facts);
} catch (error) {
if (error instanceof ConceptmemHttpError) {
console.error('Request failed:', error.status);
const retryAfter = error.headers.get('retry-after');
if (retryAfter) console.error('Retry guidance:', retryAfter);
// Inspect error.body in a trusted diagnostic environment.
// It may contain details from the request.
} else {
throw error;
}
}Authorization failures require checking the workspace key and its access. Invalid input requires correcting the observation. Rate or account limits require following the returned limit information. A successful HTTP response still requires inspecting skipped writes, violations and pending reviews.
The SDK does not automatically retry mutations. After an uncertain write outcome, inspect the record and history before deciding what to send next. Do not assume the MCP operation-recovery contract applies to SDK methods.
Use the right authority
Workspace keys carry agent authority. Schema changes depend on the database’s configured mode and permissions; use authenticated console access for human schema administration. SDK method availability does not grant permission.