Skip to content

Session Context (conversationId in MCP Tools)

When your MCP server is called from a UAPI agent, the platform automatically injects session context into userContext.sessionContext. This gives your tool handlers access to the calling conversation's metadata — no agent-side configuration needed.

Quick Start

javascript
function createMcpServer(userContext) {
  const server = new McpServer({ name: "my-server", version: "1.0.0" });
  
  // Session context is automatically available
  const session = userContext.sessionContext || {};

  server.registerTool("create_record", {
    description: "Create a record linked to this conversation",
    inputSchema: { name: z.string() }
  }, async ({ name }) => {
    const record = await db.insert({
      name,
      conversationId: session.conversationId,  // ← auto-injected
      agentId: session.agentId,
      createdBy: session.userId,
    });
    return { content: [{ type: "text", text: JSON.stringify(record) }] };
  });

  return server;
}
module.exports = { createMcpServer };

Available Fields

FieldTypeDescription
conversationIdstringThe conversation UUID that triggered this tool call
agentIdstringThe UAPI agent UUID making the call
userIdstringThe end-user's UAPI user ID
parentConversationIdstring?The parent agent's conversation UUID (present when this agent was called by another agent — e.g., a voice agent delegating to a text agent)
parentAgentIdstring?The parent agent's UUID (the agent that delegated to this one)
channelIdstring?Channel UUID (if triggered via Slack, SMS, etc.)
platformstring?Platform name: "slack", "telegram", "twilio-sms", "twilio-voice", etc.

When is sessionContext available?

CallersessionContext
UAPI agent (chat)✅ Populated with conversationId, agentId, userId
UAPI agent via channel (Slack, SMS)✅ Also includes channelId and platform
External MCP client (Cline, Claude Desktop)null
Direct API call (curl, etc.)null

Always handle the null case

Your MCP server may be called from external clients that don't inject session context. Always use a fallback:

javascript
const { conversationId } = userContext.sessionContext || {};

Use Cases

javascript
// Store conversationId on booking/order/ticket records
// so you can later display the conversation transcript alongside the record
await createBooking({
  ...bookingData,
  conversationId: session.conversationId,
});

2. Conversation-scoped state

javascript
// Store tool state per-conversation (e.g., shopping cart, draft document)
const cartKey = `cart:${session.conversationId}`;
await redis.set(cartKey, JSON.stringify(items));

3. Analytics & attribution

javascript
// Track which agents/channels drive which actions
analytics.track('booking_created', {
  agentId: session.agentId,
  channel: session.platform || 'direct',
  conversationId: session.conversationId,
});

4. Channel-aware behavior

javascript
// Adjust behavior based on the messaging platform
if (session.platform === 'twilio-sms') {
  // Keep responses short for SMS
  return { content: [{ type: "text", text: "Booked! Confirmation sent via SMS." }] };
} else {
  // Rich response for chat
  return { content: [{ type: "text", text: JSON.stringify(fullDetails) }] };
}

5. Voice call correlation (parent lineage)

javascript
// When called from a text agent that was delegated by a voice agent,
// parentConversationId gives you the originating phone call's session ID
const voiceCallId = session.parentConversationId;

await db.insert({
  ...bookingData,
  conversationId: session.conversationId,       // text agent conversation
  voiceSessionId: voiceCallId,                  // originating voice call
});

See Voice-to-Text Delegation for the full guide on multi-agent context propagation.

How It Works (Behind the Scenes)

  1. When a UAPI agent calls your MCP server tool, the agent runtime automatically injects an X-UAPI-Session-Context HTTP header on the outbound request.
  2. The UAPI MCP runtime parses this header and adds it to userContext.sessionContext.
  3. Your createMcpServer(userContext) function receives the full context.

This is completely transparent — no configuration needed on either the agent side or the MCP server side. The platform handles everything.

Agent-Side Access (env vars)

If you're writing agent code (not MCP server code) and need the current conversationId, it's available as an environment variable:

python
import os

conversation_id = os.environ.get('UAPI_CONVERSATION_ID')
agent_id = os.environ.get('UAPI_AGENT_ID')

These are set automatically during agent execution.

Universal API - The agentic entry point to the universe of APIs