Sign In

@posthog/mcp

Package Overview
Dependencies
Maintainers
22
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@posthog/mcp - npm Package Compare versions

Comparing version
0.10.7
to
0.10.8
+70
dist/extensions/output-instructions.d.ts
import type { LoggerFn } from './logger';
/**
* The `conversation_id` session handle reaches the agent as a text block appended to the
* tool result. That block is invisible to any client that reads
* `structuredContent` instead of `content` — which is what clients do whenever a
* tool declares an `outputSchema`. Measured against Claude Code, correlation for
* such tools drops to zero.
*
* The fix is to mirror the session handle into `structuredContent` as well, which this
* module does in two halves that must stay in that order:
*
* 1. declare `_mcp_instructions` on the tool's advertised `outputSchema`
* 2. write it into the result's `structuredContent`
*
* The declaration is what makes the write safe. The MCP client ajv-validates
* `structuredContent` against the schema from `tools/list`, and
* `zod-to-json-schema` emits `additionalProperties: false` for a plain
* `z.object`, so an undeclared key is not ignored — it fails the entire tool
* result. Only tools that got the declaration are ever written to.
*/
export declare const MCP_INSTRUCTIONS_KEY = "_mcp_instructions";
export interface OutputInstructionsInjectableTool {
name?: string;
outputSchema?: unknown;
[key: string]: unknown;
}
/**
* True when we can safely declare {@link MCP_INSTRUCTIONS_KEY} on this tool's
* advertised output schema.
*
* Requires a plain-object schema we can extend. A tool with no `outputSchema`
* has nothing to mirror into and keeps working through `content`; a composed
* schema (`oneOf`/`allOf`/`anyOf`/`$ref`) has no single `properties` bag to add
* to. Both stay content-only, matching the policy on the input side.
*/
export declare function canDeclareOutputInstructions(outputSchema: unknown): boolean;
/**
* Returns a copy of the tool with an optional {@link MCP_INSTRUCTIONS_KEY}
* property added to its output schema, or the tool untouched when it has no
* output schema to extend.
*
* The property is never added to `required` — a result without it must stay
* valid, since every tool result predating this change lacks it.
*/
export declare function addInstructionsToOutputSchema<TTool extends OutputInstructionsInjectableTool>(tool: TTool, logger?: LoggerFn): TTool;
/**
* Declares {@link MCP_INSTRUCTIONS_KEY} across a tool listing. Tools without an
* output schema, and tools whose schema we cannot extend, pass through unchanged.
*/
export declare function addInstructionsToOutputSchemas<TTool extends OutputInstructionsInjectableTool>(tools: TTool[], logger?: LoggerFn): TTool[];
export interface ConversationInstructions {
conversation_id: string;
instructions: string;
}
/** The payload mirrored into `structuredContent` for a tool we declared the key on. */
export declare function buildConversationInstructions(conversationId: string): ConversationInstructions;
/**
* Adds {@link MCP_INSTRUCTIONS_KEY} to a result's `structuredContent`, which is
* where clients look once a tool declares an `outputSchema` — the `content` text
* block carrying the session handle is invisible to them.
*
* Unlike the text block, this rides *every* response rather than only the one
* that minted the session handle, so an agent that drops it can read it back.
*
* Returns the result untouched when there is no plain-object `structuredContent`
* to extend, or when the tool already produced its own key — customer data wins.
* Never mutates the input.
*/
export declare function mirrorInstructionsIntoStructuredContent(result: unknown, conversationId: string): unknown;
//# sourceMappingURL=output-instructions.d.ts.map
{"version":3,"file":"output-instructions.d.ts","sourceRoot":"","sources":["../../src/extensions/output-instructions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAIxC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,oBAAoB,sBAAsB,CAAA;AAQvD,MAAM,WAAW,gCAAgC;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAgC3E;AAwCD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,SAAS,gCAAgC,EAC1F,IAAI,EAAE,KAAK,EACX,MAAM,GAAE,QAAc,GACrB,KAAK,CA8CP;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,SAAS,gCAAgC,EAC3F,KAAK,EAAE,KAAK,EAAE,EACd,MAAM,GAAE,QAAc,GACrB,KAAK,EAAE,CAET;AAED,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAID,uFAAuF;AACvF,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG,wBAAwB,CAE9F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAkBxG"}
"use strict";
var __webpack_require__ = {};
(()=>{
__webpack_require__.d = (exports1, definition)=>{
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
enumerable: true,
get: definition[key]
});
};
})();
(()=>{
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
__webpack_require__.r = (exports1)=>{
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports1, '__esModule', {
value: true
});
};
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
mirrorInstructionsIntoStructuredContent: ()=>mirrorInstructionsIntoStructuredContent,
addInstructionsToOutputSchema: ()=>addInstructionsToOutputSchema,
addInstructionsToOutputSchemas: ()=>addInstructionsToOutputSchemas,
MCP_INSTRUCTIONS_KEY: ()=>MCP_INSTRUCTIONS_KEY,
buildConversationInstructions: ()=>buildConversationInstructions,
canDeclareOutputInstructions: ()=>canDeclareOutputInstructions
});
const external_logger_js_namespaceObject = require("./logger.js");
const MCP_INSTRUCTIONS_KEY = '_mcp_instructions';
const INSTRUCTIONS_FIELD_DESCRIPTION = 'Server-issued handles for this conversation, and what to do with them. Read and follow.';
const CONVERSATION_ID_FIELD_DESCRIPTION = 'Echo this exact value as the conversation_id argument on every subsequent tool call.';
function canDeclareOutputInstructions(outputSchema) {
if (!outputSchema || 'object' != typeof outputSchema) return false;
if (isSchemaObjectLike(outputSchema)) return false;
const schema = outputSchema;
if (schema.$ref || schema.oneOf || schema.allOf || schema.anyOf) return false;
const { properties } = schema;
if (void 0 !== properties && ('object' != typeof properties || null === properties || Array.isArray(properties))) return false;
return !properties || !Object.prototype.hasOwnProperty.call(properties, MCP_INSTRUCTIONS_KEY);
}
function isZodLike(entry) {
return !!entry && 'object' == typeof entry && ('_def' in entry || '_zod' in entry || '~standard' in entry);
}
function looksLikeJsonSchema(candidate) {
if ('string' == typeof candidate.type || 'string' == typeof candidate.$ref) return true;
if (Array.isArray(candidate.oneOf) || Array.isArray(candidate.allOf) || Array.isArray(candidate.anyOf)) return true;
const { properties } = candidate;
return !!properties && 'object' == typeof properties && !isZodLike(properties);
}
function isSchemaObjectLike(value) {
const candidate = value;
if (isZodLike(candidate)) return true;
if (looksLikeJsonSchema(candidate)) return false;
return Object.values(candidate).some(isZodLike);
}
function addInstructionsToOutputSchema(tool, logger = external_logger_js_namespaceObject.log) {
const toolName = tool.name || 'unknown';
const original = tool.outputSchema;
if (!original || 'object' != typeof original) return tool;
if (!canDeclareOutputInstructions(original)) {
const schema = original;
logger(schema.properties && Object.prototype.hasOwnProperty.call(schema.properties, MCP_INSTRUCTIONS_KEY) ? `WARN: Tool "${toolName}" already declares '${MCP_INSTRUCTIONS_KEY}' in its output schema. Leaving it alone.` : `WARN: Tool "${toolName}" has a complex output schema (oneOf/allOf/anyOf/$ref). Skipping '${MCP_INSTRUCTIONS_KEY}' declaration; its session handle stays content-only.`);
return tool;
}
const modifiedTool = {
...tool
};
const outputSchema = JSON.parse(JSON.stringify(original));
if (!outputSchema.properties) outputSchema.properties = {};
outputSchema.properties[MCP_INSTRUCTIONS_KEY] = {
type: 'object',
description: INSTRUCTIONS_FIELD_DESCRIPTION,
properties: {
conversation_id: {
type: 'string',
description: CONVERSATION_ID_FIELD_DESCRIPTION
},
instructions: {
type: 'string'
}
}
};
modifiedTool.outputSchema = outputSchema;
return modifiedTool;
}
function addInstructionsToOutputSchemas(tools, logger = external_logger_js_namespaceObject.log) {
return tools.map((tool)=>addInstructionsToOutputSchema(tool, logger));
}
const ECHO_INSTRUCTION = 'Send this conversation_id as an argument on every subsequent tool call in this conversation.';
function buildConversationInstructions(conversationId) {
return {
conversation_id: conversationId,
instructions: ECHO_INSTRUCTION
};
}
function mirrorInstructionsIntoStructuredContent(result, conversationId) {
if (!result || 'object' != typeof result) return result;
const structuredContent = result.structuredContent;
if (!structuredContent || 'object' != typeof structuredContent || Array.isArray(structuredContent)) return result;
if (Object.prototype.hasOwnProperty.call(structuredContent, MCP_INSTRUCTIONS_KEY)) return result;
return {
...result,
structuredContent: {
...structuredContent,
[MCP_INSTRUCTIONS_KEY]: buildConversationInstructions(conversationId)
}
};
}
exports.MCP_INSTRUCTIONS_KEY = __webpack_exports__.MCP_INSTRUCTIONS_KEY;
exports.addInstructionsToOutputSchema = __webpack_exports__.addInstructionsToOutputSchema;
exports.addInstructionsToOutputSchemas = __webpack_exports__.addInstructionsToOutputSchemas;
exports.buildConversationInstructions = __webpack_exports__.buildConversationInstructions;
exports.canDeclareOutputInstructions = __webpack_exports__.canDeclareOutputInstructions;
exports.mirrorInstructionsIntoStructuredContent = __webpack_exports__.mirrorInstructionsIntoStructuredContent;
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
"MCP_INSTRUCTIONS_KEY",
"addInstructionsToOutputSchema",
"addInstructionsToOutputSchemas",
"buildConversationInstructions",
"canDeclareOutputInstructions",
"mirrorInstructionsIntoStructuredContent"
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
Object.defineProperty(exports, '__esModule', {
value: true
});
import { log } from "./logger.mjs";
const MCP_INSTRUCTIONS_KEY = '_mcp_instructions';
const INSTRUCTIONS_FIELD_DESCRIPTION = 'Server-issued handles for this conversation, and what to do with them. Read and follow.';
const CONVERSATION_ID_FIELD_DESCRIPTION = 'Echo this exact value as the conversation_id argument on every subsequent tool call.';
function canDeclareOutputInstructions(outputSchema) {
if (!outputSchema || 'object' != typeof outputSchema) return false;
if (isSchemaObjectLike(outputSchema)) return false;
const schema = outputSchema;
if (schema.$ref || schema.oneOf || schema.allOf || schema.anyOf) return false;
const { properties } = schema;
if (void 0 !== properties && ('object' != typeof properties || null === properties || Array.isArray(properties))) return false;
return !properties || !Object.prototype.hasOwnProperty.call(properties, MCP_INSTRUCTIONS_KEY);
}
function isZodLike(entry) {
return !!entry && 'object' == typeof entry && ('_def' in entry || '_zod' in entry || '~standard' in entry);
}
function looksLikeJsonSchema(candidate) {
if ('string' == typeof candidate.type || 'string' == typeof candidate.$ref) return true;
if (Array.isArray(candidate.oneOf) || Array.isArray(candidate.allOf) || Array.isArray(candidate.anyOf)) return true;
const { properties } = candidate;
return !!properties && 'object' == typeof properties && !isZodLike(properties);
}
function isSchemaObjectLike(value) {
const candidate = value;
if (isZodLike(candidate)) return true;
if (looksLikeJsonSchema(candidate)) return false;
return Object.values(candidate).some(isZodLike);
}
function addInstructionsToOutputSchema(tool, logger = log) {
const toolName = tool.name || 'unknown';
const original = tool.outputSchema;
if (!original || 'object' != typeof original) return tool;
if (!canDeclareOutputInstructions(original)) {
const schema = original;
logger(schema.properties && Object.prototype.hasOwnProperty.call(schema.properties, MCP_INSTRUCTIONS_KEY) ? `WARN: Tool "${toolName}" already declares '${MCP_INSTRUCTIONS_KEY}' in its output schema. Leaving it alone.` : `WARN: Tool "${toolName}" has a complex output schema (oneOf/allOf/anyOf/$ref). Skipping '${MCP_INSTRUCTIONS_KEY}' declaration; its session handle stays content-only.`);
return tool;
}
const modifiedTool = {
...tool
};
const outputSchema = JSON.parse(JSON.stringify(original));
if (!outputSchema.properties) outputSchema.properties = {};
outputSchema.properties[MCP_INSTRUCTIONS_KEY] = {
type: 'object',
description: INSTRUCTIONS_FIELD_DESCRIPTION,
properties: {
conversation_id: {
type: 'string',
description: CONVERSATION_ID_FIELD_DESCRIPTION
},
instructions: {
type: 'string'
}
}
};
modifiedTool.outputSchema = outputSchema;
return modifiedTool;
}
function addInstructionsToOutputSchemas(tools, logger = log) {
return tools.map((tool)=>addInstructionsToOutputSchema(tool, logger));
}
const ECHO_INSTRUCTION = 'Send this conversation_id as an argument on every subsequent tool call in this conversation.';
function buildConversationInstructions(conversationId) {
return {
conversation_id: conversationId,
instructions: ECHO_INSTRUCTION
};
}
function mirrorInstructionsIntoStructuredContent(result, conversationId) {
if (!result || 'object' != typeof result) return result;
const structuredContent = result.structuredContent;
if (!structuredContent || 'object' != typeof structuredContent || Array.isArray(structuredContent)) return result;
if (Object.prototype.hasOwnProperty.call(structuredContent, MCP_INSTRUCTIONS_KEY)) return result;
return {
...result,
structuredContent: {
...structuredContent,
[MCP_INSTRUCTIONS_KEY]: buildConversationInstructions(conversationId)
}
};
}
export { MCP_INSTRUCTIONS_KEY, addInstructionsToOutputSchema, addInstructionsToOutputSchemas, buildConversationInstructions, canDeclareOutputInstructions, mirrorInstructionsIntoStructuredContent };
import type { LoggerFn } from './logger'
import { log } from './logger'
import type { AnalyticsInjectableJsonSchema } from './analytics-parameters'
/**
* The `conversation_id` session handle reaches the agent as a text block appended to the
* tool result. That block is invisible to any client that reads
* `structuredContent` instead of `content` — which is what clients do whenever a
* tool declares an `outputSchema`. Measured against Claude Code, correlation for
* such tools drops to zero.
*
* The fix is to mirror the session handle into `structuredContent` as well, which this
* module does in two halves that must stay in that order:
*
* 1. declare `_mcp_instructions` on the tool's advertised `outputSchema`
* 2. write it into the result's `structuredContent`
*
* The declaration is what makes the write safe. The MCP client ajv-validates
* `structuredContent` against the schema from `tools/list`, and
* `zod-to-json-schema` emits `additionalProperties: false` for a plain
* `z.object`, so an undeclared key is not ignored — it fails the entire tool
* result. Only tools that got the declaration are ever written to.
*/
export const MCP_INSTRUCTIONS_KEY = '_mcp_instructions'
const INSTRUCTIONS_FIELD_DESCRIPTION =
'Server-issued handles for this conversation, and what to do with them. Read and follow.'
const CONVERSATION_ID_FIELD_DESCRIPTION =
'Echo this exact value as the conversation_id argument on every subsequent tool call.'
export interface OutputInstructionsInjectableTool {
name?: string
outputSchema?: unknown
[key: string]: unknown
}
/**
* True when we can safely declare {@link MCP_INSTRUCTIONS_KEY} on this tool's
* advertised output schema.
*
* Requires a plain-object schema we can extend. A tool with no `outputSchema`
* has nothing to mirror into and keeps working through `content`; a composed
* schema (`oneOf`/`allOf`/`anyOf`/`$ref`) has no single `properties` bag to add
* to. Both stay content-only, matching the policy on the input side.
*/
export function canDeclareOutputInstructions(outputSchema: unknown): boolean {
if (!outputSchema || typeof outputSchema !== 'object') {
return false
}
// Only the JSON Schema a tool advertises can answer this. A Zod schema or raw
// shape — what the high-level registry stores — has no `properties` bag, so
// every check below would pass vacuously and report `true` for a tool whose
// schema we actually skipped. Refuse rather than guess: callers holding a Zod
// value must read the recorded answer off the ownership registry instead.
if (isSchemaObjectLike(outputSchema)) {
return false
}
const schema = outputSchema as AnalyticsInjectableJsonSchema
if (schema.$ref || schema.oneOf || schema.allOf || schema.anyOf) {
return false
}
// `properties` must be a plain object if it is present at all. A tool that
// advertises something else is malformed, and harmlessly so until we try to
// declare into it — assigning a key to a boolean throws, and that throw
// surfaces inside the `tools/list` wrapper, failing the entire listing over a
// schema we only wanted to annotate.
const { properties } = schema
if (
properties !== undefined &&
(typeof properties !== 'object' || properties === null || Array.isArray(properties))
) {
return false
}
return !properties || !Object.prototype.hasOwnProperty.call(properties, MCP_INSTRUCTIONS_KEY)
}
/** A single Zod schema — the internals every version brands its instances with. */
function isZodLike(entry: unknown): boolean {
return !!entry && typeof entry === 'object' && ('_def' in entry || '_zod' in entry || '~standard' in entry)
}
/**
* Whether this is a JSON Schema, judged on the *value* of each marker rather
* than the key alone — a raw Zod shape is free to name a field `type` or
* `properties`, but its values are Zod schemas, not a string and a property bag.
*/
function looksLikeJsonSchema(candidate: Record<string, unknown>): boolean {
if (typeof candidate.type === 'string' || typeof candidate.$ref === 'string') {
return true
}
if (Array.isArray(candidate.oneOf) || Array.isArray(candidate.allOf) || Array.isArray(candidate.anyOf)) {
return true
}
const { properties } = candidate
return !!properties && typeof properties === 'object' && !isZodLike(properties)
}
/** A Zod schema, or a raw shape whose values are Zod schemas. */
function isSchemaObjectLike(value: unknown): boolean {
const candidate = value as Record<string, unknown>
if (isZodLike(candidate)) {
return true
}
// Settle "is this a JSON Schema" before scanning the values, because a schema
// may legitimately declare a property named `_def` — and the scan below would
// read that property's schema object as a Zod value and skip a tool we could
// have annotated perfectly well.
if (looksLikeJsonSchema(candidate)) {
return false
}
return Object.values(candidate).some(isZodLike)
}
/**
* Returns a copy of the tool with an optional {@link MCP_INSTRUCTIONS_KEY}
* property added to its output schema, or the tool untouched when it has no
* output schema to extend.
*
* The property is never added to `required` — a result without it must stay
* valid, since every tool result predating this change lacks it.
*/
export function addInstructionsToOutputSchema<TTool extends OutputInstructionsInjectableTool>(
tool: TTool,
logger: LoggerFn = log
): TTool {
const toolName = tool.name || 'unknown'
const original = tool.outputSchema
// No output schema means the client reads `content`, where the session handle already
// rides. Nothing to declare, and nothing broken.
if (!original || typeof original !== 'object') {
return tool
}
if (!canDeclareOutputInstructions(original)) {
const schema = original as AnalyticsInjectableJsonSchema
if (schema.properties && Object.prototype.hasOwnProperty.call(schema.properties, MCP_INSTRUCTIONS_KEY)) {
logger(
`WARN: Tool "${toolName}" already declares '${MCP_INSTRUCTIONS_KEY}' in its output schema. Leaving it alone.`
)
} else {
logger(
`WARN: Tool "${toolName}" has a complex output schema (oneOf/allOf/anyOf/$ref). Skipping '${MCP_INSTRUCTIONS_KEY}' declaration; its session handle stays content-only.`
)
}
return tool
}
const modifiedTool = { ...tool }
// Deep copy: the server may reuse or freeze the schema object it handed us.
const outputSchema = JSON.parse(JSON.stringify(original)) as AnalyticsInjectableJsonSchema
if (!outputSchema.properties) {
outputSchema.properties = {}
}
outputSchema.properties[MCP_INSTRUCTIONS_KEY] = {
type: 'object',
description: INSTRUCTIONS_FIELD_DESCRIPTION,
properties: {
conversation_id: {
type: 'string',
description: CONVERSATION_ID_FIELD_DESCRIPTION,
},
instructions: { type: 'string' },
},
}
modifiedTool.outputSchema = outputSchema
return modifiedTool
}
/**
* Declares {@link MCP_INSTRUCTIONS_KEY} across a tool listing. Tools without an
* output schema, and tools whose schema we cannot extend, pass through unchanged.
*/
export function addInstructionsToOutputSchemas<TTool extends OutputInstructionsInjectableTool>(
tools: TTool[],
logger: LoggerFn = log
): TTool[] {
return tools.map((tool) => addInstructionsToOutputSchema(tool, logger))
}
export interface ConversationInstructions {
conversation_id: string
instructions: string
}
const ECHO_INSTRUCTION = 'Send this conversation_id as an argument on every subsequent tool call in this conversation.'
/** The payload mirrored into `structuredContent` for a tool we declared the key on. */
export function buildConversationInstructions(conversationId: string): ConversationInstructions {
return { conversation_id: conversationId, instructions: ECHO_INSTRUCTION }
}
/**
* Adds {@link MCP_INSTRUCTIONS_KEY} to a result's `structuredContent`, which is
* where clients look once a tool declares an `outputSchema` — the `content` text
* block carrying the session handle is invisible to them.
*
* Unlike the text block, this rides *every* response rather than only the one
* that minted the session handle, so an agent that drops it can read it back.
*
* Returns the result untouched when there is no plain-object `structuredContent`
* to extend, or when the tool already produced its own key — customer data wins.
* Never mutates the input.
*/
export function mirrorInstructionsIntoStructuredContent(result: unknown, conversationId: string): unknown {
if (!result || typeof result !== 'object') {
return result
}
const structuredContent = (result as { structuredContent?: unknown }).structuredContent
if (!structuredContent || typeof structuredContent !== 'object' || Array.isArray(structuredContent)) {
return result
}
if (Object.prototype.hasOwnProperty.call(structuredContent, MCP_INSTRUCTIONS_KEY)) {
return result
}
return {
...result,
structuredContent: {
...structuredContent,
[MCP_INSTRUCTIONS_KEY]: buildConversationInstructions(conversationId),
},
}
}
+7
-2

