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

@atrib/daemon

v0.4.3

Published

Local daemon for atrib. Serves the attest/recall verbs plus the legacy alias tools from one stateless-native process over Streamable HTTP or stdio.

Readme

atribd

Local daemon for atrib. Serves the two-verb cognitive surface plus the legacy alias tools from one stateless-native process over Streamable HTTP or stdio.

Per the attest/recall rename (D164), atribd mounts three primitives in process: the attest write home (@atrib/attest), the recall read home (@atrib/recall), and @atrib/summarize. Together they serve the seventeen-tool union: the fifteen legacy tool names plus attest plus recall. A record signed through the daemon is byte-identical to one signed through the standalone per-primitive binary: same handler code paths, same _local.producer sidecar labels, same resolveChainRoot chain selection. The daemon is the recommended local topology; the standalone binaries keep shipping and keep working.

Install

Published as @atrib/daemon; the daemon and its binary are named atribd:

npm install -g @atrib/daemon
atribd --help

Or run without installing:

npx --package @atrib/daemon atribd --help

From the workspace (development):

pnpm --filter @atrib/daemon... build
node services/atribd/dist/index.js --help

Quick start

One daemon per profile (D120 partition axis). Start the HTTP daemon:

atribd --transport streamable-http --port 8796 --json

Point an MCP client at http://127.0.0.1:8796/mcp. Startup-spawn harnesses that can only spawn stdio children use the proxy shim:

atribd --transport stdio-http-proxy --endpoint http://127.0.0.1:8796/mcp

Direct stdio (no shared daemon) also works:

atribd

Health lives at <endpoint>/health and carries the D127-D130 gates: recall contract freshness, per-package tool-surface contracts, non-mutating behavioral probes (write primitives stay skipped), plus request counters. There is no sessions block; the daemon has no sessions. The report.compatibility block separately counts modern and legacy requests, labels the declared protocol and client when known, and reports whether the legacy adapter has seen a regression after modern traffic.

Compatibility observations persist by profile under ~/.atrib/state/atribd-mcp-compat-<profile>.json. The file contains bounded counts, labels, and timestamps. It never contains request bodies, arguments, context IDs, network addresses, or user-agent strings. Set ATRIBD_MCP_COMPAT_STATE_FILE to choose another local path. Set it to an empty string to disable persistence. ATRIBD_MCP_EXPECT_MODERN=1 makes the updater reject legacy traffic observed after modern traffic. The same regression emits the structured mcp_legacy_after_modern error event and degrades the health response. Check one or more profiles without restarting them:

pnpm monitor:mcp-compatibility -- \
  --endpoint http://127.0.0.1:8792/mcp/health \
  --endpoint http://127.0.0.1:8795/mcp/health \
  --endpoint http://127.0.0.1:8796/mcp/health

The command exits nonzero for a regression, an unavailable endpoint, or an invalid health response. The default removal gate requires 30 days with no legacy request followed by an explicit deprecation announcement. ATRIBD_MCP_LEGACY_ZERO_WINDOW_MS changes that local evidence window; it does not remove the announcement requirement.

Stateless transport

Every HTTP request is self-describing and any request can land on any instance:

  • No initialize handshake is required. A legacy initialize POST gets a valid response with no session id issued; a legacy Mcp-Session-Id header is ignored, never a 404.
  • Mcp-Method / Mcp-Name routing headers (SEP-2243) are validated against the body when present; a mismatch is HTTP 400 with nothing routed.
  • Inbound context carriers travel in per-request _meta (SEP-414) and resolve through the spec §1.5.4 ladder with the §1.5.3 X-Atrib-Chain fallback.
  • tools/list responses carry ttlMs and cacheScope (SEP-2549) so clients can cache the tool catalogue. The default ttlMs is 5 minutes during the alias window (operator-tunable via --tools-list-ttl-ms / ATRIBD_TOOLS_LIST_TTL_MS).

