Skip to main content
@withlocus/credits is the server-side SDK for Locus Pro: zero dependencies, built on fetch. It generates idempotency keys and retries with backoff on its own. Use a secret key for management methods and a scoped agent connection credential for agent execution. It should never run in the browser. The current release of @withlocus/credits is 0.5.2, versioned in lockstep with @withlocus/credits-js and @withlocus/credits-react.
This SDK is for enterprise server integrations. Personal accounts connect agents through MCP OAuth and do not expose tenant secret keys, end-user tokens, Agent Connection service credentials, or server management APIs.

Constructor

call()

Run a metered API call. slug is "provider/endpoint"; body is the provider’s own request shape.
call() and callRaw() hand you the untouched Response, so you own the body — stream it, or read it once yourself. callJson() and callText() consume it for you and put the result on data.
CallOptions Returns CallResult / ParsedCallResult<T>
Idempotency-Key is mandatory on burns and the SDK handles it for you: one key per call(), reused verbatim across internal retries, so a retry never double-charges.

Agent connections

Create and manage scoped deployment credentials from a secret-key client:
mode: "platform" binds the connection to the pooled balance. mode: "end_user" requires externalUserId and binds it to that account. tools.enable contains exact provider/endpoint slugs; omit tools to inherit every tenant-enabled endpoint. Scope is immutable, so create a replacement connection when the account or tools must change. The 0.5.2 typed helper covers account binding, tools, budgets, and expiry. The REST create operation and dashboard also support immutable per-connection pricing overrides for end-user mode; use one of those surfaces when you need credential-specific markup because this SDK version does not type that field. Use the returned credential in a separate execution client if your agent calls the REST surface directly:
The full credential and MCP authorization header are returned only after create() and rotate(). List/get responses include the display prefix, status, expiry, rotation time, revocation time, and lastUsedAt, but never recover the credential. See Connect an agent for policy and lifecycle details.

Framework MCP presets

Version 0.5.2 converts a newly created or rotated connection into exact MCP configuration shapes without adding runtime dependencies:
Hosted model APIs expect the raw token, while runtime MCP clients expect the complete bearer header. The presets enforce that distinction and reject redacted credentials or invalid URLs. OpenAI presets default approval to never; pass requireApproval to change it. See Framework integrations for complete examples and lifecycle guidance.

Also exported

Detailed on other pages rather than here: LocusMcpOAuth and openAiMcpTool for application-owned MCP OAuth; parseMcpToolResult, prepareMcpResultForSynthesis, selectSynthesisAnswer and addCreditAmounts for final-answer synthesis; and the DEFAULT_BASE_URL, HEADERS and PATHS constants if you need the raw HTTP contract the client is built on.

balance()

Read a balance: your wholesale pool, or one end-user’s account.
Returns BalanceResult: { credits: string; usd?: string; raw: unknown }

searchTools()

Find enabled tools from a plain-language capability description. Pass user to apply that end user’s current policy as well as tenant catalog enablement.
query accepts 1–256 characters. limit defaults to 8 and accepts 1–20. Results include the execution slug, tool name, description, category, price or variable-cost marker, request schema, and example arguments.

ledger()

Page through the append-only ledger with cursor pagination and attribution filters.
LedgerParams: { user?, category?, cursor?, limit?, attribution? } Returns LedgerPage: { entries: unknown[]; nextCursor?: string; raw: unknown }

allocate() / deallocate()

Move credits between your pool and an end-user’s account. The move is atomic and never overdrafts.

topup()

Create a Stripe Checkout session for a top-up. Omit externalUserId to fund your wholesale pool; set it to fund that end-user’s balance instead.
The SDK fails loudly before any request goes out: it throws if successUrl or cancelUrl is missing or not an absolute HTTP(S) URL, if you pass both or neither of usd/credits, or if the amount isn’t an exact decimal string. Returns TopupResult: { url, sessionId, externalUserId, quote, bonus?, raw }. The quote may also contain bonus and nextBonusTier; end-user top-ups never earn a volume bonus. Read the current amount limits and bonus schedule instead of hard-coding them, then poll the session until Stripe’s webhook makes the credits usable:

endUserToken()

Mint a short-lived end-user JWT for the widget or a browser-side MCP connection.
EndUserTokenOptions: expiresIn (seconds, 60–3600, default 3600) and sessionId (16–128 characters) to bind the token to one browser session. Returns EndUserTokenResult: { token: string; expiresAt: string; expiresIn: number; tokenId: string; externalUserId: string; raw: unknown }

End-user catalog

Fetch every page of the privacy-safe provider catalog visible to one end-user token. The server applies the user’s current provider/endpoint policy and returns only final prices. The helper is fetchCatalog(auth, options), exported by @withlocus/credits-js and @withlocus/credits-react (not by the server SDK):
Exact prices are { state: 'exact', credits: string, usd: string }; variable and temporarily unavailable entries never fabricate numbers.

Errors

Every non-2xx response throws a typed error you can catch:

API reference

The raw HTTP endpoints the SDK wraps.

Quickstart

Set up keys and make your first metered call.