within-sdk
v1.0.4
Published
Within SDK for MCP analytics, workflow intelligence, and qualified opportunities.
Maintainers
Readme
Within SDK
Instrument Model Context Protocol (MCP) servers with privacy-conscious workflow analytics. Within captures MCP activity, builds a catalog of available tools, groups pseudonymous user journeys, identifies qualified opportunities, and links confirmed conversions back to the workflows that produced them.
Documentation · Quickstart · API Reference · Get an API key
Installation
npm install within-sdk @modelcontextprotocol/sdkThe SDK requires Node.js 20 or later and an MCP server using
@modelcontextprotocol/sdk 1.11 or later.
Environment
Configure the vendor slug created during onboarding and its SDK API key in the server process that runs your MCP server:
WITHIN_VENDOR_SLUG=acme
WITHIN_SDK_API_KEY=within_sk_xxxKeep the API key in server-side environment or secret storage. Do not expose it in browser code or commit it to source control.
Quickstart
Register your MCP tools first, then call track() on the server instance used
by the running process.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { track } from "within-sdk";
const server = new McpServer({ name: "acme-mcp", version: "1.0.0" });
server.tool("search_companies", SearchCompaniesSchema, async (args) => {
return searchCompanies(args);
});
track(server, process.env.WITHIN_VENDOR_SLUG!, {
apiKey: process.env.WITHIN_SDK_API_KEY!,
identify: async (_request, extra) => {
const user = await lookupUserFromSession(extra?.sessionId);
if (!user) return null;
return {
userId: user.internalCustomerId,
userData: {
plan: user.plan,
segment: user.segment,
},
};
},
});
export { server };Use a stable, opaque vendor-local ID for userId rather than an email address,
name, or organization domain. The SDK hashes it locally with the vendor slug
before telemetry leaves your process.
By default, track() instruments MCP initialization, tools/list, and
tools/call activity. It also enables tool-call context capture and registers
the get_more_tools feedback tool. This changes the advertised tool list and
input schemas, while preserving vendor handler arguments and tool results.
Public APIs
track()
track(server, vendorSlug, options?): serverInstruments a high-level McpServer or compatible low-level MCP server and
returns the same server instance. Call it once for each server instance after
registering tools.
publishCustomEvent()
Publish a vendor-defined workflow event associated with a tracked server:
import { publishCustomEvent } from "within-sdk";
await publishCustomEvent(server, "acme", {
sessionId: mcpSessionId,
userId: user.internalCustomerId,
resourceName: "checkout_started",
parameters: { plan: "pro" },
message: "User started checkout after an MCP workflow",
tags: { channel: "mcp" },
});When passed a tracked server, the function reuses its API key and ingestion URL.
Pass sessionId to correlate with an MCP journey and userId when identity is
known. An explicit sessionId may reuse the subject already resolved for that
session; the SDK never falls back to a server-wide last session. Without either,
the event starts a fresh anonymous journey. You can also pass an MCP session ID
string as the first argument and provide apiKey in the event data.
reportConversion()
Report a confirmed lead-to-subscriber conversion from trusted server-side checkout, webhook, or account-upgrade code:
import { reportConversion } from "within-sdk";
const result = await reportConversion(
{
vendorSlug: process.env.WITHIN_VENDOR_SLUG!,
apiKey: process.env.WITHIN_SDK_API_KEY!,
},
{
userId: user.internalCustomerId,
convertedAt: new Date(),
plan: {
id: "pro",
name: "Pro",
interval: "month",
},
metadata: {
source: "checkout_webhook",
},
},
);Only userId is required. Use the same opaque vendor-local ID returned by
identify(); the SDK creates the subject locally before sending. Repeated
reports for the same subject on the same UTC day return inserted: false.
getSubjectForUserId()
Derive the same vendor-scoped subject used by identification and conversion reporting. The operation is local and deterministic, which makes it useful for tests and local verification.
import { getSubjectForUserId } from "within-sdk";
const subject = getSubjectForUserId("acme", user.internalCustomerId);Configuration
track(server, vendorSlug, options) accepts these commonly used options:
| Option | Purpose |
| --- | --- |
| apiKey | Within SDK API key. Falls back to WITHIN_SDK_API_KEY, then WITHIN_SDK_INGEST_KEY. |
| apiBaseUrl | Override the Within ingestion URL. Most integrations should use the default. |
| identify | Resolve a stable vendor-local userId and optional redacted traits for the current request. |
| log | Replace the default local SDK log destination with a callback. |
| enableTracing | Capture supported MCP activity. Defaults to true. |
| enableToolCallContext | Add and capture the tool-call context parameter. Defaults to true. |
| customContextDescription | Replace the default description shown for the injected context parameter. |
| enableReportMissing | Register the get_more_tools feedback tool. Defaults to true. |
| eventTags | Add validated string tags to captured activity. |
| eventProperties | Add custom properties to captured activity. |
| redactSensitiveInformation | Apply an additional vendor-provided redaction function. |
| privacy | Configure field/event byte limits and additional keys to redact. |
| exporters | Send redacted telemetry to optional vendor-configured exporters. |
apiBaseUrl falls back to WITHIN_SDK_API_URL, then
WITHIN_SDK_INGEST_BASE_URL, and finally the default Within ingestion service.
See the API Reference for the
complete option and result types.
Privacy and redaction
userIdvalues supplied to identification, custom events, and conversions are hashed locally into subjects.- Raw
userIdanduserNamevalues are not sent to Within. - Identity-like fields in user data, parameters, responses, tags, properties, and conversion metadata are removed or redacted before sending.
- Configurable field and event limits truncate oversized payloads.
- Within ingestion applies an additional server-side Presidio redaction pass for recognized values such as emails, phone numbers, SSNs, card-like values, URLs, IPs, bearer tokens, API keys, and secrets.
Pattern-based redaction cannot guarantee detection of every possible name, location, or sensitive value. Send only data needed for workflow analytics and use opaque identifiers whenever possible.
Documentation
Onboarding: Sign up and get an API key
- Create a Within dashboard account using your work email, vendor name, and vendor slug.
- Enter the confirmation code sent to your email, then sign in to the Within dashboard.
- Open Settings, select your vendor, and choose Generate under SDK API Key.
- Copy the newly displayed key and store it securely. The dashboard does not retain the plaintext key for later display.
- Set the key as
WITHIN_SDK_API_KEY, set your registered slug asWITHIN_VENDOR_SLUG, and use both values intrack().