The transport binding sits behind src/transport-adapter.ts. HTTP requests for the 2026-07-28 protocol use the stable v2 MCP TypeScript SDK and its native per-request handler. The endpoint also routes 2025-era HTTP traffic to the existing v1 stateless adapter, which keeps deployed clients on their JSON response behavior during the compatibility window. Direct stdio and the stdio-to-HTTP proxy use the v2 era negotiator. Both accept 2025-era clients and clients pinned to 2026-07-28.

Context identity on HTTP

Write primitives require an explicit context per request:

  1. An explicit 32-hex context_id tool argument wins.
  2. Otherwise the daemon resolves the inbound _meta carriers; a resolved trace context injects context_id, and a resolved propagation token seeds chain_root on tools that accept it.
  3. Otherwise the write returns a typed tool error: atrib: context_id required on stateless transport.

Read primitives that support unscoped queries proceed per their own scope rules. A single-tenant daemon can opt back into ambient env and profile-file discovery (D078/D083) with --ambient-context or ATRIBD_AMBIENT_CONTEXT=1; the flag name is a D148 open question. The stdio surfaces keep the ambient ladder unchanged.

Write serialization

The daemon serializes calls to any write-union tool name (attest, emit, atrib-annotate, atrib-revise) per resolved context_id: read-tail, sign, append runs one writer at a time per context, so concurrent writes routed through one daemon, regardless of which tool name the caller used, yield a linear chain. Writers that append to the mirror corpus without routing through the daemon sit outside this boundary and can still fork a chain; the spec/conformance/atribd/cases/concurrent-writer-serialization/ family pins both sides of that line.

Duplicate-safe writes

A write caller can set params._meta["dev.atrib/idempotencyKey"] to a stable 16 to 128 character visible-ASCII key. atribd binds the key to the request's context, tool, and complete arguments. The first call reserves the binding before dispatch and stores the complete result before returning it. A retry with the same binding returns that result without signing again. The same key with changed arguments fails before dispatch.

The default store is ~/.atrib/state/atribd-idempotency-<profile>.json. It hashes caller keys and keeps completed results for seven days. ATRIBD_IDEMPOTENCY_STATE_FILE selects another path or disables persistence when set to an empty string. Unresolved pending entries never expire automatically. After a crash, such a key returns an indeterminate-outcome error until the operator reconciles it.

Caller-facing timeouts do not release the per-context write lock. The lock stays held until the underlying primitive settles. If the late call succeeds, atribd stores its result before the next write in that context begins.

Request security and cancellation

HTTP authorization belongs to each request, not to the connection. Embedders can pass bearerAuth to bindAtribdHttpHost(). atribd then runs the MCP SDK's token verifier on every POST before dispatch. The verifier owns token validity, expiry, required scopes, and revocation checks.

The optional rateLimit hook also runs per POST. It receives the method, tool, protocol era, action class, and verified principal fields. It does not receive the bearer token. Neither a reused socket nor io.modelcontextprotocol/clientInfo grants authority.

Cancellation follows the request signal supplied by the MCP SDK. Reads pass that signal to the mounted primitive, so a disconnected or timed-out request can stop its work. Writes use a stricter rule once dispatch starts. The caller gets a cancellation or timeout error, but the write keeps settling under its per-context lock. A late success completes the idempotency entry. Health diagnostics report cancellation and timeout counts separately, including settlements that arrive after either event.

atribd does not use MCP requestState. A future multi-round tool must verify and integrity-protect that caller-carried value before it can affect authorization or routing. See D186.

Process replacement

HTTP clients do not repair or recreate a session after atribd restarts. They retry reads as new requests. A write retry uses the same action-bound idempotency key and complete arguments. Completed writes replay their original result. A pending entry stays indeterminate instead of dispatching a second write.

The daemon test suite hard-kills a real atribd process on a fixed endpoint, starts a fresh process, and proves discovery, reads, negotiated receipts, and completed-write replay. The retry produces one mirror record. The same suite exercises 32 contexts concurrently, queues competing writes within one context, and proves another context can progress while that queue is busy. A failure matrix stops and kills the daemon with discovery, tool listing, reads, and a negotiated-receipt write pending at the client. Every request recovers by retrying its complete request. The write uses the same idempotency key and produces one mirror record.