@@ -15,4 +15,9 @@ import type { AnalyticsParameterOwnership } from '../types';

export declare function analyticsOwnsParameter(inputSchema: unknown, parameterName: string): boolean;
export declare function getAnalyticsParameterOwnership(inputSchema: unknown): AnalyticsParameterOwnership;
export declare function stripOwnedAnalyticsArguments(args: unknown, ownership: AnalyticsParameterOwnership): unknown;
export declare function getAnalyticsParameterOwnership(inputSchema: unknown, outputSchema?: unknown): AnalyticsParameterOwnership;
/**
* Removes the arguments we injected, leaving the host's own. Input-side only, so
* it takes just those two flags rather than the whole ownership record — callers
* that have no output-schema context should not have to invent a value for it.
*/
export declare function stripOwnedAnalyticsArguments(args: unknown, ownership: Pick<AnalyticsParameterOwnership, 'context' | 'conversationId'>): unknown;
//# sourceMappingURL=analytics-parameters.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"analytics-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/analytics-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAgB3D,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAyB3F;AAED,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,OAAO,GAAG,2BAA2B,CAKhG;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,2BAA2B,GAAG,OAAO,CAW3G"}
{"version":3,"file":"analytics-parameters.d.ts","sourceRoot":"","sources":["../../src/extensions/analytics-parameters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAA;AAiB3D,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,6BAA6B,GAAG,SAAS,EACjD,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAyB3F;AAED,wBAAgB,8BAA8B,CAC5C,WAAW,EAAE,OAAO,EACpB,YAAY,CAAC,EAAE,OAAO,GACrB,2BAA2B,CAM7B;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,IAAI,CAAC,2BAA2B,EAAE,SAAS,GAAG,gBAAgB,CAAC,GACzE,OAAO,CAWT"}

@@ -34,2 +34,3 @@ "use strict";

const external_mcp_sdk_compat_js_namespaceObject = require("./mcp-sdk-compat.js");
const external_output_instructions_js_namespaceObject = require("./output-instructions.js");
const JSON_SCHEMA_KEYWORDS = [

@@ -67,6 +68,7 @@ '$defs',

}
function getAnalyticsParameterOwnership(inputSchema) {
function getAnalyticsParameterOwnership(inputSchema, outputSchema) {
return {
context: analyticsOwnsParameter(inputSchema, 'context'),
conversationId: analyticsOwnsParameter(inputSchema, 'conversation_id')
conversationId: analyticsOwnsParameter(inputSchema, 'conversation_id'),
outputInstructions: (0, external_output_instructions_js_namespaceObject.canDeclareOutputInstructions)(outputSchema)
};

@@ -73,0 +75,0 @@ }

import { getObjectShape, isZodRawShapeCompat } from "./mcp-sdk-compat.mjs";
import { canDeclareOutputInstructions } from "./output-instructions.mjs";
const JSON_SCHEMA_KEYWORDS = [

@@ -34,6 +35,7 @@ '$defs',

}
function getAnalyticsParameterOwnership(inputSchema) {
function getAnalyticsParameterOwnership(inputSchema, outputSchema) {
return {
context: analyticsOwnsParameter(inputSchema, 'context'),
conversationId: analyticsOwnsParameter(inputSchema, 'conversation_id')
conversationId: analyticsOwnsParameter(inputSchema, 'conversation_id'),
outputInstructions: canDeclareOutputInstructions(outputSchema)
};

@@ -40,0 +42,0 @@ }

@@ -10,3 +10,9 @@ import { type AnalyticsInjectableJsonSchema } from './analytics-parameters';

export declare function addConversationIdToTool<TTool extends ConversationIdInjectableTool>(tool: TTool, logger?: LoggerFn): TTool;
export declare function addConversationIdToTools<TTool extends ConversationIdInjectableTool>(tools: TTool[], missingCapabilityToolName?: string, skipMissingCapabilityTool?: boolean, logger?: LoggerFn): TTool[];
/**
* Injects `conversation_id` across a tool listing, including the virtual
* `get_more_tools` tool. Its calls publish `$mcp_missing_capability`, and a
* capability gap is only meaningful next to the work that hit it — so it belongs
* in the same session as the surrounding tool calls.
*/
export declare function addConversationIdToTools<TTool extends ConversationIdInjectableTool>(tools: TTool[], logger?: LoggerFn): TTool[];
export type ConversationIdResolution = {

@@ -21,11 +27,34 @@ minted: false;

* Decides which conversation_id to use for a tool call:
* - disabled or get_more_tools → none
* - agent supplied a value → use it
* - agent omitted → mint a UUID
* - disabled → none
* - agent echoed a handle we could have minted → use it
* - anything else → mint a fresh one
*
* The shape check matters because this value becomes `$session_id`, and the
* derivation is deterministic so that two pods agree — which also means two
* *callers* sending the same string land in the same session. The strings agents
* invent are not random (`conv-1`, `1`, `session`), so trusting them verbatim
* would silently merge unrelated conversations, potentially across users.
*
* A compliant agent echoes the uuidv7 we minted and is unaffected. Anything else
* is treated exactly as if the handle were absent: mint, and prompt back. Shape
* rather than a registry of issued ids, because a per-request server has no
* memory of what it minted.
*
* This narrows the problem, it does not prove provenance: a caller supplying a
* well-formed uuidv7 is trusted, so two that pick the *same* one still merge. That
* residue is far smaller than the case it replaces — an agent ignoring the
* parameter description reaches for `conv-1` or `1`, not a conforming uuidv7 — and
* closing it needs a signed handle, i.e. a secret shared by every pod. Worth doing
* if this ever anchors something security-bearing; `$session_id` is an analytics
* grouping key, so it does not today.
*/
export declare function resolveConversationId(enabled: boolean, args: unknown, toolName: string | undefined, missingCapabilityToolName?: string): ConversationIdResolution;
export declare function resolveConversationId(enabled: boolean, args: unknown): ConversationIdResolution;
/**
* Predicate matching the same eligibility checks injectConversationIdPromptBack uses,
* exposed so callers can pre-decide whether the prompt-back will actually land
* (and clear event.conversationId if not, to avoid orphan ids in analytics).
* Whether the prompt-back can ride this result's `content`. The only requirement
* is an array to append to.
*
* Errored results included on purpose. A tool that fails on the first call of a
* conversation is exactly when the agent needs the session handle: without it the
* retry starts a fresh conversation, so the failure and its fix land in different
* sessions.
*/

@@ -32,0 +61,0 @@ export declare function canInjectConversationIdPromptBack(result: unknown): boolean;

@@ -1,1 +0,1 @@

{"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAG7C,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,6BAA6B,CAAA;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAChF,IAAI,EAAE,KAAK,EACX,MAAM,GAAE,QAAc,GACrB,KAAK,CA4CP;AAED,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,EACjF,KAAK,EAAE,KAAK,EAAE,EACd,yBAAyB,GAAE,MAA4B,EACvD,yBAAyB,UAAO,EAChC,MAAM,GAAE,QAAc,GACrB,KAAK,EAAE,CAOT;AAED,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,yBAAyB,GAAE,MAA4B,GACtD,wBAAwB,CAS1B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAS1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAKA;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAS/F"}
{"version":3,"file":"conversation-id.d.ts","sourceRoot":"","sources":["../../src/extensions/conversation-id.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAE7C,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,6BAA6B,CAAA;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,4BAA4B,EAChF,IAAI,EAAE,KAAK,EACX,MAAM,GAAE,QAAc,GACrB,KAAK,CA4CP;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,SAAS,4BAA4B,EACjF,KAAK,EAAE,KAAK,EAAE,EACd,MAAM,GAAE,QAAc,GACrB,KAAK,EAAE,CAET;AAQD,MAAM,MAAM,wBAAwB,GAChC;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACrD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,wBAAwB,CAa/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAK1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUvE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAM1D;AAED,wBAAgB,6BAA6B,CAAC,cAAc,EAAE,MAAM,GAAG;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAKA;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAS/F"}

@@ -41,3 +41,2 @@ "use strict";

const external_logger_js_namespaceObject = require("./logger.js");
const external_tools_js_namespaceObject = require("./tools.js");
const CONVERSATION_ID_PARAM_NAME = 'conversation_id';

@@ -69,10 +68,8 @@ function addConversationIdToTool(tool, logger = external_logger_js_namespaceObject.log) {

}
function addConversationIdToTools(tools, missingCapabilityToolName = external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME, skipMissingCapabilityTool = true, logger = external_logger_js_namespaceObject.log) {
return tools.map((tool)=>{
if (skipMissingCapabilityTool && tool.name === missingCapabilityToolName) return tool;
return addConversationIdToTool(tool, logger);
});
function addConversationIdToTools(tools, logger = external_logger_js_namespaceObject.log) {
return tools.map((tool)=>addConversationIdToTool(tool, logger));
}
function resolveConversationId(enabled, args, toolName, missingCapabilityToolName = external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME) {
if (!enabled || toolName === missingCapabilityToolName) return {
const MINTED_CONVERSATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
function resolveConversationId(enabled, args) {
if (!enabled) return {
minted: false,

@@ -82,5 +79,5 @@ conversationId: void 0

const supplied = extractConversationId(args);
if (supplied) return {
if (supplied && MINTED_CONVERSATION_ID.test(supplied)) return {
minted: false,
conversationId: supplied
conversationId: supplied.toLowerCase()
};

@@ -94,5 +91,3 @@ return {

if (!(result && 'object' == typeof result)) return false;
const resultObj = result;
if (true === resultObj.isError) return false;
return Array.isArray(resultObj.content);
return Array.isArray(result.content);
}

@@ -99,0 +94,0 @@ function extractConversationId(args) {

@@ -5,3 +5,2 @@ import { uuidv7 } from "@posthog/core";

import { log } from "./logger.mjs";
import { GET_MORE_TOOLS_NAME } from "./tools.mjs";
const CONVERSATION_ID_PARAM_NAME = 'conversation_id';

@@ -33,10 +32,8 @@ function addConversationIdToTool(tool, logger = log) {

}
function addConversationIdToTools(tools, missingCapabilityToolName = GET_MORE_TOOLS_NAME, skipMissingCapabilityTool = true, logger = log) {
return tools.map((tool)=>{
if (skipMissingCapabilityTool && tool.name === missingCapabilityToolName) return tool;
return addConversationIdToTool(tool, logger);
});
function addConversationIdToTools(tools, logger = log) {
return tools.map((tool)=>addConversationIdToTool(tool, logger));
}
function resolveConversationId(enabled, args, toolName, missingCapabilityToolName = GET_MORE_TOOLS_NAME) {
if (!enabled || toolName === missingCapabilityToolName) return {
const MINTED_CONVERSATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
function resolveConversationId(enabled, args) {
if (!enabled) return {
minted: false,

@@ -46,5 +43,5 @@ conversationId: void 0

const supplied = extractConversationId(args);
if (supplied) return {
if (supplied && MINTED_CONVERSATION_ID.test(supplied)) return {
minted: false,
conversationId: supplied
conversationId: supplied.toLowerCase()
};

@@ -58,5 +55,3 @@ return {

if (!(result && 'object' == typeof result)) return false;
const resultObj = result;
if (true === resultObj.isError) return false;
return Array.isArray(resultObj.content);
return Array.isArray(result.content);
}

@@ -63,0 +58,0 @@ function extractConversationId(args) {

@@ -1,1 +0,1 @@

{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;AASjB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AA8PxC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CA2BhG"}
{"version":3,"file":"instrument-highlevel.d.ts","sourceRoot":"","sources":["../../src/extensions/instrument-highlevel.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,sBAAsB,EAIvB,MAAM,UAAU,CAAA;AASjB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAgQxC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CA2BhG"}

@@ -180,3 +180,3 @@ "use strict";

execute: (downstreamRequest)=>originalCallToolHandler(downstreamRequest, extra),
parameterOwnership: registeredTool ? (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(registeredTool.inputSchema) : void 0,
parameterOwnership: registeredTool ? (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(registeredTool.inputSchema, registeredTool.outputSchema) : void 0,
takeCapturedError: ()=>{

@@ -183,0 +183,0 @@ const captured = extra?.__mcp_analytics_error;

@@ -152,3 +152,3 @@ import { analyticsOwnsParameter, getAnalyticsParameterOwnership, stripOwnedAnalyticsArguments } from "./analytics-parameters.mjs";

execute: (downstreamRequest)=>originalCallToolHandler(downstreamRequest, extra),
parameterOwnership: registeredTool ? getAnalyticsParameterOwnership(registeredTool.inputSchema) : void 0,
parameterOwnership: registeredTool ? getAnalyticsParameterOwnership(registeredTool.inputSchema, registeredTool.outputSchema) : void 0,
takeCapturedError: ()=>{

@@ -155,0 +155,0 @@ const captured = extra?.__mcp_analytics_error;

@@ -1,1 +0,1 @@

{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../../src/extensions/instrumentation.ts"],"names":[],"mappings":"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"}

@@ -40,2 +40,3 @@ "use strict";

const external_client_identity_js_namespaceObject = require("./client-identity.js");
const external_output_instructions_js_namespaceObject = require("./output-instructions.js");
const external_capture_js_namespaceObject = require("./capture.js");

@@ -56,3 +57,3 @@ const external_event_types_js_namespaceObject = require("./event-types.js");

const ownership = getActiveAnalyticsParameterOwnership(data, request.params?.name, parameterOwnership, resolvedEventType === external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpMissingCapability);
const conversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(ownership.conversationId, request.params?.arguments, request.params?.name, resolvedEventType === external_event_types_js_namespaceObject.MCPAnalyticsEventType.mcpMissingCapability ? (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options) : '');
const conversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(ownership.conversationId, request.params?.arguments);
const downstreamRequest = cloneRequestWithoutOwnedAnalyticsArguments(request, ownership);

@@ -69,3 +70,3 @@ const startTime = new Date();

}
const finalResult = applyConversationPromptBack(preparedEvent?.event ?? null, result, conversation);
const finalResult = applyConversationInstructions(preparedEvent?.event ?? null, result, conversation, ownership);
publishSuccessfulToolEvent(server, preparedEvent, finalResult, startTime, data.logger, takeCapturedError);

@@ -75,6 +76,8 @@ return finalResult;

function getActiveAnalyticsParameterOwnership(data, toolName, override, isMissingCapabilityTool) {
const ownership = override ?? (toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : void 0);
const listed = toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : void 0;
const ownership = override ?? listed;
return {
context: !isMissingCapabilityTool && (0, external_context_parameters_js_namespaceObject.isContextEnabled)(data.options.context) && ownership?.context === true,
conversationId: !isMissingCapabilityTool && true === data.options.enableConversationId && ownership?.conversationId === true
conversationId: true === data.options.enableConversationId && ownership?.conversationId === true,
outputInstructions: true === data.options.enableConversationId && listed?.outputInstructions === true
};

@@ -96,5 +99,5 @@ }

try {
const sessionId = (0, external_session_js_namespaceObject.getSessionId)(server, extra);
const sessionId = (0, external_session_js_namespaceObject.getSessionId)(server, extra, conversation.conversationId);
const sessionInfo = (0, external_session_js_namespaceObject.getSessionInfo)(server, data, sessionId);
const identity = await (0, external_internal_js_namespaceObject.handleIdentify)(server, data, sessionId, request, sessionInfo, extra);
const identity = await (0, external_internal_js_namespaceObject.handleIdentify)(server, data, sessionId, request, sessionInfo, extra, !!conversation.conversationId);
const requestAttribution = (0, external_internal_js_namespaceObject.withIdentity)(sessionInfo, identity);

@@ -124,7 +127,18 @@ const toolName = request.params?.name;

}
function applyConversationPromptBack(event, result, conversation) {
if (!conversation.minted) return result;
if ((0, external_conversation_id_js_namespaceObject.canInjectConversationIdPromptBack)(result)) return (0, external_conversation_id_js_namespaceObject.injectConversationIdPromptBack)(result, conversation.conversationId);
if (event) event.conversationId = void 0;
return result;
function applyConversationInstructions(event, result, conversation, ownership) {
const conversationId = conversation.conversationId;
if (!conversationId) return result;
let updated = result;
let delivered = false;
if (ownership.outputInstructions) {
const mirrored = (0, external_output_instructions_js_namespaceObject.mirrorInstructionsIntoStructuredContent)(updated, conversationId);
delivered = mirrored !== updated;
updated = mirrored;
}
if (conversation.minted && (0, external_conversation_id_js_namespaceObject.canInjectConversationIdPromptBack)(updated)) {
updated = (0, external_conversation_id_js_namespaceObject.injectConversationIdPromptBack)(updated, conversationId);
delivered = true;
}
if (!delivered && conversation.minted && event) event.conversationId = void 0;
return updated;
}

@@ -249,3 +263,3 @@ function publishSuccessfulToolEvent(server, preparedEvent, result, startTime, logger, takeCapturedError) {

function cacheToolAnalyticsParameterOwnership(cache, tools) {
for (const tool of tools)if (tool?.name) cache.set(tool.name, (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(tool.inputSchema));
for (const tool of tools)if (tool?.name) cache.set(tool.name, (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(tool.inputSchema, tool.outputSchema));
}

@@ -268,3 +282,2 @@ function collectListedToolNames(tools) {

const missingToolName = (0, external_tools_js_namespaceObject.resolveMissingCapabilityToolName)(data.options);
let injectedMissingCapabilityTool = false;
if (data.options.reportMissing) {

@@ -274,7 +287,13 @@ const alreadyPresent = tools.some((tool)=>tool?.name === missingToolName);

else {
tools.push((0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(missingToolName));
injectedMissingCapabilityTool = true;
const virtualTool = (0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(missingToolName);
tools.push(virtualTool);
cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [
virtualTool
]);
}
}
if (data.options.enableConversationId) tools = (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)(tools, missingToolName, injectedMissingCapabilityTool, data.logger);
if (data.options.enableConversationId) {
tools = (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)(tools, data.logger);
tools = (0, external_output_instructions_js_namespaceObject.addInstructionsToOutputSchemas)(tools, data.logger);
}
}

@@ -281,0 +300,0 @@ if (data) {

@@ -5,2 +5,3 @@ import { getAnalyticsParameterOwnership, stripOwnedAnalyticsArguments } from "./analytics-parameters.mjs";

import { stampMetaClientInfo } from "./client-identity.mjs";
import { addInstructionsToOutputSchemas, mirrorInstructionsIntoStructuredContent } from "./output-instructions.mjs";
import { captureEvent } from "./capture.mjs";

@@ -21,3 +22,3 @@ import { MCPAnalyticsEventType } from "./event-types.mjs";

const ownership = getActiveAnalyticsParameterOwnership(data, request.params?.name, parameterOwnership, resolvedEventType === MCPAnalyticsEventType.mcpMissingCapability);
const conversation = resolveConversationId(ownership.conversationId, request.params?.arguments, request.params?.name, resolvedEventType === MCPAnalyticsEventType.mcpMissingCapability ? resolveMissingCapabilityToolName(data.options) : '');
const conversation = resolveConversationId(ownership.conversationId, request.params?.arguments);
const downstreamRequest = cloneRequestWithoutOwnedAnalyticsArguments(request, ownership);

@@ -34,3 +35,3 @@ const startTime = new Date();

}
const finalResult = applyConversationPromptBack(preparedEvent?.event ?? null, result, conversation);
const finalResult = applyConversationInstructions(preparedEvent?.event ?? null, result, conversation, ownership);
publishSuccessfulToolEvent(server, preparedEvent, finalResult, startTime, data.logger, takeCapturedError);

@@ -40,6 +41,8 @@ return finalResult;

function getActiveAnalyticsParameterOwnership(data, toolName, override, isMissingCapabilityTool) {
const ownership = override ?? (toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : void 0);
const listed = toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : void 0;
const ownership = override ?? listed;
return {
context: !isMissingCapabilityTool && isContextEnabled(data.options.context) && ownership?.context === true,
conversationId: !isMissingCapabilityTool && true === data.options.enableConversationId && ownership?.conversationId === true
conversationId: true === data.options.enableConversationId && ownership?.conversationId === true,
outputInstructions: true === data.options.enableConversationId && listed?.outputInstructions === true
};

@@ -61,5 +64,5 @@ }

try {
const sessionId = getSessionId(server, extra);
const sessionId = getSessionId(server, extra, conversation.conversationId);
const sessionInfo = getSessionInfo(server, data, sessionId);
const identity = await handleIdentify(server, data, sessionId, request, sessionInfo, extra);
const identity = await handleIdentify(server, data, sessionId, request, sessionInfo, extra, !!conversation.conversationId);
const requestAttribution = withIdentity(sessionInfo, identity);

@@ -89,7 +92,18 @@ const toolName = request.params?.name;

}
function applyConversationPromptBack(event, result, conversation) {
if (!conversation.minted) return result;
if (canInjectConversationIdPromptBack(result)) return injectConversationIdPromptBack(result, conversation.conversationId);
if (event) event.conversationId = void 0;
return result;
function applyConversationInstructions(event, result, conversation, ownership) {
const conversationId = conversation.conversationId;
if (!conversationId) return result;
let updated = result;
let delivered = false;
if (ownership.outputInstructions) {
const mirrored = mirrorInstructionsIntoStructuredContent(updated, conversationId);
delivered = mirrored !== updated;
updated = mirrored;
}
if (conversation.minted && canInjectConversationIdPromptBack(updated)) {
updated = injectConversationIdPromptBack(updated, conversationId);
delivered = true;
}
if (!delivered && conversation.minted && event) event.conversationId = void 0;
return updated;
}

@@ -214,3 +228,3 @@ function publishSuccessfulToolEvent(server, preparedEvent, result, startTime, logger, takeCapturedError) {

function cacheToolAnalyticsParameterOwnership(cache, tools) {
for (const tool of tools)if (tool?.name) cache.set(tool.name, getAnalyticsParameterOwnership(tool.inputSchema));
for (const tool of tools)if (tool?.name) cache.set(tool.name, getAnalyticsParameterOwnership(tool.inputSchema, tool.outputSchema));
}

@@ -233,3 +247,2 @@ function collectListedToolNames(tools) {

const missingToolName = resolveMissingCapabilityToolName(data.options);
let injectedMissingCapabilityTool = false;
if (data.options.reportMissing) {

@@ -239,7 +252,13 @@ const alreadyPresent = tools.some((tool)=>tool?.name === missingToolName);

else {
tools.push(getReportMissingToolDescriptor(missingToolName));
injectedMissingCapabilityTool = true;
const virtualTool = getReportMissingToolDescriptor(missingToolName);
tools.push(virtualTool);
cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [
virtualTool
]);
}
}
if (data.options.enableConversationId) tools = addConversationIdToTools(tools, missingToolName, injectedMissingCapabilityTool, data.logger);
if (data.options.enableConversationId) {
tools = addConversationIdToTools(tools, data.logger);
tools = addInstructionsToOutputSchemas(tools, data.logger);
}
}

@@ -246,0 +265,0 @@ if (data) {

@@ -27,3 +27,10 @@ import type { CompatibleRequestHandlerExtra, MCPAnalyticsData, MCPRequestLike, MCPServerLike, SessionInfo, UserIdentity } from '../types';

*/
export declare function handleIdentify(server: MCPServerLike, data: MCPAnalyticsData, sessionId: string, request: MCPRequestLike, requestAttribution: SessionInfo, extra?: CompatibleRequestHandlerExtra): Promise<UserIdentity | undefined>;
export declare function handleIdentify(server: MCPServerLike, data: MCPAnalyticsData, sessionId: string, request: MCPRequestLike, requestAttribution: SessionInfo, extra?: CompatibleRequestHandlerExtra,
/**
* True when this session id came from an agent-carried `conversation_id`
* rather than the transport. Such a session is brand new and was never
* announced at `initialize`, whatever `data.sessionSource` still says about
* the connection.
*/
sessionFromConversation?: boolean): Promise<UserIdentity | undefined>;
export declare function withIdentity(sessionInfo: SessionInfo, identity: UserIdentity | undefined): SessionInfo;

@@ -30,0 +37,0 @@ /**

@@ -1,1 +0,1 @@

{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/extensions/internal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,cAAc,EACd,aAAa,EAEb,WAAW,EACX,YAAY,EACb,MAAM,UAAU,CAAA;AAKjB;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,OAAO,SAAO;IAI1B,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWhD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAapD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B,IAAI,IAAI,MAAM;CAGf;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA4B5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAapG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,kBAAkB,EAAE,WAAW,EAC/B,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAsDnC;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAOtG;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAUzC"}
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/extensions/internal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,cAAc,EACd,aAAa,EAEb,WAAW,EACX,YAAY,EACb,MAAM,UAAU,CAAA;AAKjB;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,OAAO,SAAO;IAI1B,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWhD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAapD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B,IAAI,IAAI,MAAM;CAGf;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA4B5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAapG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,kBAAkB,EAAE,WAAW,EAC/B,KAAK,CAAC,EAAE,6BAA6B;AACrC;;;;;GAKG;AACH,uBAAuB,UAAQ,GAC9B,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuDnC;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAOtG;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAUzC"}

@@ -98,3 +98,3 @@ "use strict";

}
async function handleIdentify(server, data, sessionId, request, requestAttribution, extra) {
async function handleIdentify(server, data, sessionId, request, requestAttribution, extra, sessionFromConversation = false) {
const identityBeforeRequest = data.identifiedSessions.get(sessionId);

@@ -121,3 +121,3 @@ const sessionSourceBeforeIdentify = data.sessionSource;

const firstSeen = void 0 === previousIdentity;
const announcedAtInitialize = 'token' === sessionSourceBeforeIdentify && 'initialize' !== request.method;
const announcedAtInitialize = !sessionFromConversation && 'token' === sessionSourceBeforeIdentify && 'initialize' !== request.method;
const shouldPublish = changed || firstSeen && !announcedAtInitialize;

@@ -124,0 +124,0 @@ data.identifiedSessions.set(sessionId, mergedIdentity);

@@ -63,3 +63,3 @@ import { MCPAnalyticsEventType } from "./event-types.mjs";

}
async function handleIdentify(server, data, sessionId, request, requestAttribution, extra) {
async function handleIdentify(server, data, sessionId, request, requestAttribution, extra, sessionFromConversation = false) {
const identityBeforeRequest = data.identifiedSessions.get(sessionId);

@@ -86,3 +86,3 @@ const sessionSourceBeforeIdentify = data.sessionSource;

const firstSeen = void 0 === previousIdentity;
const announcedAtInitialize = 'token' === sessionSourceBeforeIdentify && 'initialize' !== request.method;
const announcedAtInitialize = !sessionFromConversation && 'token' === sessionSourceBeforeIdentify && 'initialize' !== request.method;
const shouldPublish = changed || firstSeen && !announcedAtInitialize;

@@ -89,0 +89,0 @@ data.identifiedSessions.set(sessionId, mergedIdentity);

@@ -9,9 +9,30 @@ import type { CompatibleRequestHandlerExtra, MCPAnalyticsData, MCPServerLike, SessionInfo } from '../types';

/**
* Resolves the session id for a request: from the replayed session token, from
* the transport's MCP session id, or — when the request carries nothing — from
* this instance's memory. Also saves the token's client name/version so events
* built later in the request can use them (see getSessionInfo).
* Derives the SDK session id from the agent's conversation handle. Deterministic
* and unsalted on purpose: two pods that never met must agree on the session, and
* the 2026-07-28 revision leaves them no shared state to agree through.
*
* Hashed rather than used verbatim so an MCP session can never collide with a
* Session Replay id — a bare uuidv7 would render a "View recording" button that
* resolves to nothing.
*
* Exported because this *is* the cross-SDK contract: posthog-python has to
* reproduce it byte for byte or the same conversation splits into two sessions
* depending on which SDK served the call.
*/
export declare function getSessionId(server: MCPServerLike, extra?: CompatibleRequestHandlerExtra): string;
export declare function deriveSessionIdFromConversation(conversationId: string): string;
/**
* Resolves the session id for a request. Three steps, first match wins:
*
* 1. the agent carried a `conversation_id` tool argument — 2026-07-28
* 2. the request carried a session id — 2025-11-25
* 3. nothing was carried, so reuse this instance's own id — stdio
*
* The split mirrors the two protocol revisions. 2026-07-28 removed protocol-level
* sessions, so the only thing that can carry a session across calls is the agent
* itself (1). 2025-11-25 kept the session on the connection, so the request
* carries it (2). 3 is for stdio, where neither applies — there is no
* HTTP request to carry anything, and no agent handle unless the host opted in.
*/
export declare function getSessionId(server: MCPServerLike, extra?: CompatibleRequestHandlerExtra, conversationId?: string): string;
/**
* Builds the session metadata stamped onto an event. The caller passes the

@@ -18,0 +39,0 @@ * session id resolved for *this* request so identity attribution can't be

@@ -1,1 +0,1 @@

{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/extensions/session.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,UAAU,CAAA;AAMjB,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,6BAA6B,GAAG,MAAM,CAgCjG;AAgBD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GAAG,SAAS,EAClC,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,CAmCb"}
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/extensions/session.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,aAAa,EAEb,WAAW,EACZ,MAAM,UAAU,CAAA;AAOjB,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,aAAa,EACrB,KAAK,CAAC,EAAE,6BAA6B,EACrC,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CA0CR;AA4ED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,GAAG,SAAS,EAClC,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,CAmCb"}

@@ -27,2 +27,3 @@ "use strict";

__webpack_require__.d(__webpack_exports__, {
deriveSessionIdFromConversation: ()=>deriveSessionIdFromConversation,
getSessionId: ()=>getSessionId,

@@ -44,18 +45,14 @@ deriveSessionIdFromMCPSession: ()=>deriveSessionIdFromMCPSession,

}
function getSessionId(server, extra) {
function deriveSessionIdFromConversation(conversationId) {
return (0, external_ids_js_namespaceObject.deterministicPrefixedId)('ses', conversationId);
}
function getSessionId(server, extra, conversationId) {
const data = (0, external_internal_js_namespaceObject.getServerTrackingData)(server);
if (!data) throw new Error('Server tracking data not found');
const sessionHeader = (0, external_session_token_js_namespaceObject.readMcpSessionHeader)(extra?.requestInfo?.headers);
const token = (0, external_session_token_js_namespaceObject.decodeSessionId)(sessionHeader);
let sessionId;
if (token) {
data.sessionSource = 'token';
data.sessionInfo.clientName = token.clientName;
data.sessionInfo.clientVersion = token.clientVersion;
data.sessionInfo.protocolVersion = token.protocolVersion;
sessionId = token.sessionId;
} else if (extra?.sessionId) {
data.sessionSource = 'mcp';
sessionId = deriveSessionIdFromMCPSession(extra.sessionId);
} else sessionId = getSessionIdFromMemory(data);
if (conversationId) {
applyTokenClientIdentity(data, extra);
return deriveSessionIdFromConversation(conversationId);
}
const carriedByRequest = readSessionIdFromRequest(data, extra);
const sessionId = carriedByRequest ?? getSessionIdFromMemory(data);
data.sessionId = sessionId;

@@ -66,2 +63,21 @@ data.lastActivity = new Date();

}
function applyTokenClientIdentity(data, extra) {
const token = (0, external_session_token_js_namespaceObject.decodeSessionId)((0, external_session_token_js_namespaceObject.readMcpSessionHeader)(extra?.requestInfo?.headers));
if (!token) return;
data.sessionInfo.clientName = token.clientName;
data.sessionInfo.clientVersion = token.clientVersion;
data.sessionInfo.protocolVersion = token.protocolVersion;
return token;
}
function readSessionIdFromRequest(data, extra) {
const token = applyTokenClientIdentity(data, extra);
if (token) {
data.sessionSource = 'token';
return token.sessionId;
}
if (extra?.sessionId) {
data.sessionSource = 'mcp';
return deriveSessionIdFromMCPSession(extra.sessionId);
}
}
function getSessionIdFromMemory(data) {

@@ -100,2 +116,3 @@ const timeoutMs = 60 * external_constants_js_namespaceObject.INACTIVITY_TIMEOUT_IN_MINUTES * 1000;

}
exports.deriveSessionIdFromConversation = __webpack_exports__.deriveSessionIdFromConversation;
exports.deriveSessionIdFromMCPSession = __webpack_exports__.deriveSessionIdFromMCPSession;

@@ -106,2 +123,3 @@ exports.getSessionId = __webpack_exports__.getSessionId;

for(var __webpack_i__ in __webpack_exports__)if (-1 === [
"deriveSessionIdFromConversation",
"deriveSessionIdFromMCPSession",

@@ -108,0 +126,0 @@ "getSessionId",

@@ -12,18 +12,14 @@ import { version } from "../version.mjs";

}
function getSessionId(server, extra) {
function deriveSessionIdFromConversation(conversationId) {
return deterministicPrefixedId('ses', conversationId);
}
function getSessionId(server, extra, conversationId) {
const data = getServerTrackingData(server);
if (!data) throw new Error('Server tracking data not found');
const sessionHeader = readMcpSessionHeader(extra?.requestInfo?.headers);
const token = decodeSessionId(sessionHeader);
let sessionId;
if (token) {
data.sessionSource = 'token';
data.sessionInfo.clientName = token.clientName;
data.sessionInfo.clientVersion = token.clientVersion;
data.sessionInfo.protocolVersion = token.protocolVersion;
sessionId = token.sessionId;
} else if (extra?.sessionId) {
data.sessionSource = 'mcp';
sessionId = deriveSessionIdFromMCPSession(extra.sessionId);
} else sessionId = getSessionIdFromMemory(data);
if (conversationId) {
applyTokenClientIdentity(data, extra);
return deriveSessionIdFromConversation(conversationId);
}
const carriedByRequest = readSessionIdFromRequest(data, extra);
const sessionId = carriedByRequest ?? getSessionIdFromMemory(data);
data.sessionId = sessionId;

@@ -34,2 +30,21 @@ data.lastActivity = new Date();

}
function applyTokenClientIdentity(data, extra) {
const token = decodeSessionId(readMcpSessionHeader(extra?.requestInfo?.headers));
if (!token) return;
data.sessionInfo.clientName = token.clientName;
data.sessionInfo.clientVersion = token.clientVersion;
data.sessionInfo.protocolVersion = token.protocolVersion;
return token;
}
function readSessionIdFromRequest(data, extra) {
const token = applyTokenClientIdentity(data, extra);
if (token) {
data.sessionSource = 'token';
return token.sessionId;
}
if (extra?.sessionId) {
data.sessionSource = 'mcp';
return deriveSessionIdFromMCPSession(extra.sessionId);
}
}
function getSessionIdFromMemory(data) {

@@ -68,2 +83,2 @@ const timeoutMs = 60 * INACTIVITY_TIMEOUT_IN_MINUTES * 1000;

}
export { deriveSessionIdFromMCPSession, getSessionId, getSessionInfo, newSessionId };
export { deriveSessionIdFromConversation, deriveSessionIdFromMCPSession, getSessionId, getSessionInfo, newSessionId };

@@ -49,3 +49,17 @@ import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';

missingCapabilityToolName?: string;
/** Enables the `conversation_id` tool parameter + prompt-back loop. */
/**
* Opt in to session correlation for the MCP **2026-07-28** revision, which removed
* protocol-level sessions: no `initialize`, no `mcp-session-id` header, and a fresh
* server instance per HTTP request. With none of those left to anchor on, the only
* thing that can carry a session across calls is the agent itself.
*
* Turning this on injects a `conversation_id` parameter into every tool, mints one
* on the first call, asks the agent to echo it back, and derives `$session_id` from
* that handle — so calls correlate across reconnects, restarts, and per-request
* instances.
*
* Off by default, and fully inert when off: no parameter is injected, no schema is
* touched, no prompt-back is appended, and `$session_id` resolves exactly as it did
* before (the request's own session id, else this instance's).
*/
enableConversationId?: boolean;

@@ -100,2 +114,4 @@ /**

inputSchema?: unknown;
/** Present when the tool was registered with a declared output schema. */
outputSchema?: unknown;
update?: (...args: unknown[]) => unknown;

@@ -248,2 +264,8 @@ } & ({

conversationId: boolean;
/**
* True when we declared `_mcp_instructions` on this tool's advertised output
* schema, so writing that key into `structuredContent` will validate. False
* for tools with no output schema, or one we could not extend.
*/
outputInstructions: boolean;
}

@@ -250,0 +272,0 @@ export interface MCPAnalyticsData {

@@ -1,1 +0,1 @@

{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}

@@ -1,2 +0,2 @@

export declare const version = "0.10.7";
export declare const version = "0.10.8";
//# sourceMappingURL=version.d.ts.map

@@ -29,3 +29,3 @@ "use strict";

});
const version = '0.10.7';
const version = '0.10.8';
exports.version = __webpack_exports__.version;

@@ -32,0 +32,0 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [

@@ -1,2 +0,2 @@

const version = '0.10.7';
const version = '0.10.8';
export { version };
{
"name": "@posthog/mcp",
"version": "0.10.7",
"version": "0.10.8",
"bugs": {

@@ -31,3 +31,3 @@ "url": "https://github.com/PostHog/posthog-js/issues"

"dependencies": {
"@posthog/core": "^1.46.6"
"@posthog/core": "^1.46.9"
},

@@ -43,4 +43,4 @@ "devDependencies": {

"zod": "^3.25.0",
"@posthog-tooling/tsconfig-base": "1.1.1",
"posthog-node": "^5.47.9"
"posthog-node": "^5.48.1",
"@posthog-tooling/tsconfig-base": "1.1.1"
},

@@ -47,0 +47,0 @@ "peerDependencies": {

import type { AnalyticsParameterOwnership } from '../types'
import { getObjectShape, isZodRawShapeCompat } from './mcp-sdk-compat'
import { canDeclareOutputInstructions } from './output-instructions'

@@ -71,10 +72,22 @@ const JSON_SCHEMA_KEYWORDS = [

export function getAnalyticsParameterOwnership(inputSchema: unknown): AnalyticsParameterOwnership {
export function getAnalyticsParameterOwnership(
inputSchema: unknown,
outputSchema?: unknown
): AnalyticsParameterOwnership {
return {
context: analyticsOwnsParameter(inputSchema, 'context'),
conversationId: analyticsOwnsParameter(inputSchema, 'conversation_id'),
outputInstructions: canDeclareOutputInstructions(outputSchema),
}
}
export function stripOwnedAnalyticsArguments(args: unknown, ownership: AnalyticsParameterOwnership): unknown {
/**
* Removes the arguments we injected, leaving the host's own. Input-side only, so
* it takes just those two flags rather than the whole ownership record — callers
* that have no output-schema context should not have to invent a value for it.
*/
export function stripOwnedAnalyticsArguments(
args: unknown,
ownership: Pick<AnalyticsParameterOwnership, 'context' | 'conversationId'>
): unknown {
let cleanedArgs = args

@@ -81,0 +94,0 @@ if (ownership.context && cleanedArgs && typeof cleanedArgs === 'object' && 'context' in cleanedArgs) {

@@ -14,3 +14,2 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

import { log, type LoggerFn } from './logger'
import { GET_MORE_TOOLS_NAME } from './tools'

@@ -74,16 +73,21 @@ export const CONVERSATION_ID_PARAM_NAME = 'conversation_id'

/**
* Injects `conversation_id` across a tool listing, including the virtual
* `get_more_tools` tool. Its calls publish `$mcp_missing_capability`, and a
* capability gap is only meaningful next to the work that hit it — so it belongs
* in the same session as the surrounding tool calls.
*/
export function addConversationIdToTools<TTool extends ConversationIdInjectableTool>(
tools: TTool[],
missingCapabilityToolName: string = GET_MORE_TOOLS_NAME,
skipMissingCapabilityTool = true,
logger: LoggerFn = log
): TTool[] {
return tools.map((tool) => {
if (skipMissingCapabilityTool && tool.name === missingCapabilityToolName) {
return tool
}
return addConversationIdToTool(tool, logger)
})
return tools.map((tool) => addConversationIdToTool(tool, logger))
}
/**
* The shape of every id we mint: a uuidv7. Used to tell an echo of our own handle
* from a value the agent made up.
*/
const MINTED_CONVERSATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
export type ConversationIdResolution =

@@ -95,18 +99,36 @@ | { minted: false; conversationId: string | undefined }

* Decides which conversation_id to use for a tool call:
* - disabled or get_more_tools → none
* - agent supplied a value → use it
* - agent omitted → mint a UUID
* - disabled → none
* - agent echoed a handle we could have minted → use it
* - anything else → mint a fresh one
*
* The shape check matters because this value becomes `$session_id`, and the
* derivation is deterministic so that two pods agree — which also means two
* *callers* sending the same string land in the same session. The strings agents
* invent are not random (`conv-1`, `1`, `session`), so trusting them verbatim
* would silently merge unrelated conversations, potentially across users.
*
* A compliant agent echoes the uuidv7 we minted and is unaffected. Anything else
* is treated exactly as if the handle were absent: mint, and prompt back. Shape
* rather than a registry of issued ids, because a per-request server has no
* memory of what it minted.
*
* This narrows the problem, it does not prove provenance: a caller supplying a
* well-formed uuidv7 is trusted, so two that pick the *same* one still merge. That
* residue is far smaller than the case it replaces — an agent ignoring the
* parameter description reaches for `conv-1` or `1`, not a conforming uuidv7 — and
* closing it needs a signed handle, i.e. a secret shared by every pod. Worth doing
* if this ever anchors something security-bearing; `$session_id` is an analytics
* grouping key, so it does not today.
*/
export function resolveConversationId(
enabled: boolean,
args: unknown,
toolName: string | undefined,
missingCapabilityToolName: string = GET_MORE_TOOLS_NAME
): ConversationIdResolution {
if (!enabled || toolName === missingCapabilityToolName) {
export function resolveConversationId(enabled: boolean, args: unknown): ConversationIdResolution {
if (!enabled) {
return { minted: false, conversationId: undefined }
}
const supplied = extractConversationId(args)
if (supplied) {
return { minted: false, conversationId: supplied }
if (supplied && MINTED_CONVERSATION_ID.test(supplied)) {
// Lowercased because the shape test is case-insensitive but the hash behind
// `$session_id` is not. Some hosts normalise uuids to uppercase, and an
// uppercased echo of our own handle would otherwise clear the gate and then
// land in a different session than the call that minted it.
return { minted: false, conversationId: supplied.toLowerCase() }
}

@@ -117,5 +139,9 @@ return { minted: true, conversationId: uuidv7() }

/**
* Predicate matching the same eligibility checks injectConversationIdPromptBack uses,
* exposed so callers can pre-decide whether the prompt-back will actually land
* (and clear event.conversationId if not, to avoid orphan ids in analytics).
* Whether the prompt-back can ride this result's `content`. The only requirement
* is an array to append to.
*
* Errored results included on purpose. A tool that fails on the first call of a
* conversation is exactly when the agent needs the session handle: without it the
* retry starts a fresh conversation, so the failure and its fix land in different
* sessions.
*/

@@ -126,7 +152,3 @@ export function canInjectConversationIdPromptBack(result: unknown): boolean {

}
const resultObj = result as { content?: unknown; isError?: unknown }
if (resultObj.isError === true) {
return false
}
return Array.isArray(resultObj.content)
return Array.isArray((result as { content?: unknown }).content)
}

@@ -133,0 +155,0 @@

@@ -265,3 +265,5 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

execute: (downstreamRequest) => originalCallToolHandler(downstreamRequest as MCPRequest, extra),
parameterOwnership: registeredTool ? getAnalyticsParameterOwnership(registeredTool.inputSchema) : undefined,
parameterOwnership: registeredTool
? getAnalyticsParameterOwnership(registeredTool.inputSchema, registeredTool.outputSchema)
: undefined,
takeCapturedError: () => {

@@ -268,0 +270,0 @@ const captured = extra?.__mcp_analytics_error

@@ -27,2 +27,3 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

import { stampMetaClientInfo } from './client-identity'
import { addInstructionsToOutputSchemas, mirrorInstructionsIntoStructuredContent } from './output-instructions'
import { captureEvent } from './capture'

@@ -110,10 +111,3 @@ import { MCPAnalyticsEventType } from './event-types'

)
const conversation = resolveConversationId(
ownership.conversationId,
request.params?.arguments,
request.params?.name,
resolvedEventType === MCPAnalyticsEventType.mcpMissingCapability
? resolveMissingCapabilityToolName(data.options)
: ''
)
const conversation = resolveConversationId(ownership.conversationId, request.params?.arguments)
const downstreamRequest = cloneRequestWithoutOwnedAnalyticsArguments(request, ownership)

@@ -147,3 +141,3 @@

const finalResult = applyConversationPromptBack(preparedEvent?.event ?? null, result, conversation)
const finalResult = applyConversationInstructions(preparedEvent?.event ?? null, result, conversation, ownership)
publishSuccessfulToolEvent(server, preparedEvent, finalResult, startTime, data.logger, takeCapturedError)

@@ -164,7 +158,24 @@ return finalResult

): AnalyticsParameterOwnership {
const ownership = override ?? (toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : undefined)
const listed = toolName ? data.toolAnalyticsParameterOwnership.get(toolName) : undefined
const ownership = override ?? listed
return {
context: !isMissingCapabilityTool && isContextEnabled(data.options.context) && ownership?.context === true,
conversationId:
!isMissingCapabilityTool && data.options.enableConversationId === true && ownership?.conversationId === true,
conversationId: data.options.enableConversationId === true && ownership?.conversationId === true,
// Deliberately read off `listed`, never the override. This asks whether
// `tools/list` actually declared `_mcp_instructions`, and only the advertised
// JSON Schema can answer it — an override is built from the live registry,
// which on the high-level path holds Zod.
//
// The cache is per-instance, so this is not merely "before the first
// `tools/list`": an instance that never serves a listing never writes the
// mirror at all. That is the per-request server pattern — `tools/list` lands
// on one instance, `tools/call` on a cold one — where the handle falls back
// to the `content` block and a structuredContent-only client misses it.
//
// Failing closed is deliberate. Writing a key the advertised schema did not
// declare fails the *entire* tool result under `additionalProperties: false`,
// so guessing costs the caller their result, while not guessing costs us one
// delivery channel. The fix is a process-scoped ownership cache, so a listing
// served by any instance answers for the rest — not a per-call guess.
outputInstructions: data.options.enableConversationId === true && listed?.outputInstructions === true,
}

@@ -203,7 +214,15 @@ }

try {
const sessionId = getSessionId(server, extra)
const sessionId = getSessionId(server, extra, conversation.conversationId)
// Snapshot token/client/protocol metadata synchronously, before identify or
// metadata callbacks can yield and let another request replace shared state.
const sessionInfo = getSessionInfo(server, data, sessionId)
const identity = await handleIdentify(server, data, sessionId, request, sessionInfo, extra)
const identity = await handleIdentify(
server,
data,
sessionId,
request,
sessionInfo,
extra,
!!conversation.conversationId
)
const requestAttribution = withIdentity(sessionInfo, identity)

@@ -239,21 +258,47 @@

/**
* When we minted a conversation id, append the prompt-back so the agent echoes
* it on subsequent calls. If the result can't carry it, clear the id off the
* event so analytics doesn't show an orphan the agent never received.
* Delivers the conversation session handle back to the agent, over both channels a tool
* result has:
*
* - `structuredContent`, on *every* response for a tool whose output schema we
* declared the key on. Clients that read structured results never see the text
* block, and re-sending it each time lets an agent that dropped the session handle read
* it back.
* - `content`, as a text block, only on the response that minted the session handle.
* Repeating it every call would put a `[SERVER]:` line in front of the user on
* every single tool result.
*
* If neither channel could carry a session handle we minted, the agent never received it,
* so clear it off the event rather than showing analytics an id nobody has.
*/
function applyConversationPromptBack(
function applyConversationInstructions(
event: McpEvent | null,
result: unknown,
conversation: ConversationIdResolution
conversation: ConversationIdResolution,
ownership: AnalyticsParameterOwnership
): unknown {
if (!conversation.minted) {
const conversationId = conversation.conversationId
if (!conversationId) {
return result
}
if (canInjectConversationIdPromptBack(result)) {
return injectConversationIdPromptBack(result, conversation.conversationId)
let updated = result
let delivered = false
if (ownership.outputInstructions) {
const mirrored = mirrorInstructionsIntoStructuredContent(updated, conversationId)
delivered = mirrored !== updated
updated = mirrored
}
if (event) {
if (conversation.minted && canInjectConversationIdPromptBack(updated)) {
updated = injectConversationIdPromptBack(updated, conversationId)
delivered = true
}
// Only a minted session handle can be lost this way — one the agent supplied, it has.
if (!delivered && conversation.minted && event) {
event.conversationId = undefined
}
return result
return updated
}

@@ -487,3 +532,3 @@

if (tool?.name) {
cache.set(tool.name, getAnalyticsParameterOwnership(tool.inputSchema))
cache.set(tool.name, getAnalyticsParameterOwnership(tool.inputSchema, tool.outputSchema))
}

@@ -525,3 +570,2 @@ }

const missingToolName = resolveMissingCapabilityToolName(data.options)
let injectedMissingCapabilityTool = false
if (data.options.reportMissing) {

@@ -534,4 +578,7 @@ const alreadyPresent = tools.some((tool) => tool?.name === missingToolName)

} else {
tools.push(getReportMissingToolDescriptor(missingToolName))
injectedMissingCapabilityTool = true
const virtualTool = getReportMissingToolDescriptor(missingToolName)
tools.push(virtualTool)
// Cached separately because the virtual tool is added after the listing
// was cached, and its calls need ownership like any other tool's.
cacheToolAnalyticsParameterOwnership(data.toolAnalyticsParameterOwnership, [virtualTool])
}

@@ -541,3 +588,4 @@ }

if (data.options.enableConversationId) {
tools = addConversationIdToTools(tools, missingToolName, injectedMissingCapabilityTool, data.logger)
tools = addConversationIdToTools(tools, data.logger)
tools = addInstructionsToOutputSchemas(tools, data.logger)
}

@@ -544,0 +592,0 @@ }

@@ -133,3 +133,10 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

requestAttribution: SessionInfo,
extra?: CompatibleRequestHandlerExtra
extra?: CompatibleRequestHandlerExtra,
/**
* True when this session id came from an agent-carried `conversation_id`
* rather than the transport. Such a session is brand new and was never
* announced at `initialize`, whatever `data.sessionSource` still says about
* the connection.
*/
sessionFromConversation = false
): Promise<UserIdentity | undefined> {

@@ -170,3 +177,4 @@ const identityBeforeRequest = data.identifiedSessions.get(sessionId)

const firstSeen = previousIdentity === undefined
const announcedAtInitialize = sessionSourceBeforeIdentify === 'token' && request.method !== 'initialize'
const announcedAtInitialize =
!sessionFromConversation && sessionSourceBeforeIdentify === 'token' && request.method !== 'initialize'
const shouldPublish = changed || (firstSeen && !announcedAtInitialize)

@@ -173,0 +181,0 @@

@@ -18,2 +18,3 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

import { decodeSessionId, readMcpSessionHeader } from './session-token'
import type { SessionTokenPayload } from './session-token'

@@ -33,8 +34,36 @@ export function newSessionId(): string {

/**
* Resolves the session id for a request: from the replayed session token, from
* the transport's MCP session id, or — when the request carries nothing — from
* this instance's memory. Also saves the token's client name/version so events
* built later in the request can use them (see getSessionInfo).
* Derives the SDK session id from the agent's conversation handle. Deterministic
* and unsalted on purpose: two pods that never met must agree on the session, and
* the 2026-07-28 revision leaves them no shared state to agree through.
*
* Hashed rather than used verbatim so an MCP session can never collide with a
* Session Replay id — a bare uuidv7 would render a "View recording" button that
* resolves to nothing.
*
* Exported because this *is* the cross-SDK contract: posthog-python has to
* reproduce it byte for byte or the same conversation splits into two sessions
* depending on which SDK served the call.
*/
export function getSessionId(server: MCPServerLike, extra?: CompatibleRequestHandlerExtra): string {
export function deriveSessionIdFromConversation(conversationId: string): string {
return deterministicPrefixedId('ses', conversationId)
}
/**
* Resolves the session id for a request. Three steps, first match wins:
*
* 1. the agent carried a `conversation_id` tool argument — 2026-07-28
* 2. the request carried a session id — 2025-11-25
* 3. nothing was carried, so reuse this instance's own id — stdio
*
* The split mirrors the two protocol revisions. 2026-07-28 removed protocol-level
* sessions, so the only thing that can carry a session across calls is the agent
* itself (1). 2025-11-25 kept the session on the connection, so the request
* carries it (2). 3 is for stdio, where neither applies — there is no
* HTTP request to carry anything, and no agent handle unless the host opted in.
*/
export function getSessionId(
server: MCPServerLike,
extra?: CompatibleRequestHandlerExtra,
conversationId?: string
): string {
const data = getServerTrackingData(server)

@@ -45,24 +74,34 @@ if (!data) {

// Our token rides the `mcp-session-id` request header, which stateless
// transports ignore — so read it ourselves.
const sessionHeader = readMcpSessionHeader(extra?.requestInfo?.headers)
const token = decodeSessionId(sessionHeader)
let sessionId: string
if (token) {
// Token we minted at `initialize` (see session-token.ts).
data.sessionSource = 'token'
data.sessionInfo.clientName = token.clientName
data.sessionInfo.clientVersion = token.clientVersion
data.sessionInfo.protocolVersion = token.protocolVersion
sessionId = token.sessionId
} else if (extra?.sessionId) {
// Session id issued by a stateful transport: hash it so the same MCP
// session maps to the same SDK session across restarts.
data.sessionSource = 'mcp'
sessionId = deriveSessionIdFromMCPSession(extra.sessionId)
} else {
sessionId = getSessionIdFromMemory(data)
// 1. The agent's conversation handle. It outranks both steps below because it
// is the only id that survives reconnects, restarts, and the per-request
// server instances the 2026-07-28 revision introduces. Hashed rather than used
// verbatim so it can never collide with Session Replay ids.
//
// This returns instead of falling through to the shared-state writes at the
// end: the handle belongs to this one request, and persisting it would leak
// one chat's session onto a concurrent chat's `tools/list`.
//
// `lastActivity` therefore does not advance either, so a conversation that
// always echoes lets the in-memory fallback age past the inactivity timeout —
// and a later call carrying no handle rotates it. That is the honest reading:
// the fallback session really has been idle for that whole time.
if (conversationId) {
// The handle decides the *session*, but the request may still carry our token,
// and on a stateless instance that never processed `initialize` its payload is
// the only place client identity exists. Restore that before returning: the
// early return is about not persisting a session, not about ignoring what the
// request told us about the client. Without this, tool calls and `$identify`
// go out unattributed on exactly the deployments this branch exists for.
applyTokenClientIdentity(data, extra)
return deriveSessionIdFromConversation(conversationId)
}
// 2. A session id the request itself carried (undefined if it carried none).
const carriedByRequest = readSessionIdFromRequest(data, extra)
// 3. Nothing carried, so fall back to the id this instance already holds.
const sessionId = carriedByRequest ?? getSessionIdFromMemory(data)
// 2 and 3 are connection-scoped, so their result is remembered for the
// next request on this instance. 1 never reaches here.
data.sessionId = sessionId

@@ -75,6 +114,66 @@ data.lastActivity = new Date()

/**
* Nothing replayed on this request: keep the id we already have. Only
* generated sessions roll over on inactivity — token/MCP ids live as long as
* the client replays them, and regenerating one would split the session.
* Restores the client name/version and protocol version baked into our token at
* mint time, and hands the decoded token back so the caller can also take the
* session id from it.
*
* Split out from step 2 because the two halves of the token have different
* scopes. The session id it carries is per-chat, so a conversation-anchored
* request must not adopt it. The client identity is per-connection — the same
* client for every request on it — so a conversation-anchored request should,
* and on a stateless instance that never saw `initialize` this is the only
* source of it.
*/
function applyTokenClientIdentity(
data: MCPAnalyticsData,
extra?: CompatibleRequestHandlerExtra
): SessionTokenPayload | undefined {
const token = decodeSessionId(readMcpSessionHeader(extra?.requestInfo?.headers))
if (!token) {
return undefined
}
data.sessionInfo.clientName = token.clientName
data.sessionInfo.clientVersion = token.clientVersion
data.sessionInfo.protocolVersion = token.protocolVersion
return token
}
/**
* 2. The session id a request carried. Two sources, tried in order: our own token
* on the `mcp-session-id` header, then the raw session id a stateful transport
* issued. Returns undefined when the request carried neither, which is what
* sends the caller on to 3.
*
* Both are 2025-11-25 mechanisms. The 2026-07-28 revision removed that header
* outright — servers MUST NOT mint or echo it — so this entire step becomes
* legacy-only once era detection lands.
*/
function readSessionIdFromRequest(data: MCPAnalyticsData, extra?: CompatibleRequestHandlerExtra): string | undefined {
// 2a. A token we minted at `initialize` and the client replayed. It rides the
// `mcp-session-id` header, which stateless transports don't surface as
// extra.sessionId, so read the header ourselves.
const token = applyTokenClientIdentity(data, extra)
if (token) {
data.sessionSource = 'token'
return token.sessionId
}
// 2b. No token, but a stateful transport issued its own session id. Hash it so
// the same MCP session maps to the same SDK session across restarts.
if (extra?.sessionId) {
data.sessionSource = 'mcp'
return deriveSessionIdFromMCPSession(extra.sessionId)
}
return undefined
}
/**
* 3. The request carried nothing, so keep the id this instance already holds —
* minted once at `instrument()`. This is what groups a stdio server's calls,
* where there is no header and no transport session to read.
*
* Only self-generated ids roll over on inactivity. Token and transport ids live
* as long as the client replays them, so regenerating one would split a session
* that is still very much alive.
*/
function getSessionIdFromMemory(data: MCPAnalyticsData): string {

@@ -81,0 +180,0 @@ const timeoutMs = INACTIVITY_TIMEOUT_IN_MINUTES * 60 * 1000

@@ -60,3 +60,17 @@ // Portions of this file are derived from agentcathq/agentcat-typescript-sdk

missingCapabilityToolName?: string
/** Enables the `conversation_id` tool parameter + prompt-back loop. */
/**
* Opt in to session correlation for the MCP **2026-07-28** revision, which removed
* protocol-level sessions: no `initialize`, no `mcp-session-id` header, and a fresh
* server instance per HTTP request. With none of those left to anchor on, the only
* thing that can carry a session across calls is the agent itself.
*
* Turning this on injects a `conversation_id` parameter into every tool, mints one
* on the first call, asks the agent to echo it back, and derives `$session_id` from
* that handle — so calls correlate across reconnects, restarts, and per-request
* instances.
*
* Off by default, and fully inert when off: no parameter is injected, no schema is
* touched, no prompt-back is appended, and `$session_id` resolves exactly as it did
* before (the request's own session id, else this instance's).
*/
enableConversationId?: boolean

@@ -127,2 +141,4 @@ /**

inputSchema?: unknown
/** Present when the tool was registered with a declared output schema. */
outputSchema?: unknown
update?: (...args: unknown[]) => unknown

@@ -279,2 +295,8 @@ } & ({ callback: ToolCallback; handler?: never } | { handler: ToolCallback; callback?: never })

conversationId: boolean
/**
* True when we declared `_mcp_instructions` on this tool's advertised output
* schema, so writing that key into `structuredContent` will validate. False
* for tools with no output schema, or one we could not extend.
*/
outputInstructions: boolean
}

@@ -281,0 +303,0 @@

@@ -1,1 +0,1 @@

export const version = '0.10.7'
export const version = '0.10.8'