npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@synapsor/client

v0.1.6

Published

Node.js SDK for Synapsor, the agent-native database for auditable AI applications

Downloads

659

Readme

Synapsor Node.js SDK

The Synapsor Node.js SDK connects applications to hosted or local Synapsor databases. Use it for SQL, branch workflows, agent contexts, capabilities, evidence, memory, and safe write proposals from Node.js applications.

Local Usage

import { Synapsor } from "@synapsor/client";

const db = await Synapsor.connect("app.db", { autoStart: true });
db.setSession({
  tenant_id: "acme",
  principal: "support_agent_17",
  session_id: "agent_run_1",
});

await db.execute("CREATE TABLE messages (id INT, body VARCHAR);");
await db.execute("INSERT INTO messages VALUES (1, 'hello');");
const rows = await db.query("SELECT * FROM messages;");

const proposal = await db.proposeMemoryFact({
  scope: ["tenant", "acme"],
  subject: ["preference", "answer_style"],
  claim: "The operator prefers concise answers.",
  source: ["turn", "msg_1"],
  trust: "verified",
  approval: "approved",
  reason: "stable preference extracted from chat",
});
await db.approveMemoryProposal(proposal.proposal.proposal_id, "operator approved");

await db.close();

Hosted Usage

Install from npm:

npm install @synapsor/client
import { Synapsor } from "@synapsor/client";

const db = await Synapsor.connect("https://synapsor.ai", {
  apiKey: process.env.SYNAPSOR_API_KEY,
});

db.setSession({
  tenant_id: "acme",
  principal: "app_user_1",
  session_id: "first_hosted_run",
});

console.log(await db.query("SELECT 1;"));
const ctx = await db.invokeAgentCapability("chat.prepare_llm_context", { question: "..." });

Use database-scoped API keys from the Synapsor control panel for hosted projects.

Agent Workflows

Use agentRuns when an agent framework owns routing, but Synapsor should own the durable workflow contract: session scope, capability calls, evidence, proposal branches, outbox actions, settlement, and replay.

const run = await db.agentRuns.start({
  workflow: "billing.late_fee_waiver_flow",
  version: "2026-05-27",
  input: { user_request: "Can we waive this late fee?" },
});

const answer = await run.invokeCapability("support.answer_ticket_question", {
  stepKey: "answer_ticket_question",
  arguments: { question: "Can we waive this late fee?" },
  responseEnvelope: true,
});

const proposal = await run.invokeCapability("billing.propose_late_fee_waiver", {
  stepKey: "propose_waiver",
  arguments: { amount_cents: 2500 },
  mode: "propose_only",
  autoBranch: true,
  responseEnvelope: true,
});

const action = await run.proposeExternalAction("stripe.issue_refund", {
  stepKey: "refund_customer",
  arguments: { charge_id: "ch_123", amount_cents: 2500 },
  idempotencyKey: "refund:TCK_1001:2500",
});

await run.checkpoint("before_worker_claim", {
  payload: { reason: "external action queued" },
});
await run.complete({ decision: "waiver_proposed" }, { status: "waiting_approval" });
const graph = await run.explain();

Find the persisted run/evidence/proposal later by business object, workflow, tenant, query fingerprint, or time window:

const activity = await db.agentActivity.search({
  tenantId: "acme",
  businessObjectId: "T-1042",
  workflow: "support.ticket_refund_flow",
  timeRange: { from: 123, to: 456 },
  limit: 50,
});

This helper sends the native lookup form:

SELECT *
FROM AGENT ACTIVITY
WHERE tenant_id = 'acme'
  AND business_object_id = 'T-1042'
ORDER BY created_at DESC
LIMIT 50;

Replay a stored capability run by using the numeric agent_run_id returned by Synapsor. Deterministic replay returns the captured persisted run; comparison modes can inspect the original snapshot, current state, a commit version, a timestamp, or a review branch.

const replay = await db.replayAgentRun(123, {
  mode: "original_snapshot",
});

const branchReplay = await db.replayAgentRun(123, {
  mode: "branch",
  branchName: "review_run_123",
});

Workers should claim and confirm side effects through the outbox namespace:

const task = await db.externalActions.claim({
  queue: "billing_external_actions",
  workerId: "billing-worker-1",
});
await db.externalActions.confirm(task.action_instance_id, {
  status: "succeeded",
  providerRequestId: "re_456",
  response: { status: "succeeded" },
});

External DB Writeback Worker

For existing Postgres/MySQL integrations, keep Synapsor in proposal mode. The agent stages an evidence-backed external write proposal, a human or settlement policy approves it, and a trusted worker in your app environment applies the approved change back to your existing database with parameterized SQL.

import { createExternalDbWritebackWorker } from "@synapsor/client/external-db-writeback";

const worker = createExternalDbWritebackWorker({
  synapsorApiKey: process.env.SYNAPSOR_API_KEY,
  sourceName: "app_postgres",
  execute: async ({ sql, params }) => {
    // Use your own Postgres/MySQL client here. The model never provides SQL.
    return appDb.query(sql, params);
  },
});

await worker.pollOnce();

The worker validates Synapsor-provided mapping metadata, only writes allowlisted columns, adds tenant and primary-key guards, checks optional conflict columns, and reports applied, conflict, or failed back to Synapsor idempotently.

CLI MCP Risk Review

The package installs a synapsor CLI. Use synapsor mcp audit <target> for a static MCP database risk review of exported tool manifests, remote tools/list endpoints, or stdio MCP servers.

synapsor mcp audit ./tools-manifest.json
synapsor mcp audit https://mcp.example.com --bearer-env MCP_AUDIT_TOKEN --json
synapsor mcp audit 'stdio:node ./server.mjs' --timeout-ms 5000

The audit flags patterns such as generic execute_sql tools, model-controlled tenant/table/column inputs, model-callable approval or commit tools, missing proposal boundaries, missing structured output schemas, and missing idempotency or conflict-guard metadata. It never calls business tools during the audit.

This is a static MCP database risk review, not proof that an MCP server is secure. MCP annotations are treated as descriptive hints, not enforcement.

API Surface

  • execute(sql) and query(sql)
  • setSession({...})
  • invokeAgentCapability(name, args, options)
  • agentRuns.start(...), run.invokeCapability(...), run.checkpoint(...), run.complete(...), run.explain(...)
  • agentActivity.search({ tenantId, businessObjectId, workflow, timeRange, limit })
  • replayAgentRun(id, { mode, version, timestamp, branchName })
  • externalActions.claim(...) and externalActions.confirm(...)
  • createAgentEval(...) / evals.create(...) for run-history or sourceTable dataset evals
  • evals.run(...).failures()
  • listCapabilities(query)
  • rememberFact({...})
  • proposeMemoryFact({...})
  • approveMemoryProposal(id, reason)
  • rejectMemoryProposal(id, reason)
  • listMemoryProposals({...})
  • recallMemory({...})
  • retireFact(id, {...}) and forgetFact(id, reason)
  • checkFactForAction({...})
  • branch helpers: createBranch, useBranch, diffBranch, mergeBranch, dropBranch
  • write lifecycle helpers: previewWrite, approveWrite, commitWrite, rejectWrite, settleWrite
  • external DB writeback worker: createExternalDbWritebackWorker from @synapsor/client/external-db-writeback
  • readResource(uri)

Errors from Synapsor become SynapsorError with status, code, requestId, retryable, and the raw payload. Include requestId when opening support or incident tickets so server, gateway, and runtime logs can be joined without exposing secrets.