Mock Server

@nopii/mock-server is an in-memory NoPII for local development, tests, and demos. It needs no account, no keys, and no network, and behaves the same way on every run.

Preview

The SDKs are in preview and not yet published to npm or PyPI. Package names and APIs may change before 1.0.

Run it

bash
npx nopii-mock --port 7431

Point the SDKs at http://127.0.0.1:7431. It serves the client API, client sessions, reveal grants, and the proxy for OpenAI Chat Completions and the OpenAI Responses API, with a scripted LLM in place of a provider.

CredentialAccepted as
nsk_...A secret key
npk_...A publishable key
sk-...A provider key on proxy routes

See what each party received

GET /__mock/state returns a log of every request: what your backend sent, what the scripted LLM saw, and what came back. It is the quickest way to confirm that plaintext never reached a place it should not. POST /__mock/reset clears everything.

In tests

Skip HTTP entirely. The mock's fetch handles requests in memory.

typescript
import { createMockNoPII } from "@nopii/mock-server";
import { NoPIIServer } from "@nopii/node";
import { NoPII } from "@nopii/browser";

const mock = createMockNoPII({ names: ["Ada Lovelace"] });

// Mint a session the way your backend would.
const server = new NoPIIServer({ secretKey: "nsk_test", baseUrl: "http://mock", fetchImpl: mock.fetch });
const session = await server.clientSessions.create({ endUserId: "user-1" });

const nopii = NoPII.init({ baseUrl: "http://mock", sessionToken: session.token, fetchImpl: mock.fetch });
const { texts } = await nopii.tokenize("Ada Lovelace wrote the first program");
// texts[0] is "[NAME: ...] wrote the first program"

A publishable key works in the mock as it does in NoPII: only with an Origin header, which tests running outside a browser do not send. Use a client session, as above.

OptionMeaning
namesExtra names detected as people. Common full names such as Jane Doe, and surnames after a title such as Dr. Patel, are detected without it, as are emails and phone numbers.
allowedOriginsOrigins publishable keys may be used from. Defaults to any, but an Origin is still required.
streamChunkSizeCharacters per streamed chunk. Small by default, so tokens split across chunks.
llmReplace the scripted LLM with your own function of the messages it receives.

How close it is to the real thing

  • Its responses are checked against a snapshot of the NoPII API's own schema, so the mock cannot drift from the real API unnoticed.
  • It applies the same reveal policy, including session ownership and grants.
  • Detection is deliberately simple: patterns, a list of names, and common first names followed by a surname. An unusual name may be missed where the real service would catch it. It refuses the same sample Social Security numbers NoPII does, so a demo cannot appear to protect a value production would let through.
  • It does not implement the Anthropic Messages proxy route or device enrollment.

Related