The same real-process suite pins broad local-host budgets that catch request path regressions without treating CI jitter as product latency: first server/discover under 2 seconds; p95 cached tools/list and compatibility routing under 500 milliseconds; p95 reads under 1.5 seconds; and p95 signed writes with receipt generation under 2 seconds. These budgets cover daemon work after startup and exclude public-log delivery, which runs through the degradation queue.

tools/list remains cacheScope: "private". During the alias window its default ttlMs is five minutes and operators can lower it. A client may use a cached catalogue until that advertised TTL expires, then must refresh before it assumes a removed or renamed tool still exists.

Degradation

The §5.8 contract is absolute. Log submission, mirror writes, and health probing fail silently with atrib:-prefixed logging and never block a primary tool call. With the log endpoint unreachable, a write still returns a signed record_hash and the record lands in the local mirror. Probe and call timeouts degrade the health report; they never kill the process. The daemon binds 127.0.0.1 by default and is never a public service; the key and mirror stay on the host.

Migration from @atrib/primitives-runtime

  • LaunchAgents. Migrate through the D128 updater: node scripts/update-primitives-runtime.mjs --runtime atribd. It discovers com.nader.atribd.* LaunchAgents running this package's dist/index.js, builds the dependency closure, restarts, probes health and the direct MCP surface, and gates on the daemon health shape. All operator profiles now run @atrib/daemon; the topology gate validates the daemon shape.
  • Deprecated session flags. --session-idle-ms and ATRIB_PRIMITIVES_SESSION_IDLE_MS are accepted and ignored with a one-line stderr notice, never a fatal error. The stateless daemon has no sessions to expire.
  • Environment. ATRIBD_* variables take precedence; the legacy ATRIB_PRIMITIVES_HTTP_HOST / _PORT / _PATH / _TOOL_TIMEOUT_MS values are honored so existing LaunchAgent plists migrate without config churn. ATRIB_REQUIRE_EXPLICIT_CONTEXT_ID is redundant on HTTP (explicit is the default) and keeps its meaning on stdio.
  • Old MCP clients. Session-era clients work through the v1 compatibility adapter on HTTP, or through the stdio shim indefinitely. Modern HTTP clients negotiate server/discover without initialize or Mcp-Session-Id. Remove the HTTP adapter only after every expected-modern profile reports zero regressions, the sustained-zero window completes, and the removal has been announced.
  • Rollback. Re-point the harness MCP config at the per-primitive binaries or at atrib-primitives. Rollback is a config change, not a data migration; no signed byte differs between the topologies.

Request diagnosis

Diagnose one bounded request, not a connection:

  1. Record the profile, endpoint, timestamp, MCP method, and tool name.
  2. Check Mcp-Protocol-Version, Mcp-Method, and Mcp-Name against the JSON body. For modern traffic the protocol version is 2026-07-28.
  3. Inspect request _meta for protocol version, client info, capabilities, explicit atrib context, trace context, and the write idempotency key. Redact bearer tokens and private tool arguments.
  4. Inspect the response status, JSON-RPC error or result, attribution receipt, and health counters. A receipt proves a signed commitment, not the truth of the underlying claim.
  5. Retry reads as fresh requests. Retry writes only with the same idempotency key and byte-equivalent action. A changed action must use a new key.
  6. After process replacement, probe server/discover, tools/list, and one non-mutating read. Do not attempt session repair.

The outer atrib server can be modern while a configured wrapper still talks to an older upstream MCP server. Diagnose the outer and upstream legs separately. The outer receipt proves what the atrib layer signed. It does not upgrade the upstream server's transport or make an upstream claim true.

Verify locally

pnpm --filter @atrib/daemon... build
pnpm --filter @atrib/daemon test

The test suite includes the reference tests for spec/conformance/atribd/, which pin the stateless transport contract, routing-header rejection, the context ladder, record byte parity across surfaces, health gates, degradation posture, and write serialization. It also pins a real stable-v2-client negotiation and tools/list call against the daemon.