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.

Publication pending. The SDK and public types are being validated before their first public npm release. Installation commands below are for that release and are not available yet. For an available integration, follow the hosted MCP guide.

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:

Install after public release
npm install @conceptmem/sdk @conceptmem/types
npm install --save-dev tsx typescript

From 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.

memory.ts
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

Relevant output — fields abbreviated
Current: [{ predicate: "contact_channel", value: "email" }]
History: phone (superseded), email (current)
Sources: source "support", actor assigned from authenticated access

History 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

ConceptmemClient configuration
OptionContract
baseUrlRequired hosted service origin. Use the value provided by Connections.
apiKeyWorkspace access key. Keep it in a trusted server environment.
timeoutMsOptional positive integer timeout covering the request and response body. Omitted means no timeout.
headersOptional additional request headers. Do not override authorization unintentionally.
fetchOptional compatible fetch implementation for your application’s transport requirements.

Common methods

SDK method reference
MethodResult 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

HTTP error handling
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.