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

@datar-platform/cli

v0.1.1

Published

Datar CLI and MCP server — connect any AI harness (Claude Code, etc.) to a Datar org via an API token. Read + discovery in v1.

Readme

@datar-platform/cli

The datar CLI and MCP server — connect any AI harness (Claude Code, Cursor, etc.) to a Datar organization with a single API token, the way you connect a CLI to a cloud account. The token is bound server-side to one org and a set of scopes, so once you authenticate, the harness already knows which org it's in and what it may do — no org selection, no endpoint guessing.

Built entirely on @datar-platform/sdk. v1 is read + discovery only, available over two transports that share one tool registry: a local stdio server (datar mcp, this package) and a remote Streamable HTTP endpoint (/api/mcp in the web app — no local install needed, just a token).

A layered agent surface

Datar exposes its capabilities as layers — identity, memory, storage, knowledge, runtime — and this CLI/MCP is the tools surface over them:

| Layer | Datar surface | Tools | | ------------- | ------------------------------------- | ---------------------------------------------- | | Identity | dt_ token → org + scopes | datar_whoami (reports which layers are live) | | Memory | stored agent sessions + turns | datar_list_sessions, datar_get_session | | Knowledge | knowledge base (per-tenant, optional) | datar_kb_search, datar_kb_list_documents | | Storage | Drive | drive_* | | Runtime | agents (A2A) | datar_ask (opt-in), datar_describe_service |

Each layer is independently gated — a harness only ever sees what's actually provisioned for the org. The Knowledge layer especially is optional: on a tenant with no knowledge base, its tools return { available: false, reason } instead of erroring, and can be omitted entirely with DATAR_MCP_ENABLE_KB=0 (see below).

Install & authenticate

pnpm add -g @datar-platform/cli    # or run via npx

export DATAR_API_TOKEN=dt_...       # mint at <baseUrl>/settings/api-tokens
export DATAR_BASE_URL=https://acme.datar.co.za   # or http://localhost:3000 for dev

How read-only is actually enforced

The read-only guarantee is client-side, not scope-based:

  • Every discovery/read tool and datar_query issue HTTP GET only, and tRPC refuses mutations over GET — so they physically cannot write, whatever the token's scopes are.
  • datar_ask is the only tool that can act (it drives an A2A agent, which may call mutating endpoints). It is opt-in — registered only when DATAR_MCP_ALLOW_AGENT=1. Default off ⇒ the whole surface is provably read-only.

⚠️ Do not rely on token scopes alone for read-only. Token scope enforcement runs platform-wide today, but treat it as defense-in-depth on top of the client-side guarantee above (GET-only tools, datar_ask off by default) — not a replacement for it.

Use as a CLI

datar whoami                         # the org/user this token resolves to
datar ls                             # list Datar service agents
datar ask "how many open tenders do we have?"      # orchestrator routes it
datar ask procurement "list my draft submissions"  # target one agent
datar query v2.people.org.getActiveMembers          # any read procedure by path
datar projects ls                    # quick record listings
datar memory ls                      # stored agent sessions (short-term memory)
datar memory show <sessionId>        # a session's prior turns
datar kb search "leave policy"       # semantic search over the knowledge base
datar kb ls                          # indexed/recallable documents

Use as an MCP server (Claude Code)

claude mcp add datar \
  --env DATAR_API_TOKEN=dt_... \
  --env DATAR_BASE_URL=https://acme.datar.co.za \
  -- npx -y @datar-platform/cli mcp

Then ask Claude things like "list Datar services", "show my projects", or "what PayFast-backed transactions came in this month?" — it will call the tools below.

Use remotely — no local install (Streamable HTTP)

Any MCP-capable harness can connect straight to a Datar tenant with nothing but a token — the platform exposes the same tool registry over the MCP Streamable HTTP transport (stateless — a fresh McpServer per request, as the SDK recommends for serverless):

claude mcp add datar-remote --transport http \
  https://acme.datar.co.za/api/mcp \
  --header "Authorization: Bearer dt_..."

Auth is the same bearer-token model as everywhere else in the platform (dt_ API token / sk_ access key), validated with the same check the A2A gateway uses (resolveA2AAuth) — a missing/invalid token gets a 401 before any MCP handling happens. Every tool call then re-enters the app's own tRPC endpoints under the caller's real identity, exactly like the local CLI does (the SDK client is just pointed at the request's own origin instead of an env var). Same DATAR_MCP_ALLOW_AGENT=1 gate controls whether datar_ask is registered on the remote endpoint too.

Tools exposed (30 read-only by default; +datar_ask = 31 with DATAR_MCP_ALLOW_AGENT=1)

  • Discoverydatar_whoami (identity + which harness layers are live for this org), datar_list_services, datar_describe_service (skills + input/output JSON schemas from each agent card — the catalog that makes downstream calls precise).
  • Memory (short-term) — datar_list_sessions, datar_get_session (the caller's stored agent sessions and their prior turns — the same history the agent replays).
  • Knowledge (long-term recall, capability-gated) — datar_kb_search (raw semantic retrieval), datar_kb_list_documents (what's indexed). Return { available: false } when the org has no KB; omit entirely with DATAR_MCP_ENABLE_KB=0.
  • Typed reads (deterministic, no nested-LLM cost) — drive_list_files, drive_get_file, drive_list_folders, projects_list, projects_get, projects_metrics, tasks_list, people_list, requests_list, requests_pending_approvals, transact_list_accounts, transact_list_transactions, procurement_list_tenders, procurement_list_public_tenders, procurement_list_suppliers, inventory_list_items, inventory_low_stock, isms_list_risks, isms_list_controls, invoicing_list_invoices, invoicing_list_clients, messages_list.
  • Natural-language fallbackdatar_ask (forwards to any agent / the orchestrator; reuses tool-calling, KB grounding, cross-service routing). Opt-in / can act: only registered when DATAR_MCP_ALLOW_AGENT=1; omitted by default so the surface stays read-only.
  • Read escape hatchdatar_query (any v2.* tRPC query by path; mutation-looking paths are refused, and client.query() only issues GETs, which tRPC never serves for mutations).

Verify locally

pnpm -F @datar-platform/cli build && pnpm -F @datar-platform/cli test
# Drive it interactively with the MCP inspector:
npx @modelcontextprotocol/inspector node packages/cli/dist/index.js mcp

Architecture notes

  • The tool registry (exported as @datar-platform/cli/mcp/tools) is transport-agnostic — a ToolDef[] with no MCP/stdio/HTTP types. A shared createDatarMcpServer(client, tools) (exported as @datar-platform/cli/mcp) builds an McpServer from it and is reused verbatim by both transports:
    • startStdioServer() (this package's datar mcp command).
    • The platform's remote endpoint, stateless (fresh server + transport per request; the SDK's own guidance for serverless — reusing one across requests causes message-ID collisions between clients).
  • Everything routes through one Datar SDK client. No direct database access; the CLI (and the remote endpoint) are pure API consumers.

More write capabilities, richer onboarding, and additional integrations are on the roadmap.