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

@qverisai/sdk

v0.9.0

Published

QVeris TypeScript SDK for connecting AI agents to professional data and tools: find services, review supported scope, call, and audit usage

Readme

@qverisai/sdk

TypeScript SDK for QVeris — the Agent External Data & Tool Harness. Discover, inspect and call 1000+ ranked external data & tool capabilities with unified billing and usage audit. No per-provider API keys required.

  • Typed end to end — response types aligned with the public OpenAPI contract (categories, capabilities, why_recommended, expected_cost, billing)
  • Zero dependencies — native fetch, Node.js 18+
  • Same wire semantics as the Python SDK and the MCP server

Install

npm install @qverisai/sdk

Quickstart

import { Qveris } from '@qverisai/sdk';

const qveris = new Qveris({ apiKey: process.env.QVERIS_API_KEY! });
// or: const qveris = Qveris.fromEnv();

// 1. Discover — free, returns ranked capabilities
const found = await qveris.discover('stock price market data API', { limit: 5 });
for (const tool of found.results) {
  console.log(tool.tool_id, '—', tool.why_recommended);
}

const parameters: Record<string, unknown> = { symbol: 'AAPL' };
const matchesType = (type: string, value: unknown) => {
  if (type === 'string') return typeof value === 'string';
  if (type === 'integer') return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value);
  if (type === 'number') return typeof value === 'number' && Number.isFinite(value);
  if (type === 'boolean') return typeof value === 'boolean';
  if (type === 'array') return Array.isArray(value);
  if (type === 'object') return value !== null && typeof value === 'object' && !Array.isArray(value);
  return false;
};
// 2. Select only a contract compatible with every supplied value
const selected = found.results.find((tool) => {
  if (!tool.params) return false;
  const definitions = new Map(tool.params.map((param) => [param.name, param]));
  if (definitions.size !== tool.params.length) return false;
  return Object.entries(parameters).every(([name, value]) => {
    const param = definitions.get(name);
    return Boolean(param && matchesType(param.type, value) &&
      (!param.enum || param.enum.some((allowed) => Object.is(allowed, value))));
  }) &&
    tool.params.every((param) => !param.required || Object.prototype.hasOwnProperty.call(parameters, param.name));
});
if (!selected) throw new Error('Inspect candidates before calling: no compatible contract was returned');

// 3. Apply the current request's value instead of copying sample values
const missing = selected.params!.filter((param) => param.required && parameters[param.name] === undefined);
if (missing.length) throw new Error(`Missing inputs: ${missing.map((param) => param.name)}`);
const outcome = await qveris.call(selected.tool_id, {
  searchId: found.search_id,
  parameters,
});
console.log(outcome.success, outcome.result);

inspect and probe are optional checks, not mandatory stages. Inspect when selection or valid request construction depends on missing/stale contract details, or candidates need comparison. Probe when parameters need validation, a current quote is needed for a budget decision, or preflight is explicitly requested. A quote is not a price reservation or user authorization.

For provider comparison, Inspect every candidate when current scope or a complete contract must be confirmed; a Discover summary is not confirmation. Probe every candidate when the comparison requires a current quote. Reuse may preserve an exact route, never business parameters or results: build parameters from the current request, and make a fresh Call for current, latest, today, or other time-sensitive data.

The SDK is stateless for routing: it does not persist semantic intent, schema, price, or business results. Preserve a Discover result's real search_id in the active application flow. If your host adds reuse, isolate it by account/API endpoint/authorization/session, rebuild business values from the current request, and expire schema, price, and availability metadata; never invent attribution or cache credentials/sensitive values.

Audit

// Final charge status for an execution
const usage = await qveris.usage({ execution_id: outcome.execution_id });

// Credit balance movements
const ledger = await qveris.ledger({ direction: 'consume', summary: true });

// Current balance
const credits = await qveris.credits();

API reference

Construct with new Qveris({ apiKey }) or Qveris.fromEnv(overrides?) (reads QVERIS_API_KEY and resolves the API endpoint automatically). Applications that manage short-lived credentials can instead pass an async-capable provider:

import { Qveris, type CredentialProvider } from '@qverisai/sdk';

const credentialProvider: CredentialProvider = {
  async getCredential({ resource, scopes }) {
    // Resolve a bearer credential through your application's credential store.
    return process.env.QVERIS_API_KEY!;
  },
};

const qveris = new Qveris({ credentialProvider });

The provider receives the resolved API resource, configured audience and requested scopes. Configure either apiKey or credentialProvider, never both. A provider does not select or change the API endpoint.

For a registered confidential Agent Runtime, exchange a user's OAuth access token for a short-lived, non-refreshable delegation token:

import {
  AgentDelegationCredentialProvider,
  Qveris,
  type CredentialProvider,
} from '@qverisai/sdk';

const delegatedResource = 'https://api.qveris.ai/tools';
const subjectCredentialProvider: CredentialProvider = {
  async getCredential() {
    return loadCurrentUserAccessToken();
  },
};
const credentialProvider = new AgentDelegationCredentialProvider({
  tokenEndpoint: 'https://qveris.ai/api/v1/oauth/token',
  clientId: process.env.QVERIS_AGENT_CLIENT_ID!,
  clientSecret: process.env.QVERIS_AGENT_CLIENT_SECRET!,
  subjectCredentialProvider,
  resource: delegatedResource,
  scopes: ['tools.inspect', 'tools.execute'],
  constraints: { toolIds: ['openweathermap.weather.retrieve.v2'], maxCredits: 25 },
});
const qveris = new Qveris({
  credentialProvider,
  credentialAudience: delegatedResource,
  credentialScopes: ['tools.execute'],
});

