Skip to content

Install the SDK

The SDK is one package per language, with no runtime dependencies of its own. Provider SDKs are optional peer dependencies: Metergraph instruments whichever ones you already have installed, and ignores the rest.

pip install metergraph
PackageInstallRuntime
metergraph (Python)pip install metergraphCPython 3.10 and newer
metergraph (Node)npm install metergraphNode.js 18 and newer

The Node package declares engines.node >= 18. If you use the Vercel AI SDK, that library sets its own floor: AI SDK 7 requires Node.js 22. Metergraph itself does not. See Vercel AI SDK.

Nothing here is installed for you, and nothing here is required. The Node package declares these as optional peer dependencies:

Peer dependencyAccepted range
openai>=4 <8
@anthropic-ai/sdk>=0.30
@google/genai>=1
ai (Vercel AI SDK)>=5 <8

The Python package declares no provider dependency at all, so pip will not complain about any version you have. The versions it is tested against are openai>=2.50.0,<3, anthropic>=0.40,<1 and google-genai>=1.

Python has one optional extra, for the OpenTelemetry span exporter:

OpenTelemetry exporter
pip install 'metergraph[otel]'

That pulls in opentelemetry-sdk>=1.30. See OTLP spans.

METERGRAPH_APP_TOKEN is the only setting with no working default. Everything else has one. Create an ingest key in the dashboard, then put it in the environment:

export METERGRAPH_APP_TOKEN=mg_...

To configure in code instead, call init() once, before the first wrap().

app/telemetry.py
import metergraph
metergraph.init(
token="mg_...", # or leave unset to read METERGRAPH_APP_TOKEN
repository="owner/repository",
environment="production",
)

init() is idempotent and never raises. The first configuration to succeed stays active for the life of the process. A second call logs one generic warning and changes nothing, and that warning never names an option or echoes a value.

wrap() calls init() for you when nothing has initialized yet, so with environment configuration a single wrap() line is the whole setup.

The full list of environment variables is on Configuration.

Repository identity is separate from the token and enables repository-level attribution. Any one of these is sufficient:

  • repository="owner/repository" in Python, or { repository: "owner/repository" } in TypeScript
  • the METERGRAPH_REPOSITORY environment variable
  • a .metergraph/config.json file containing {"repository":"owner/repository"}

Without one, the SDK warns once and continues on the legacy ingestion path.

This is not a failure mode. It is the designed behavior, and it is worth understanding because it is silent from your application’s point of view.

With no token, init() deliberately leaves itself uninitialized and logs one warning:

Metergraph capture disabled: token and ingest URL are required

It stays uninitialized on purpose, so that a later init() that does supply a token still succeeds. In the meantime:

  • wrap() returns your client and your calls run normally.
  • No rows are produced and nothing is sent anywhere.
  • Nothing raises, nothing retries, nothing slows down.

METERGRAPH_DISABLED=1, or disabled: true on init(), is the harder off switch: it marks the SDK initialized and does nothing further, so no later init() can turn capture on in that process.

  1. Python logs to the metergraph logger and TypeScript logs to the console. The confirmation line is at info level, so in Python you need to ask for it.

    import logging
    logging.basicConfig(level=logging.INFO)
  2. Metergraph patched 7 seam(s) on openai client: chat.completions.create, ...

    That message means the methods were instrumented. If you see Metergraph found no supported methods on ... client instead, you wrapped something that is not a supported provider client, or a client whose resources are constructed lazily in a way wrap() could not reach.

    The seam count on its own does not prove a token is set. wrap() patches the methods either way, and the patched method checks for a live runtime at call time. Check for the “capture disabled” warning above as well.

  3. Rows are batched in the background, so allow a few seconds. If nothing arrives, Send your first trace walks the whole path end to end, and Errors covers what the ingest endpoint rejects.