Skip to content
Connect an agent
Telemetry

Receive the opt-in daily totals of the local npm package

For the local npm package (@buun_group/plotwork-mcp) only, and only when the person who runs it has set PLOTWORK_USAGE=share; it is off by default, and setting DO_NOT_TRACK=1 stops the package from ever sending.

POST/telemetry/usage

TL;DR

QuestionAnswer
What does it do?Receive the opt-in daily totals of the local npm package.
What does it take?A JSON body of type LocalUsageBody.
What does it return?Status 200 with a body of type LocalUsageAck.
What can go wrong?400 the body is not valid json, has a field the schema does not name, or breaks a bound. the answer lists the first problems; 413 the body is larger than 64 kib; 429 too many requests; 503 this server has no database. Every failure uses the one error envelope.

What it does

For the local npm package (@buun_group/plotwork-mcp) only, and only when the person who runs it has set PLOTWORK_USAGE=share; it is off by default, and setting DO_NOT_TRACK=1 stops the package from ever sending. The body is pseudonymous daily totals for finished days: a random install id that changes every month, counts of how often each local tool ended in each way for each kind of diagram, the package version, the operating system family, and the Node major version. It never carries diagram source, tool arguments or results, names, folders, paths, error text, host names, user names, environment variables, or the time of day. Plotwork stores no address, header, account, or time beyond the day with it. The route is rate limited by the caller's address, which Cloudflare's rate limiter holds as a counter key for 60 seconds; Plotwork's own code does not store it. There is no session, key, or cookie. A count whose tool or kind the server does not know is dropped and counted as ignored. A count sent again replaces the one stored. The totals are indicative: anyone can post to a public route, so they are never used for limits, billing, or anything about an account. Rows are kept for 400 days.

Request body

The body has the type LocalUsageBody.

FieldTypeRequiredDescription
schema1yesThe version of this request shape. Always 1.
clientLocalUsageClientyes
client.name"plotwork-mcp"yesAlways plotwork-mcp.
client.versionstringyesThe package version, in semver form. at most 40 characters; pattern ^\d{1,6}\.\d{1,6}\.\d{1,6}(?:-[0-9A-Za-z.-]{1,32})?(?:\+[0-9A-Za-z.-]{1,32})?$.
client.os"linux" | "darwin" | "win32" | "other"yesThe operating system family. Anything else is other.
client.nodeintegeryesThe Node major version, a whole number. minimum 18; maximum 99.
daysLocalUsageDay[]yesAt most 31 finished days.
days[].daystringyesA UTC date from 40 days ago to yesterday. Nothing is accepted for today. pattern ^\d{4}-\d{2}-\d{2}$.
days[].idstringyesA pseudonym for one install for one month: the first 128 bits of an HMAC-SHA-256 of plotwork-usage: and the month, keyed with a secret that never leaves the device. It changes every month, so installs can be counted within a month and cannot be followed from one month to the next. pattern ^[0-9a-f]{32}$.
days[].countsLocalUsageCount[]yesAt most 400 counts. A tool, kind, and outcome may appear once a day.
days[].counts[].toolstringyesThe name of the local MCP tool, such as draw_diagram. A name this server does not know is ignored, not refused, so an older server accepts a newer package. pattern ^[a-z][a-z0-9_]{0,63}$.
days[].counts[].kindstringyesThe diagram kind the source declared, such as flow, or none for a call with no source or one that names no kind. A kind this server does not know is ignored, not refused, so an older server accepts a newer package. pattern ^[a-z][a-z0-9]{0,31}$.
days[].counts[].outcome"ok" | "rejected" | "error"yesok produced its answer, rejected was refused because of its input, error failed inside the tool.
days[].counts[].countintegeryesA whole number from 1 to 1,000,000. minimum 1; maximum 1000000.

Responses

StatusMeaningBody
200The request was understood: how many counts were stored, and how many were ignored because their tool is not known.LocalUsageAck
400The body is not valid JSON, has a field the schema does not name, or breaks a bound. The answer lists the first problems.ErrorResponse
413The body is larger than 64 KiB.ErrorResponse
429Too many requests.ErrorResponse
503This server has no database.ErrorResponse

Response body

A 200 answer has the type LocalUsageAck.

FieldTypeRequiredDescription
acceptedintegeryesHow many counts were stored. A count sent again replaces the one stored, so a retry never adds twice. minimum 0.
ignoredintegeryesHow many counts were dropped because their tool or kind is not one this server knows. A 200 means the client may treat the days as sent. minimum 0.

See also

DocWhy
API referenceEvery endpoint, and the error envelope
SchemasEvery request and response type
Tool referenceThe operations as callable tools