Keep the confidential client secret on a trusted server; do not embed this provider in browser or mobile code. Delegation tokens stay in memory, are never refreshed, and fail closed when the requested audience or scopes exceed the configured ceiling.

A credential provider supplies the bearer value that authenticates requests to the QVeris API itself. It is unrelated to the data and tool providers in the service catalog: their upstream credentials are managed by the platform and never pass through the SDK.

| Method | Billed | Returns | Notes | | --- | --- | --- | --- | | discover(query, options?) | Free | SearchResponse | options: limit, sessionId, view, lang, timeoutMs. view: 'routing' returns compact routing cards; omitted/default is full. | | inspect(toolIds, options?) | Free | SearchResponse | toolIds is one id or an array; options: searchId, sessionId, timeoutMs. An empty array resolves locally with no request. | | call(toolId, options) | Credits | ExecuteResponse | Strict single-submit by default. model records model attribution. respondWith accepts full, summary, or fields:<JSONPath,...>; deprecated compatibilityMode: 'legacyOptionalFields' explicitly enables one projection replay. | | credits() | Free | CreditsResponse | Current balance and bucket details. | | usage(filters?) | Free | UsageEventsResponse | Request-level audit; filter by execution_id, search_id, dates, summary, limit. | | ledger(filters?) | Free | CreditsLedgerResponse | Settled credit movements; filter by direction, dates, summary, limit. |

Read-only members: qveris.rateLimitRetryCount (see Rate limiting).

Key response fields:

  • SearchResponse — search_id, total, results: ToolInfo[] (tool_id, name, description, params, examples.sample_parameters, stats.success_rate, stats.avg_execution_time_ms, expected_cost, why_recommended).
  • ExecuteResponse — execution_id, success, result, billing (pre-settlement estimate; the final charge is in usage() / ledger()).

Projection options are never sent unless explicitly configured. Omitting respondWith keeps compatibility auto-delivery with a 20KB default inline limit and overflow envelope. Explicit respondWith: 'full' forces complete inline result.data, takes precedence over a finite maxResponseSize, and reports response_too_large at the platform hard limit instead of truncating. Summary delivery is independent of maxResponseSize.

Paid calls do not retry 429/503 or automatically replay a rejected optional field. The deprecated compatibilityMode: 'legacyOptionalFields' opt-in enables exactly one projection fallback when an older service returns 422 extra_forbidden; invalid projections remain errors.

All types are exported from the package root (import type { SearchResponse, ExecuteResponse, ToolInfo } from '@qverisai/sdk').

Configuration

| Option / env var | Description | | --- | --- | | apiKey / QVERIS_API_KEY | Required. Create one at qveris.ai | | credentialProvider | Async-capable bearer credential source; mutually exclusive with apiKey | | credentialAudience | Audience forwarded to the credential provider for fail-closed binding | | credentialScopes | OAuth scopes forwarded to the credential provider | | baseUrl / QVERIS_BASE_URL | API endpoint: constructor option > environment variable > built-in default | | timeoutMs | Default request timeout (30s; call defaults to 120s) | | maxRetries | Read-operation retries for rate-limited (429) / transient (503) responses (default 3; 0 disables); paid calls never inherit it |

API keys never select the endpoint. Endpoint overrides must be HTTP(S) URLs without credentials, a query string, or a fragment.

Rate limiting & retries

The client transparently retries rate-limited (429) and transient (503) responses for read/audit operations: it honors the Retry-After header when present, otherwise backs off exponentially with full jitter. Each wait is capped and retries are bounded by maxRetries; paid calls remain single-submit and HTTP redirects are not followed.

const qveris = new Qveris({ apiKey: process.env.QVERIS_API_KEY!, maxRetries: 5 });
// ... after some calls under load:
qveris.rateLimitRetryCount; // how many times it backed off (pressure, not failures)

Set maxRetries: 0 to disable. Rate-limit backoff is retried pressure rather than failure — read rateLimitRetryCount to observe it instead of treating the retried 429s as errors.

Errors

All failures throw QverisApiError (an Error subclass) with status, details, and an observability object (operation, endpoint, request id) for diagnostics:

import { QverisApiError } from '@qverisai/sdk';

try {
  await qveris.call('some.tool.v1', { parameters: {} });
} catch (err) {
  if (err instanceof QverisApiError && err.status === 402) {
    // insufficient credits — err.message includes the purchase link
  }
}

Framework integrations

Expose the QVeris workflow as Vercel AI SDK tools. ai and zod are peer dependencies:

npm install @qverisai/sdk ai zod
import { generateText, stepCountIs } from 'ai';
import { openai } from '@ai-sdk/openai';
import { Qveris } from '@qverisai/sdk';
import { getQverisTools } from '@qverisai/sdk/ai';

const qveris = new Qveris({ apiKey: process.env.QVERIS_API_KEY! });
const { text } = await generateText({
  model: openai('gpt-4o'),
  tools: getQverisTools(qveris), // qveris_discover / qveris_inspect / qveris_call
  stopWhen: stepCountIs(6),
  prompt: 'Find a stock quote capability and quote AAPL.',
});

Examples

Runnable scripts in examples/: the discover → call quickstart, optional inspection, a Vercel AI SDK agent, and rate-limit/observability. Each is safe to run without an API key (it explains how to set one), and any credit-spending call is gated behind RUN_QVERIS_CALLS=1.

Version history note

Versions 0.1.x of this npm package were an early MCP-focused SDK, since superseded by @qverisai/mcp. The typed REST client documented here starts at 0.2.0.

Related

License

MIT