reference
Every tool and endpoint an agent can call.
MCP over Streamable HTTP, REST, and posted source — with the price of each call and the click that stands before every charge. The same text, for your agent to fetch: nittim.com/agents.md.
Connecting
The endpoint is https://nittim.com/api/mcp. Streamable HTTP is the MCP transport for servers that live at a URL: your assistant talks to nittim.com over ordinary HTTPS, and nothing runs on your machine. One command connects Claude Code:
claude mcp add --transport http nittim https://nittim.com/api/mcp
That writes one entry to your Claude Code config (~/.claude.json, not your repo). Undo it with claude mcp remove nittim. Any other MCP client takes the same URL as a config block:
{
"nittim": {
"url": "https://nittim.com/api/mcp"
}
}Connected this way, your assistant can already call scan_source (committed secrets and known CVEs — no charge) and list_modules — no account, no key. Nothing is sent to nittim until your assistant calls a tool, and Claude Code asks you before each call. The score and the verdict need a key.
With a key
Every request that runs a paid tool authenticates with a nittim_sk_… key, sent as Authorization: Bearer nittim_sk_… — mint one on the API keys page; the plaintext is shown once, at creation. Keep the key out of your repo: add it at user scope (pass -s user when you add the server, or edit ~/.claude.json), never in a project .mcp.json that gets committed. A key you revoke stops working immediately. Clients that connect to remote MCP servers natively — Claude Code, claude.ai connectors, newer Claude Desktop builds — use this JSON shape:
{
"nittim": {
"url": "https://nittim.com/api/mcp",
"headers": {
"Authorization": "Bearer nittim_sk_…",
"x-nittim-anthropic-key": "sk-ant-…"
}
}
}x-nittim-anthropic-key is optional — BYOK Pro subscribers only. Your key is forwarded per request and never stored. Drop it entirely to run on credits as usual. audit_repo doesn't take it: its report is finalized after the call ends, so it always runs on nittim's own model key and is charged in credits. Leave the header in for audit_source and run_module.
Older, stdio-only clients can't dial a remote URL at all — they only speak to a local process over standard input and output. For those, mcp-remote is a small bridge process that runs on your machine and forwards stdio to the exact same https://nittim.com/api/mcp endpoint above:
{
"nittim": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://nittim.com/api/mcp",
"--header",
"Authorization: Bearer nittim_sk_…"
]
}
}Or sign in — no key to paste
Rather than minting a key and putting it in a config file, you can connect and sign in to nittim the way you would to any website. Point your client at this URL instead and it will send you to nittim.com to approve the connection once:
claude mcp add --transport http nittim 'https://nittim.com/api/mcp?auth=oauth'
Any client that speaks OAuth takes the same URL as a config block, with no Authorization header at all — it registers itself and gets its own token:
{
"nittim": {
"url": "https://nittim.com/api/mcp?auth=oauth"
}
}A signed-in connection is the same account a key would have reached: the same tools, the same credits, the same audit history. Keys and sign-in are interchangeable and both keep working — nothing you have configured today changes, and you can use one on one machine and the other somewhere else. A paid tool still quotes its price and waits for your Confirm; signing in is proof of who you are, never a standing permission to spend.
Two kinds of key
A key can be scoped to an organization at creation, in which case requests it authenticates carry that org's context; an unscoped key acts on your personal account. Sharing a config with a whole fleet? Mint a publishable key (nittim_pk_…) instead — safe to embed in a shared assistant config, it can only list modules and call the judge, spends your credits up to a per-key cap you set, and revokes just as instantly.
The nine tools
scan_source — Scan posted files for free, no key
free
Post files straight from your assistant — no GitHub repo, no account — and get back committed secrets and known-vulnerable dependencies as hard evidence. Your assistant sends only the files it picks, and nothing is sent to nittim until it does. nittim reads them in memory and keeps the findings — path, line, a masked excerpt — so the report has a link; it never keeps the files, and never the secret itself. The only deep-look tool a guest with no key can call.
list_modules — See every check, in plain English
free
List every check the audit engine can run, each with a plain-English description of what it looks for. Same copy as the public What we check page. A guest with no key can call this too.
estimate_audit — Price it first — no upload required
free
Ask before you post. Give a GitHub repository URL, or a manifest of just the paths and byte sizes you would post to audit_source (no file content — nothing is uploaded to ask this), and get back the tier this selection would run at (Audit or Full Audit), how many passes, the exact price, your account's current credit balance, and whether this run would be covered by an unspent Audit. Set fullScan to price a Full Audit run instead of the default Audit — and that quote is exactly what audit_repo/audit_source will charge when you pass fullScan: true to them.
A manifest with no content posted yet gets an honest upper-bound pass count, clearly marked as an estimate — computed by the SAME pricing functions audit_repo/audit_source actually charge with, so the number can't legitimately drift from the real quote. A selection too large to sell as Full Audit comes back saying so, with the way to trim it, rather than a bare refusal. Never charges, never runs an audit, never stores anything.
audit_repo — Audit a whole repo and get the verdict
5.14 credits · report usually within 15 minutes*
Audits a GitHub repository — the deterministic scanners plus one structured AI pass, scored, with a verdict. It reads whatever commit is currently on GitHub, so push first or you're auditing stale code. The call hands the agent the audit's id straight away and the report lands usually within 15 minutes* — read it with get_audit, which returns the compact digest: verdict, scores, top findings, plus a shareable report link.
Two tiers: by default it reads the repository's highest-signal source (Audit); pass fullScan: true to buy Full Audit — every eligible source file, priced by pass count, refused up front with the way to trim it if the repo is too large to read in full. It runs on nittim's own model key and is charged in credits — nittim never holds a key to your code: a private repo is read through the GitHub App you install, whose only permissions are read-only. audit_source is the tool that takes your own model key, and runs the identical pipeline on posted files.
audit_source — Audit posted files and get the verdict
5.14 credits usually within 15 minutes* · 200 in the call on BYOK
The posted-source twin of audit_repo — same verdict, same scores, same evidence, same price — for code with nowhere to push: a builder like Abacus or Replit, or files with no GitHub remote at all. Two tiers, same as audit_repo: Audit by default, or fullScan: true for Full Audit over every eligible file you posted. On nittim's own model key it submits and hands back an id like audit_repo, landing usually within 15 minutes*. BYOK Pro is the one exception: on your own key it answers with the report inside the call instead.
get_audit — Fetch an audit you already ran
free
Fetch an audit by its UUID at any stage. A finished one comes back as the same digest audit_repo produces; one that is still running says so and says when to ask again, so an agent never reads a pending audit as a failure and starts a second, paid one. A failed one says why, and — if you own it — what happened to the charge. Costs nothing to call, but still needs a key: reports are gated to the account that ran them. On some Full Audit runs a finding gets a second, independent read — those confirmed both times are listed first in the digest; ones caught once are listed after, still worth a look.
run_module — Run just one check
5.03 credits per call
Run ONE module against a repo. Returns that module's findings only. Scores and a verdict come from audit_repo.
judge_output — Get a second opinion from a different lab
5.03 credits per call
Hand over any work product — code, a plan, a claim — and an independent judge grades it: a version-pinned model from a different lab than the audit model, so an agent never has to grade its own homework. Returns severity-tagged findings and a rationale — never a score, never a verdict.
report_loop — Share what a Nittim Loop run found — counts only
free to call · a small reward, tapering as the corpus grows
After running the Nittim Loop (nittim's free self-review rubric, run on your own model) to a real stopping point, tell nittim ANONYMISED COUNTS of what happened — pass numbers, a findings-by-category tally, a fixed count, whether each pass was clean. Never a title, a file path, a snippet, or any other description of what was found; the schema has no room for one. Ask your developer first, in plain words, and only send it if they say yes — this is data consent, not spend consent, so it never touches a balance either way. The reward is for a real loop that acted — at least two passes, something fixed, and a real stop: converged, flagged systemic, or capped after three or more passes. Reporting the same repo again from this account updates that record with the new numbers instead of being rejected — the reward is a one-time check, decided when this repo was first reported, so a repo whose first report earned nothing isn't re-checked on a later resubmission either; the response's outcome field says which of the two happened ("inserted" or "updated"), so a wrong repo_hash is caught immediately rather than days later on /loop. 5 credits under 20 repos reported, 3 credits under 100 repos reported, 1 credit under 500 repos reported, then nothing once the corpus reaches 500 — nittim's own report_loop answer always states today's exact number. Capped too: three rewarded repos per account, lifetime, and at most one newly-rewarded repo per account per UTC day. Results appear at nittim.com/loop.
* Most reports land within 15 minutes. Worst case, 24 hours.
Paying: the price is quoted, then a person clicks
Call a paid tool the ordinary way and it doesn't run. It answers with the price:
audit_repo({ repoUrl: "owner/repo" })
→ This will cost 5.14 credits. AI audit for owner/repo has NOT run
and NOTHING has been charged. It reads up to 214 files, across up to two passes.
The report is delivered usually within 15 minutes*.
{ confirmRequired: true,
cost: { kind: "credits", credits: 5.14, centicredits: 514 } }
audit_repo({ repoUrl: "owner/repo",
confirmedCost: { kind: "credits", credits: 5.14, centicredits: 514 } })
→ Waiting for you to confirm. Nothing has run and nothing has
been charged. Here is your link:
https://nittim.com/confirm/… ← you open this and press Confirm
audit_repo({ repoUrl: "owner/repo",
confirmedCost: { kind: "credits", credits: 5.14, centicredits: 514 },
authorization: "a1b2c3…" })
→ the audit is submitted, 5.14 credits are spent, and you get
its id back. Read the report with get_auditYour agent shows you that number, then calls again with confirmedCost set to the exact cost it was quoted — the whole object, both credits and centicredits, copied verbatim. If the price has changed in between (a bigger repo than the last quote, a covered audit another tab just used), the call is refused and re-quoted rather than charged the difference. Agreeing to one price is not agreeing to another.
Then you get a one-time confirm link. That second call makes it and hands it to your agent so it can pass it on: open it, see the repo, the reach and the exact cost, and press Confirm. Your agent calls once more with the authorization it was given, and only then does the ledger move — by exactly that amount, once. A confirmation is good for one run, at that price, for a few minutes, and your assistant is never the one deciding — it relays the price and waits for you. (When both your MCP client and nittim's transport support in-conversation prompts, the same yes can be asked right where you are instead of through a link; today the link is the path that runs.)
Runs that cost you nothing skip all of it — an org inside its included allowance, a BYOK module run. The confirmation follows the charge, not the caller.
Running unattended? When you mint a key on /keys you can tick a box that lets that key spend without asking you each time — for a nightly CI audit or a long agent loop. Its spend cap still applies, the price handshake still happens, the report still lands on your account, and you can revoke it in one click. Only a signed-in person can create such a key: an API key cannot mint one, including one that is itself autonomous.
Why there are two steps and not one. The price echo proves your assistant saw the number. It cannot prove you did — on MCP the assistant reads the result and you read what it chooses to repeat, and no wording in a tool result changes that. The click is the part a model can't do for you.
scan_source and list_modules take no confirmation, ever — no key needed either, since nothing moves and nothing is charged. get_audit and the two deterministic modules don't cost credits, but still need a key: they read data a guest shouldn't.
The loop
The pattern that makes this useful for an agent, not just a human with a browser: run audit_repo once, read back the findings and their fixes, and patch the ship-blockers it names. Run it again to see they're gone — nittim only re-audits when the commit actually moves, so an unchanged commit gets back the exact same report, at no charge. This is not a loop that spends credits every lap: run_module is the cheaper single-dimension check (security, privacy, secret-scan, …) for one pass along the way.
To gate a whole team's pull requests instead of one agent's local loop, call the REST API below from any CI system and fail the build on the verdict — a four-step ladder, Production Ready · Production Ready with Conditions · High Risk · Not Safe for Production — so the gate can pick which step fails it. One value is not a step: Not audited, when the AI step was paused and nothing was rated.
REST
An audit is asynchronous: kick it off, then poll. Every AI pass here — Audit and Full Audit alike — is submitted to the Batches API and lands usually within 15 minutes*; the call below hands back an id straight away, never a report. A key runs and charges on the first POST — there is no confirm step for a REST/API-key caller the way there is for an MCP client talking to a person. Start one —
curl -X POST https://nittim.com/api/v1/audit \
-H "Authorization: Bearer nittim_sk_…" \
-H "Content-Type: application/json" \
-d '{"repoUrl":"https://github.com/owner/repo"}'No x-nittim-anthropic-key header on this endpoint — a batch is finalized hours later by a job that never saw your request, so a customer key sent here is refused (400) rather than silently run on nittim's own model key and charged as if it had. POST /api/v1/source/audit (below) is the BYOK door: post the repository's files instead of a GitHub URL and it answers with the report in the call, on your own key.
Full Audit isn’t on offer for this repository — it holds more source than one audit reads end to end. Point nittim at a repository — or a branch — carrying less source, and this gate will say what Full Audit covers there. What’s on offer here reads the highest-risk files first. The request comes back 422 with { reason: "pass-ceiling" } — refused up front, nothing charged and nothing run — never a capped, partial pass sold as Full Audit.
The response is 202 with a poll_url and a report_url. Poll until the status is no longer "running" —
curl https://nittim.com/api/v1/audit/<id> \ -H "Authorization: Bearer nittim_sk_…"
Add ?format=markdown, ?format=digest, or ?format=sarif to the poll URL for the full report, a compact digest, or SARIF 2.1.0 — the standard results format code-scanning tools read, so findings show up in GitHub's Security tab.
No repo? Post the files
Some agent platforms only speak plain HTTP — no MCP client, no GitHub repository either. If your code lives in a builder like Abacus or Replit, or your agent just has files on disk with nowhere to push them, post them straight to nittim instead of fetching a repo. Same engine, same scanners, same everything — the only difference is where the source comes from.
Before posting anything, MCP's estimate_audit tool answers the price for a paths-and-sizes manifest — no content, nothing uploaded — so a caller with a balance too low to cover the run finds out before spending the upload, not after a 402. At most 1000 entries; over that comes back saying so rather than a schema error.
AI audit — score + verdict
POST /api/v1/source/audit is the posted-source twin of POST /api/v1/audit: same async job, same 202 with a poll_url, same poll route, same credits pricing, same batch delivery on nittim's own model key. Its one difference: this is the endpoint that still honours x-nittim-anthropic-key (BYOK Pro) — on your own key it answers with the report in the call instead of landing usually within 15 minutes*. A single-pass AI run this way draws 2 credits from your subscription's 100-credit monthly allowance (about 50 single-pass audits a month) instead of the ordinary 5.14 credits, with your key paying the model tokens. Full Audit on this same endpoint costs more — it is priced per pass, exactly as it is on credits. Omit the header to run on credits as usual.
curl -X POST https://nittim.com/api/v1/source/audit \
-H "Authorization: Bearer nittim_sk_…" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app",
"files": [
{ "path": "src/index.ts", "content": "..." },
{ "path": "package.json", "content": "..." }
]
}'Poll the returned poll_url exactly as you would for a repo-based audit — it's the same GET /api/v1/audit/<id> route, and every ?format= option above works on it too.
A full-coverage run past what one bounded invocation can read still batches here rather than refusing — this endpoint holds every posted byte in memory for the one request that posts it, so it can submit every pass in ONE call instead of chaining across invocations the way a fetched repository does. 422 with { reason: "pass-ceiling" } survives only for source too large even at the batch lane's own wider ceiling, and { reason: "byok-unsupported" } covers a customer Anthropic key over the bounded ceiling — a batch lands hours later on an invocation that never saw it, so BYOK can only ever run one-shot, inside the request that posted it.
Free scan — evidence, no verdict
POST /api/v1/source/scan runs the free deterministic tier — committed secrets and known-vulnerable dependencies, no model call, no charge — and answers inline, since there's no job to poll:
curl -X POST https://nittim.com/api/v1/source/scan \
-H "Authorization: Bearer nittim_sk_…" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app",
"files": [
{ "path": "src/index.ts", "content": "..." }
]
}'The response is 200 with { id, share_url, report } — report is hard evidence only, never a verdict. It's still an authenticated call (send the same Authorization header) — anonymous scanning is a web-only convenience on the dashboard, not a programmatic one.
Both endpoints, either way
files is the exact same shape as audit_source/scan_source take over MCP: an array of { path, content }, plain text only.
Limits: at most 500 files and ~20MB of JSON total. Pre-filter node_modules, build output, and binaries — they'd get dropped anyway. Post more than ~20MB of raw JSON and you get a 413 before either endpoint tries to parse it; that ceiling sits under Vercel's own request-body limit, so you get nittim's clean error instead of a platform-level failure.
Privacy: a posted snapshot is always treated as private source — never shown in any public listing, and its report is gated to the account that posted it.
A 402 from the audit endpoint means you're out of credits — the response carries a checkoutPath; buy more at nittim.com/account, or send an x-nittim-anthropic-key header (BYOK Pro) to run on your own Anthropic key instead — the audit endpoint only, not the free scan.
Your key is forwarded per request and never stored.
Building against an OpenAPI-importing agent builder (Abacus and similar)? Import https://nittim.com/openapi-source.json directly — it covers both endpoints above plus the poll route.
Already working inside a coding assistant? Don't assemble this yourself
Reading every file into your own context just to build the POST above doubles what you're holding — once as the files, again as the request — and to a security-conscious agent harness, "read files, attach a bearer credential, POST them somewhere" is indistinguishable from exfiltration, so it may refuse outright. nittim-bridge is a small local MCP server that does this walking, pricing and posting on the developer's behalf: it holds NITTIM_API_KEY and reads the repo directly from disk, so you never see the file contents or the key — only a price to relay and, later, a report id. Run npx nittim-bridge; call its own estimate/run/status tools instead of assembling the calls above by hand. Source still leaves the developer's machine exactly as it would from a direct call above — this only moves who assembles the request, never what's sent or where.
The free Nittim Loop
Once connected, the Nittim Loop rubric is a prompt the server hands your assistant on request — /mcp__nittim__nittim-selfcheck in Claude Code — so nothing is fetched from the web and nothing lands in your project. Without MCP, the same text is at https://nittim.com/selfcheck.md; the Nittim Loop page shows how to install a one-line pointer to it rather than the rubric itself.
Put it in CLAUDE.md
Commit this block once and every teammate's assistant reaches for the free look on its own — no nittim_sk_… anywhere in the file, because the two tools it names don't take one:
# nittim We use nittim (nittim.com) for a scan of committed secrets and known vulnerable dependencies. What nittim does with code it reads: nittim.com/trust. It is a scan, not a verdict. It runs as an MCP server, so connecting adds one entry to this machine's client config, not to this repo, and the client still asks before a tool call. With no key it can only read — scan_source and list_modules — and no money changes hands: claude mcp add --transport http nittim https://nittim.com/api/mcp The scan works by sending file contents to nittim.com. We have read their trust page and accepted that for this repo — that call is ours, not yours. When we want that scan, ask for scan_source on the working folder. Show us the list of files you would send and wait for a yes before sending it; leave out anything holding customer data. It sends the files you pick to nittim.com and nothing else, and you can scan this folder whenever we ask. Prefer it over rereading this repo in the chat for secrets and CVEs — that burns our tokens for a worse answer. Run a paid report only when we have a nittim key and one of us has asked for a production verdict. After a nittim report, leave "are we production ready?" to us: fix the blockers it lists, and we will run nittim again.
Report what the loop found — opt-in, counts only
After the loop reaches a real stopping point, report_loop (above) shares anonymised counts with nittim — never a title, path, or snippet — and the results show up at nittim.com/loop, a live public read of what the loop is actually finding and fixing across every reporter. The reward is for a real loop that acted — at least two passes, something fixed, and a real stop: converged, flagged systemic, or capped after three or more passes. Report the same repo again later and it UPDATES that record with the new numbers rather than being rejected — the reward is a one-time check, decided on the first report, so it's never re-evaluated on a later resubmission even if that first report earned nothing, but the numbers stay current. 5 credits under 20 repos reported, 3 credits under 100 repos reported, 1 credit under 500 repos reported, then nothing once the corpus reaches 500 — nittim's own report_loop answer always states today's exact number. Capped too: three rewarded repos per account, lifetime, and at most one newly-rewarded repo per account per UTC day. No MCP client? The REST twin takes the identical body and returns the same shape — including outcome: "inserted" | "updated", naming which of the two happened:
curl -X POST https://nittim.com/api/v1/loop/report \
-H "Authorization: Bearer nittim_sk_…" \
-H "Content-Type: application/json" \
-d '{
"repo_hash": "<sha256 of the repo'"'"'s canonical identity, never its name>",
"repo_size_bucket": "m",
"passes": [
{ "n": 1, "findings": { "security": { "critical": 1, "high": 0, "medium": 0, "low": 0 } }, "fixed": 0, "clean": false },
{ "n": 2, "findings": {}, "fixed": 1, "clean": true }
]
}'Troubleshooting
The tools worked before, and now they error or look missing
The server was likely updated under your connection — reconnect or reload the nittim MCP server in your client and try again. Nothing is lost, and a failed tool listing charged nothing. The server states its version in its own instructions, so a reconnected client can see that it changed.
Every call answers 401
The key was revoked, expired, or mistyped. Mint a new nittim_sk_… on the API keys page and replace the bearer token in your MCP config — a revoked key stops working immediately, and there is no grace period to wait out.
get_audit has said “running” for a while
That is batch delivery, not a hang: the report lands usually within 15 minutes*. Keep polling get_audit — at least a minute apart, never in a tight loop — and never start a second audit because the first is still running.
“Not found” on an audit id you own
A report is read by the account that ran it: the key your config sends probably belongs to a different account — or an org-scoped key where a personal one ran the audit. Check which key the client is configured with, or mint one on the right account at /keys.