npm.io
0.1.4 • Published 51m agoCLI

@latten/installer

Licence
Apache-2.0
Version
0.1.4
Deps
3
Size
103 kB
Vulns
0
Weekly
321

@latten/installer

The Latten Installer is the deterministic senses a coding agent uses to see where a TypeScript app reaches into LLMs, data, and other services, wire those crossings into Latten, and read back what it found — read-only, with every change landing as a reviewable PR a human approves. Shipped as an MCP server (latten-mcp) and a companion skill (latten-instrument). The agent supplies the judgment, the diff, and the PR; this package supplies the tools it calls.

If you only downloaded the package, nothing has reached Latten yet. The valuable step is connecting it as an MCP server and letting your agent call provision, guide, scan, verify, and receipt. Provisioning creates an observe-only brain without a login; the first receipt is free. Claim the brain when you want history, recommendations, agent-applied fix PRs, verification, and team context to continue in the paid product.

Setup in your agent

The server speaks stdio MCP; every client below gets the same experience — connect, call provision if no token exists, call guide, follow it. LATTEN_URL points at the Console. LATTEN_TOKEN is optional up front: if you omit it, the agent calls provision once to mint an observe-only brain and a claim URL.

Codex (CLI and desktop)~/.codex/config.toml:

[mcp_servers.latten]
command = "npx"
args = ["-y", "@latten/installer"]
env = { LATTEN_URL = "https://latten.io" }

Then ask Codex:

Use the Latten MCP. If there is no LATTEN_TOKEN, call provision once. Then read guide, scan this repo, instrument high-confidence TypeScript crossings with @latten/sdk, open a reviewable PR, verify real crossings, and return the receipt plus claim_url.

Claude Code

claude mcp add latten \
  -e LATTEN_URL=https://latten.io \
  -- npx -y @latten/installer

(Claude Code users also get the latten-instrument skill; other clients get the identical choreography from the guide tool.)

Claude Desktopclaude_desktop_config.json:

{
  "mcpServers": {
    "latten": {
      "command": "npx",
      "args": ["-y", "@latten/installer"],
      "env": { "LATTEN_URL": "https://latten.io" }
    }
  }
}

Gemini CLI~/.gemini/settings.json:

{
  "mcpServers": {
    "latten": {
      "command": "npx",
      "args": ["-y", "@latten/installer"],
      "env": { "LATTEN_URL": "https://latten.io" }
    }
  }
}

If you already created a connection in Latten Console, include LATTEN_TOKEN=ltnpx_... and provision is skipped. Otherwise the agent returns the new token, claim_url, value path, and receipt after verification.

Then ask your agent: "instrument this app with Latten" — it provisions if needed, reads guide, scans, places the SDK calls, opens the PR, verifies real crossings, and returns the receipt.

The seven tools

The MCP server (buildServer(), exposed by the latten-mcp bin over stdio) registers:

  • guide({}) — the placement playbook, served by the server itself so every MCP client (Gemini, Claude Desktop, Codex, Claude Code) follows the same contract: where SDK calls go (every LLM call, data touch, external API, agent handoff, plus the actor seed), naming, the reviewable-PR rule, and the verify/fix loop. The server's MCP instructions tell agents to read it first.
  • provision({ name?, endpoint? }) — the bootstrap. Mint an observe-only brain and proxy token with no human login. Call once when there is no LATTEN_TOKEN; it returns the token, console_url, a claim_url for the human, and a short value path the agent can repeat in its handoff.
  • scan({ repoPath }) — static analysis only. scanRepo(repoPath) walks a repo's .ts source with ts-morph and returns candidate crossings — DB queries, fetch/HTTP calls, and LLM-SDK calls — each with a kind, a suggestedTarget, a suggestedAction, and a confidence. Detection is library-signature based (it matches imported modules against a catalog, then call patterns), so it needs only source — no node_modules. Candidates are proposals; the skill judges which to instrument and refines targets. scan never implies coverage beyond its catalog.
  • verify({ since? }) — the reveal. Asks the console which crossings have actually arrived for this app since a timestamp, returning a digest (count, sources, targets, findings, firstSeenAt) that drives the "waiting… ✓ received" moment and the first shocking finding.
  • receipt({ since? }) — the trust artifact. Pulls the human-facing receipt after crossings arrive: reached data domains and models, attribution quality, cost, fixes available, the trial state, the zero-PII-values attestation, and the calm account path for keeping history, recommendations, fix PRs, and verification.
  • recommendations({}) — the fix list. Pulls the console's recommended boundary per open exposure for this app. Returns 402 if the app isn't on a trial/paid plan.
  • fix({ findingId }) — one recommendation by id, so the agent can propose the diff, let the human review, and land it. Latten only serves the recommendation; the agent does the edit and the human approves — the console never executes.

verify, recommendations, and fix reach the console at LATTEN_URL and authenticate with the app's proxy token (LATTEN_TOKEN) — the token is the app's identity. Both are overridable per-call. Wire fields stay snake_case to match the engine and every other Latten client.

Where the token may be sent

The proxy token is a bearer credential, so the endpoint is locked down. The token is only sent over https (an http endpoint is allowed only for localhost during development), and only to an allowlisted host:

  • the host of LATTEN_URL (your configured console), plus
  • any hosts in LATTEN_ALLOWED_HOSTS (comma-separated) — set this to authorize a self-hosted console when you pass the endpoint as a literal argument with no LATTEN_URL in the env;
  • if neither is set, the default Latten SaaS host (latten.io).

Because the MCP tools accept endpoint as a per-call argument, this pin is what stops a prompt-injected agent from redirecting your app token to an unrecognized host: a mismatched endpoint is refused, not sent.

The skill

skill/SKILL.md (latten-instrument) is the choreographer: discover → scan → judge & instrument → prove (typecheck/build) → PR → reveal. scan and verify/recommendations/fix are its deterministic senses; everything else — judgment, the diff, the reviewable PR, the reveal — is the agent. The output is always a reviewable PR: for a security buyer, a reviewable diff is the precondition for trust.

scan limitations (by design — it is a candidate-proposer, not the final word)

  • Over-proposes on shared method names. Rules fire on any .query/.execute/.create call in a file that imports the relevant library — there is no dataflow check that the call is on that client. An unrelated .execute() in a DB-importing file is flagged. The skill refines.
  • Raw-SQL targets only. Target/action are derived from a string-literal first argument (from/into/update <table>, leading SQL verb). Query-builder ORMs (knex, drizzle, typeorm, prisma) that build SQL via chained calls degrade to a generic data_domain:db / read — still flagged as a crossing, just with a target the skill must refine.
  • TypeScript only — the language frontier expands as each SDK language ships.

Keywords