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

@kya-os/checkpoint-mcp

v0.1.0

Published

Wire a self-hosted KYA-OS MCP server into Checkpoint: register it as a server, publish its tool catalog, and report every tool dispatch attributed to it.

Readme

@kya-os/checkpoint-mcp

Wire a self-hosted KYA-OS MCP server into Checkpoint.

Register the server, publish its tool catalog, and report every tool dispatch attributed to it, so its calls, delegations and proofs show up under that server rather than only under the project.

This is the adopter path for a service that runs @kya-os/id and @kya-os/mcp on its own infrastructure. Hobbsidian is the reference implementation.

Install

npm install @kya-os/checkpoint-mcp

Use

import { createCheckpointReporter } from '@kya-os/checkpoint-mcp';

const checkpoint = createCheckpointReporter({
  apiKey: process.env.CHECKPOINT_API_KEY!,
  serverDid: 'did:web:example.com',
  serverUrl: 'https://example.com/api/mcp',
  displayName: 'Example',
  sdk: { name: 'example-mcp', version: '1.0.0' },
});

// Once on boot. Idempotent, and doubles as the liveness heartbeat.
await checkpoint.registerServer({
  tools: [{ name: 'vault_read', description: 'Read a file', capability: 'vault:read' }],
});

// Per tool dispatch. Never throws.
await checkpoint.reportToolCall({
  toolName: 'vault_read',
  capability: 'vault:read',
  action: 'permit',
  reason: 'capability-granted',
  agentDid: verifiedAgentDid,
  principalDid: delegatingUserDid,
  stages: [{ name: 'delegation_verify', verdict: 'pass', latencyMicros: 1500 }],
  context: { userAgent, ipAddress, path: '/api/mcp', method: 'POST' },
});

Your server DID

serverDid is not a new identifier. It is the DID you already pin as the audience on the delegations you mint, so a credential minted for your server cannot be replayed against another one.

Registration claims that DID, and every report carries it. If the two ever diverge, attribution silently falls back to project scope rather than failing loudly, so keep them derived from one value.

The tool catalog

tools is optional, and omitting it is meaningful.

Omitted means leave the stored catalog unchanged. Passing [] means this server advertises nothing. A boot heartbeat that does not resend its catalog must not retire everything, which is why the distinction exists.

Publishing is accretive. A tool you stop listing is marked stale, never deleted, because the catalog drives per-tool authorization on the Checkpoint side and deleting an entry would drop whatever protection an operator configured against it. Republishing never overwrites authorization, requiredScopes or requiresDelegation.

Derive the catalog from whatever already defines your MCP surface rather than hand-maintaining a copy, so the two cannot drift:

await checkpoint.registerServer({
  tools: tools.map((t) => ({
    name: t.name,
    description: t.description,
    capability: t.capability,
  })),
});

Durability

reportToolCall persists to an outbox before attempting delivery, then marks the outcome. A delivery that fails stays queued; flush() sweeps it.

The default MemoryOutbox is process-local and is lost on restart. It exists so the package works with no configuration and so tests need no database. For production, implement OutboxPort against a real store and keep ownership of retention and your local audit trail:

import type { OutboxPort } from '@kya-os/checkpoint-mcp';

const outbox: OutboxPort = {
  async enqueue({ body, toolName }) {
    const [row] = await db.insert(reports).values({ body, toolName }).returning();
    return { id: row.id };
  },
  async markDelivered(id) {
    await db.update(reports).set({ deliveredAt: new Date() }).where(eq(reports.id, id));
  },
  async markFailed(id, error) {
    await db
      .update(reports)
      .set({ attempts: sql`attempts + 1`, lastError: error })
      .where(eq(reports.id, id));
  },
  async listRetryable(limit) {
    return db.select().from(reports).where(isNull(reports.deliveredAt)).limit(limit);
  },
};

Then sweep on a cron:

export async function GET() {
  const { delivered, failed } = await checkpoint.flush(25);
  return Response.json({ delivered, failed });
}

Delivery guarantees

Delivery is at-least-once. A report that POSTs successfully but whose markDelivered then fails stays retryable, so a later sweep re-sends it — losing the report is the worse outcome, and Checkpoint's detections writer tolerates duplicates by design.

The reporter skips rows it is itself mid-delivery on, so a flush overlapping a live report in the same process cannot double-send. Across processes it can: two instances sweeping one shared store both see the same undelivered row. If that matters for your deployment, make listRetryable claim what it returns — a locked_until column, SELECT … FOR UPDATE SKIP LOCKED, or a queue with visibility timeouts.

Your OutboxPort should avoid throwing. Every call is guarded, so a throw cannot reach your tool handler, but it does degrade behaviour: a failed mark leaves a row to be re-sent.

Failure posture

Nothing in this package throws into your tool handler. Registration returns { registered: false, reason }, reporting returns { delivered: false, error }, and an outbox that fails degrades to direct delivery.

A server that cannot reach Checkpoint must still serve MCP.

Why this is not in @kya-os/mcp

@kya-os/mcp is the DIF TAAWG protocol reference implementation. A Checkpoint API key and a vendor endpoint do not belong in a standards-track package, so the protocol stays neutral and the vendor binding lives here.

See also

  • Self-hosted MCP servers — the endpoint contract this package speaks, including the choice between the log-detection and tool.invoked ingest lanes.