> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmcpulse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Local development

> Point the SDK at an API on your own machine, and turn instrumentation off in tests and CI.

Two options exist for development and nothing else: `endpoint` and `enabled`.

## Point at a local API

```ts theme={null}
watch(server, {
  key: process.env.MCPULSE_KEY ?? "",
  endpoint: process.env.MCPULSE_ENDPOINT,   // http://localhost:3000
});
```

A trailing slash is stripped for you. Leaving `endpoint` unset sends to the hosted API.

> [!WARNING]
>
> Never set `endpoint` in production. MCPulse is not self-hosted, so there is nowhere else to point — and because the SDK never throws and drops batches it cannot send, a wrong endpoint means you install, wrap, see no error at all, and simply never appear in your dashboard.
>
> Drive it from an environment variable that is unset in production rather than from a hardcoded string.

## Turn it off in tests and CI

```ts theme={null}
watch(server, {
  key: process.env.MCPULSE_KEY ?? "",
  enabled: process.env.NODE_ENV === "production",
});
```

`enabled: false` returns the server untouched. An **empty key does the same thing** regardless of `enabled`, so simply not setting `MCPULSE_KEY` in CI is enough — a server started without its key should be silent, not a source of 401s on every flush.

## Watch what is being sent

```ts theme={null}
watch(server, { key: process.env.MCPULSE_KEY, debug: true });
```

Debug goes to **stderr**, never stdout — on a [stdio server](/sdk/stdio) stdout is the transport, and anything else written there corrupts the stream.

You will see `watching`, then `startup: N tools, client <name>` on the first initialize, then each batch.

## Use a separate MCP for development

Not a separate key on the same MCP — a separate **MCP**. Development traffic is not representative: you call every tool once, you deliberately break things, and you restart constantly, which fragments [sessions](/metrics/sessions).

Mixed into production numbers that moves [first-call success](/metrics/first-call-success) and [cost per session](/metrics/cost) for reasons that have nothing to do with your users.

## Exercise every behaviour

The SDK repo ships a test server with one tool per behaviour — fast, slow, empty, `isError`, throw, and one registered but never called so [dead-tool detection](/tools/dead) has something to find.

```bash theme={null}
cd examples/test-server
pnpm install
MCPULSE_KEY=mp_live_… MCPULSE_ENDPOINT=http://localhost:3000 pnpm exercise
```

`pnpm exercise` drives every behaviour once through a real MCP client, flushes, and exits. It is the fastest way to confirm a whole install path — SDK to API to dashboard — is working, and to tell whether a problem is in your wiring or ours.

## Restarts open new sessions

A session id is generated per process, so every restart starts a fresh session. Expect an inflated session count and a low cost-per-session while developing. This is another reason to keep development on its own MCP.

## Related

* [Options](/sdk/options)
* [SDK troubleshooting](/sdk/troubleshooting)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.