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

@mixmaxhq/context-sdk

v1.0.0

Published

Typed client for Mixmax context-api — list/get/create/update/delete/bundle context blocks. Server-side callers use SigV4-signed Function URL; browser callers use the cookie-authenticated public gateway. Transport is swappable.

Readme

@mixmaxhq/context-sdk

Typed client for Mixmax context-api. Six operations covering CRUD over context blocks plus a bundle convenience for AI cold-start. Server-side callers (Lambda/ECS) go through the SigV4-signed Function URL; browser callers go through the cookie-authenticated public gateway. The transport is swappable — future migrations (VPC Lattice, mTLS) drop in without changing the public method surface.

See docs/adr-inter-service-auth.md in monorepo-context for the architectural decisions behind the SDK.

Install

npm i @mixmaxhq/context-sdk

Getting started (server-side)

For a Lambda/ECS service that calls context-api on behalf of a user:

import { ContextSDK } from '@mixmaxhq/context-sdk';
import EnvironmentLib from '@mixmaxhq/environment';

const env = EnvironmentLib.get();

export async function draftReplyHandler(event) {
  const { userId, workspaceId } = event.requestContext.authorizer;
  const ctx = new ContextSDK({ userId, workspaceId }, env);

  // Pull everything in one call — personal + workspace + per-team blocks
  const { personal, workspace } = await ctx.bundle();

  // ...feed `personal`/`workspace` into your LLM prompt
}

You also need to grant the caller's Lambda role lambda:InvokeFunctionUrl on context-api's Function URL ARN. Use the shipped Terraform module:

module "context_caller" {
  source      = "github.com/mixmaxhq/monorepo-context//libs/terraform-aws-context-api-caller?ref=v1"
  environment = var.environment
  role_name   = aws_iam_role.my_lambda.name
}

That's all the infra setup. The IAM grant scales linearly per caller — no SG mesh, no shared secret, no central state.

Getting started (browser)

For the SPA, use the useGateway: true mode:

import { ContextSDK } from '@mixmaxhq/context-sdk';
import EnvironmentLib from '@mixmaxhq/environment';

const ctx = new ContextSDK({ useGateway: true }, EnvironmentLib.get());

// Same method surface, different transport under the hood
const { blocks } = await ctx.list({ scope: 'personal' });

The browser path hits the existing /v1/context/blocks* routes on the public gateway with credentials: 'include'. The gateway's Lambda authorizer validates the user's session cookie.

Cookbook (the job, not the method)

Pull context for a draft-reply Lambda

const { personal, workspace } = await ctx.bundle();
const prompt = renderPrompt({ personal, workspace, email });

Surface only blocks visible to the user's team

const { blocks } = await ctx.list({ scope: 'workspace', teamId: identity.teamId });

Save a user's new ICP description as a workspace block

const { block } = await ctx.create({
  scope: 'workspace',
  section: 'ICP',
  title: 'Series B SaaS founders',
  body: '...',
  teamIds: ['team-AE-mid-market'],
});

Refresh a brand-voice block without touching other fields

// Partial patch — omitted fields are unchanged.
await ctx.update(blockId, { scope: 'workspace', body: newBody });

Clear team narrowing on a block (make it visible to all teams)

await ctx.update(blockId, { scope: 'workspace', teamIds: null });

Soft-delete a deprecated block

await ctx.delete(blockId, { scope: 'workspace' });
// Auto-purged after 90 days. To restore within the window, ping on-call.

Error handling

All errors are subclasses of ContextApiError with a .status field.

import { ContextSDK, NotFoundError, ForbiddenError } from '@mixmaxhq/context-sdk';

try {
  await ctx.update(blockId, { scope: 'personal', body });
} catch (err) {
  if (err instanceof NotFoundError) {
    // Block was deleted between read and write. Fall back to create or skip.
    return;
  }
  if (err instanceof ForbiddenError) {
    // User can't update this block (e.g. personal block owned by another user).
    throw new UserFacingError('You can only update your own context blocks.');
  }
  throw err;
}

Retry behavior

Transient failures (429, 5xx, network/timeout) are retried automatically with decorrelated jitter (max 3 retries, capped at 5s total budget). The SDK honors a server-provided retryAfter field in the response body when present. Non-retryable errors (401, 403, 422) surface immediately.

Transports (advanced)

The SDK ships two transports out of the box and accepts a custom one:

import { ContextSDK } from '@mixmaxhq/context-sdk';
import type { Transport } from '@mixmaxhq/context-sdk/transport';

class MyCustomTransport implements Transport {
  async send(req) { /* ... */ }
}

const ctx = new ContextSDK({ userId, workspaceId }, env, {
  transport: new MyCustomTransport(),
});

Why this matters: when AWS announces VPC Lattice (or mTLS or anything else) as the next-generation inter-service transport, the migration is a new Transport class + a SDK minor bump. The callers' code does not change.

Versioning

Strict semver. Patch releases for bug fixes and transport-internal changes. Minor for new methods and backward-compatible widenings. Major for breaking changes — deprecation window of 90 days minimum, with the old method shipped alongside the new for one minor release.

Reporting issues

File an issue at monorepo-context or ping #brain-context on Slack.