sessionId that the SDK extracts from the MCP request metadata (_meta).
You do not create sessions. You pass meta: extra._meta on every track() call, and the SDK does the correlation.
How session correlation works
The SDK reads the first non-empty string value it finds under these keys of_meta, in order:
waniwani/sessionIdopenai/sessionIdopenai/sessionsessionIdconversationIdanthropic/sessionId
correlation.sessionId field on the outgoing V2 envelope. The SDK also extracts requestId, traceId, correlationId, and externalUserId from _meta using the same approach. Source is derived from the session key (openai/sessionId -> chatgpt, anthropic/sessionId -> claude, waniwani/sessionId -> chatbar).
The rule
Always pass
meta: extra._meta when tracking events from inside a tool handler.meta and do not set sessionId explicitly, the envelope ships without a session id and the dashboard cannot group it with the rest of the conversation.
Where _meta lives
| MCP library | Location |
|---|---|
@modelcontextprotocol/sdk | request.params._meta (on the raw request), surfaced as extra._meta in tool handlers |
@vercel/mcp-handler | extra._meta |
extra._meta in these docs, substitute the equivalent for your runtime.
The scoped client inside tools and flows
When a server is wrapped withwithWaniwani(server), each tool invocation receives a request-scoped WaniWani client on extra["waniwani/client"]. The scoped client is also surfaced as context.waniwani inside createTool handlers and as waniwani inside flow nodes. Its track() and identify() methods merge the current request’s _meta automatically, so you do not pass it yourself.
Manual session ids
For background jobs, backfills, or tests where_meta is not available, you can set sessionId explicitly:
Session lifecycle
The WaniWani backend emitssession.started automatically the first time it sees a new sessionId. You do not send it yourself, and session.started in the SDK’s EventType union exists only to type the ingestion envelope.
Sessions do not have a hard close. The backend treats them as closed after an idle window. If the user comes back, they either resume the same session (within the window) or start a fresh one, depending on what the host client sends in _meta.