Skip to content
Sign up

SDK v1.0 migration guide

SDK v1.0 introduces breaking changes to improve consistency and align with modern API design patterns:

  • Naming convention: All properties now use snake_case instead of camelCase
  • Client initialization: Simplified client constructor with renamed parameters
  • Method names: Several methods renamed for clarity
  • Type imports: Types moved to subpath exports for better organization
  • Enums: Replaced with string literal types
  • Tool calls: Changed from single object to array structure
  • Pagination: List methods now return page objects

Update your package dependency:

{
"dependencies": {
- "@letta-ai/letta-client": "0.1.211"
+ "@letta-ai/letta-client": "1.0.0"
}
}
// Old
- import { LettaClient, Letta } from "@letta-ai/letta-client";
// New
+ import Letta from "@letta-ai/letta-client";
+ import type {
+ Block,
+ CreateBlock,
+ AgentType
+ } from "@letta-ai/letta-client/resources/agents/agents";
+ import type {
+ LettaMessageUnion,
+ ApprovalCreate
+ } from "@letta-ai/letta-client/resources/agents/messages";
+ import type {
+ LlmConfig
+ } from "@letta-ai/letta-client/resources/models/models";
// Old
- const client = new LettaClient({
- token: process.env.LETTA_API_KEY,
- baseUrl: "https://api.letta.com"
- });
// New
+ const client = new Letta({
+ apiKey: process.env.LETTA_API_KEY,
+ baseURL: "https://api.letta.com"
+ });

All list endpoints now use cursor-based pagination with consistent parameters:

// Old - various pagination styles
const messages = await client.agents.messages.list(agentId, {
sort_by: "created_at",
ascending: true
});
// New - standardized cursor pagination
const messagesPage = await client.agents.messages.list(agentId, {
before: "msg_123", // cursor (message ID)
after: "msg_456", // cursor (message ID)
limit: 50,
order: "asc" // or "desc"
});
const messages = messagesPage.items;

Affected endpoints:

  • agents.list() - renamed sort_byorder_by, ascendingorder
  • agents.messages.list()
  • agents.tools.list()
  • agents.blocks.list()
  • agents.files.list()
  • agents.folders.list()
  • agents.groups.list()
  • blocks.list()
  • folders.list()
  • folders.files.list()
  • folders.passages.list()
  • folders.agents.list()
  • groups.list()
  • groups.messages.list()
  • identities.list()
  • providers.list()
  • runs.list()
  • runs.messages.list()
  • runs.steps.list()
  • jobs.list()
  • steps.list()
  • tags.list()
  • tools.list()
  • batches.list()
  • batches.messages.list()

2. Method Renames and Endpoint Restructuring

Section titled “2. Method Renames and Endpoint Restructuring”

Many methods were reorganized for better SDK structure:

// Agent updates
- await client.agents.modify(agentId, updates)
+ await client.agents.update(agentId, updates)
// Message operations
- await client.agents.summarize_agent_conversation(agentId)
+ await client.agents.messages.compact(agentId)
- await client.agents.cancel_agent_run(agentId)
+ await client.agents.messages.cancel(agentId)
- await client.agents.messages.preview_raw_payload(agentId, messages)
+ await client.agents.messages.preview(agentId, messages)
// Agent file operations
- await client.agents.list_agent_files(agentId)
+ await client.agents.files.list(agentId)
// Export/Import
- await client.agents.export_agent_serialized(agentId)
+ await client.agents.exportFile(agentId)
- await client.agents.import_agent_serialized(file)
+ await client.agents.importFile(file)
// Folder operations
- await client.folders.get_agents_for_folder(folderId)
+ await client.folders.agents.list(folderId)
// Provider operations
- await client.providers.check_provider(providerId)
+ await client.providers.check(providerId)
// Telemetry
- await client.telemetry.retrieve_provider_trace(stepId)
+ await client.steps.trace.retrieve(stepId)
// Step metrics
- await client.steps.retrieve_step_metrics(stepId)
+ await client.steps.metrics.retrieve(stepId)
// Batch messages
- await client.messages.list_batch_messages(batchId)
+ await client.batches.messages.list(batchId)
// Multi-agent groups
- agent.multi_agent_group
+ agent.managed_group

Several endpoints and fields are now deprecated:

Deprecated endpoints:

  • client.agents.search() - use client.agents.list() with filters
  • client.messages.search() - use client.agents.messages.list() with filters
  • client.runs.list_active() - use client.runs.list(active=True)
  • client.jobs.list_active() - use client.jobs.list(active=True)
  • client.folders.get_by_name() - use client.folders.list(name="...")
  • MCP routes under /tools/mcp/servers - replaced with new /mcp-servers endpoints
    • All old MCP methods moved from client.tools.mcp.servers to client.mcp_servers
    • Now use server IDs and tool IDs instead of names
  • Sources-related routes - replaced with folders
  • Passages routes - replaced with archives
  • Legacy agent architecture routes
  • All /count endpoints

Deprecated fields:

  • agent.memory - use agent.blocks
  • step.messages - use client.steps.messages.list(step_id)
  • agent.identity_ids - replaced with agent.identities (full objects)
  • agent.multi_agent_group - renamed to agent.managed_group
  • use_assistant_message parameter - no longer needed
  • tool_exec_environment_variables - renamed to secrets

Deprecated on agent/block objects:

  • Template-related fields: is_template, base_template_id, deployment_id
  • entity_id, preserve_on_migration, hidden
  • name on blocks (use label)

4. Property Names (camelCase → snake_case)

Section titled “4. Property Names (camelCase → snake_case)”

All API properties now use snake_case:

// Agent properties
- agent.llmConfig
+ agent.llm_config
- agent.contextWindowLimit
+ agent.context_window_limit
- agent.blockIds
+ agent.block_ids
- agent.includeBaseTools
+ agent.include_base_tools
- agent.includeBaseToolRules
+ agent.include_base_tool_rules
- agent.initialMessageSequence
+ agent.initial_message_sequence
// Message properties
- message.toolCallId
+ message.tool_call_id
- message.toolReturn
+ message.tool_returns // Note: plural
// tool_calls is now always an array
+ message.tool_calls
// API parameters
- streamTokens: true
+ stream_tokens: true // Also add streaming: true for streaming requests
- approvalRequestId: id
+ approval_request_id: id
// Old
- agentType: Letta.AgentType.LettaV1Agent
// New
+ agent_type: "letta_v1_agent" as AgentType
// Agent updates
- await client.agents.modify(agentId, { model, llmConfig })
+ await client.agents.update(agentId, { model, llm_config })
// Message streaming
- client.agents.messages.createStream(agentId, { messages, streamTokens: true })
+ client.agents.messages.stream(agentId, { messages, stream_tokens: true })

Enums replaced with string literals:

// Message roles
- role: Letta.MessageCreateRole.User
+ role: "user"
// Stop reasons
- if (stopReason === Letta.StopReasonType.EndTurn)
+ if (stopReason === "end_turn")
- if (stopReason === Letta.StopReasonType.RequiresApproval)
+ if (stopReason === "requires_approval")

Tool calls changed from single object to array:

// Old - single tool_call
- if (message.messageType === "approval_request_message") {
- const toolCall = message.toolCall;
- const id = toolCall.toolCallId;
- const name = toolCall.name;
- }
// New - tool_calls array
+ if (message.message_type === "approval_request_message") {
+ const toolCalls = message.tool_calls || [];
+ if (toolCalls.length > 0) {
+ const toolCall = toolCalls[0];
+ const id = toolCall.tool_call_id;
+ const name = toolCall.name;
+ }
+ }

List methods now return page objects:

// Old
- const messages = await client.agents.messages.list(agentId);
// New
+ const messagesPage = await client.agents.messages.list(agentId, {
+ before: "msg_123",
+ after: "msg_456",
+ limit: 50,
+ order: "asc"
+ });
+ const messages = messagesPage.items;
// Old
- date: new Date()
// New
+ date: new Date().toISOString()

New endpoints for managing archival memory:

// Create archive
const archive = await client.archives.create({
name: "my-archive",
description: "Project knowledge base"
});
// List archives
const archives = await client.archives.list();
// Get archive by ID
const archive = await client.archives.retrieve(archiveId);
// Update archive
await client.archives.update(archiveId, { name: "updated-name" });
// Delete archive
await client.archives.delete(archiveId);
// Attach archive to agent
await client.agents.archives.attach(archiveId, { agent_id: agentId });
// Detach archive from agent
await client.agents.archives.detach(archiveId, { agent_id: agentId });
// List agents using an archive
const agents = await client.archives.agents.list(archiveId);
// Create passages in archive
await client.archives.passages.create(archiveId, { text: "Important fact" });

New attach/detach patterns for identities and blocks:

// Attach identity to agent
await client.agents.identities.attach(identityId, { agent_id: agentId });
// Detach identity from agent
await client.agents.identities.detach(identityId, { agent_id: agentId });
// Attach identity to block
await client.blocks.identities.attach(identityId, { block_id: blockId });
// Detach identity from block
await client.blocks.identities.detach(identityId, { block_id: blockId });
// Agent now returns full identity objects
const agent = await client.agents.retrieve(agentId);
// Old: agent.identity_ids = ["id1", "id2"]
// New: agent.identities = [{ id: "id1", name: "Alice", ... }, ...]

Model-specific settings are configured via the model_settings object:

// Create agent with OpenAI model settings
const agent = await client.agents.create({
model: "openai/gpt-4",
model_settings: {
provider_type: "openai",
temperature: 0.7,
max_output_tokens: 4096,
reasoning: {
reasoning_effort: "medium"
}
},
context_window_limit: 128000
});
// Create agent with Anthropic model settings
const agent2 = await client.agents.create({
model: "anthropic/claude-3-5-sonnet-20241022",
model_settings: {
provider_type: "anthropic",
temperature: 0.7,
max_output_tokens: 4096,
thinking: {
type: "enabled",
budget_tokens: 1024
}
},
context_window_limit: 128000
});
// Update agent configuration
await client.agents.update(agentId, {
model_settings: {
provider_type: "openai",
temperature: 0.5
},
context_window_limit: 64000
});

Simplified syntax for sending simple user messages:

// Old - verbose
const response = await client.agents.messages.create(agentId, {
messages: [{
role: "user",
content: "Hello!"
}]
});
// New - shorthand available
const response = await client.agents.messages.create(agentId, {
input: "Hello!" // Automatically creates user message
});
// Both forms still supported

All attach/detach endpoints now return None instead of agent/object state:

// Old - returned updated agent
const updatedAgent = await client.agents.tools.attach(agentId, toolId);
// New - returns void/None
await client.agents.tools.attach(agentId, toolId);
// Fetch agent separately if needed
const agent = await client.agents.retrieve(agentId);

Affected methods:

  • agents.tools.attach/detach
  • agents.blocks.attach/detach
  • agents.folders.attach/detach
  • agents.archives.attach/detach
  • agents.identities.attach/detach
  • blocks.identities.attach/detach

Import endpoint now supports name overriding:

// Old - append_copy_suffix parameter
const agent = await client.agents.import(file, {
append_copy_suffix: true // Deprecated
});
// New - override_name parameter
const agent = await client.agents.importFile(file, {
override_name: "my-imported-agent" // Optional, exact name to use
});

14. Query Parameter to Request Body Changes

Section titled “14. Query Parameter to Request Body Changes”

Several endpoints moved from query parameters to request body:

// Tool approval settings (was query params, now request body)
await client.agents.tools.update_approval(agentId, toolName, {
require_approval: true
});
// Reset messages (was query param, now request body)
await client.agents.messages.reset(agentId, {
add_default_initial_messages: false
});
// Steps feedback (was query params, now request body)
await client.steps.feedback.create(stepId, {
rating: "positive",
tags: ["helpful", "accurate"]
});

Tags list endpoint now uses name parameter instead of query_text:

// Old
const tags = await client.tags.list({ query_text: "important" });
// New
const tags = await client.tags.list({ name: "important" });

Project ID is now passed in the client constructor or headers:

// Pass in constructor
const client = new Letta({
apiKey: process.env.LETTA_API_KEY,
projectId: "proj_123"
});
// No longer in URL paths
- await client.templates.agents.create("proj_123", templateVersion, data)
+ await client.templates.agents.create(templateVersion, data)

17. MCP (Model Context Protocol) Server Management

Section titled “17. MCP (Model Context Protocol) Server Management”

MCP routes have been completely restructured with new endpoints under /mcp-servers:

// OLD ROUTES (under /tools/mcp/servers - DEPRECATED)
// Using server names and tool names
// List MCP servers
- const servers = await client.tools.mcp.servers.list();
// Add MCP server
- await client.tools.mcp.servers.create(serverConfig);
// Update MCP server by name
- await client.tools.mcp.servers.update(serverName, updateConfig);
// Delete MCP server by name
- await client.tools.mcp.servers.delete(serverName);
// List tools from a server by name
- const tools = await client.tools.mcp.servers.tools.list(serverName);
// Add individual tool by name
- await client.tools.mcp.servers.tools.add(serverName, toolName);
// Resync tools
- await client.tools.mcp.servers.resync(serverName);
// Execute tool by names
- await client.tools.mcp.servers.tools.execute(serverName, toolName, { args });
// Connect to server (for OAuth)
- await client.tools.mcp.servers.connect(serverConfig);
// NEW ROUTES (under /mcp-servers)
// Using server IDs and tool IDs
// List MCP servers (returns array of server objects with IDs)
+ const servers = await client.mcpServers.list();
// Create MCP server (automatically syncs tools)
+ const server = await client.mcpServers.create(serverConfig);
+ // Returns: { id: "mcp_server_123", name: "...", ... }
// Get MCP server by ID
+ const server = await client.mcpServers.retrieve(serverId);
// Update MCP server by ID
+ await client.mcpServers.update(serverId, updateConfig);
// Delete MCP server by ID
+ await client.mcpServers.delete(serverId);
// List tools from a server by ID
+ const tools = await client.mcpServers.tools.list(serverId);
// Get specific tool by ID
+ const tool = await client.mcpServers.tools.retrieve(serverId, toolId);
// Run/execute tool by ID
+ const result = await client.mcpServers.tools.run(serverId, toolId, {
+ args: { key: "value" }
+ });
// Refresh tools (replaces resync)
+ await client.mcpServers.refresh(serverId);
// Connect to server (for OAuth) - now uses server ID
+ await client.mcpServers.connect(serverId);

Key Changes:

  • Namespace: Moved from client.tools.mcp.servers to client.mcpServers (TypeScript) or client.mcp_servers (Python)
  • Identification: Use server IDs and tool IDs instead of names
    • Old: serverName (string) → New: serverId (ID string like "mcp_server-12ab34cd")
    • Old: toolName (string) → New: toolId (UUID string like "tool-123e4567-e89b-42d3-8456-426614174000")
  • Tool Management: Tools are now automatically synced when creating a server
    • No longer need to manually “add” individual tools
    • Use refresh() to resync tools (replaces resync())
  • Tool Execution: Method renamed from execute() to run()
  • Server Retrieval: New retrieve() method to get individual server by ID
  • Tool Retrieval: New retrieve() method to get individual tool by ID

Migration Example:

// Before: Using names
const servers = await client.tools.mcp.servers.list();
const myServer = servers.find(s => s.name === "my-server");
const tools = await client.tools.mcp.servers.tools.list("my-server");
const myTool = tools.find(t => t.name === "my-tool");
await client.tools.mcp.servers.tools.execute("my-server", "my-tool", {
args: { query: "hello" }
});
// After: Using IDs
const servers = await client.mcpServers.list();
const myServer = servers.find(s => s.name === "my-server");
const serverId = myServer.id; // Get ID from server object
const tools = await client.mcpServers.tools.list(serverId);
const myTool = tools.find(t => t.name === "my-tool");
const toolId = myTool.id; // Get ID from tool object
await client.mcpServers.tools.run(serverId, toolId, {
args: { query: "hello" }
});

Notes:

  • MCP servers and tools now have persistent IDs in the database
  • Server names are no longer unique identifiers - use IDs instead
  • Tool schemas are automatically kept in sync via the refresh() endpoint
  • The old routes under /tools/mcp/servers are deprecated and will be removed
// Before
const agent = await client.agents.create({
agentType: Letta.AgentType.LettaV1Agent,
model: "openai/gpt-4",
contextWindowLimit: 200_000,
blockIds: ["block-1", "block-2"],
includeBaseTools: false,
includeBaseToolRules: false,
initialMessageSequence: [],
});
// After
const agent = await client.agents.create({
agent_type: "letta_v1_agent" as AgentType,
model: "openai/gpt-4",
context_window_limit: 200_000,
block_ids: ["block-1", "block-2"],
include_base_tools: false,
include_base_tool_rules: false,
initial_message_sequence: [],
});
// Before
const stream = await client.agents.messages.createStream(agentId, {
messages: [{
role: Letta.MessageCreateRole.User,
content: "Hello"
}],
streamTokens: true,
});
// After
const stream = await client.agents.messages.stream(agentId, {
messages: [{
role: "user",
content: "Hello"
}],
stream_tokens: true,
});
// Before
if (message.messageType === "approval_request_message") {
const toolCall = message.toolCall;
await client.agents.messages.create(agentId, {
messages: [{
type: "approval",
approvalRequestId: toolCall.toolCallId,
approve: true,
}],
});
}
// After
if (message.message_type === "approval_request_message") {
const toolCalls = message.tool_calls || [];
if (toolCalls.length > 0) {
const toolCall = toolCalls[0];
await client.agents.messages.create(agentId, {
messages: [{
type: "approval",
approval_request_id: toolCall.tool_call_id,
approve: true,
}],
});
}
}
// Before
await client.agents.modify(agentId, {
model: "openai/gpt-4",
llmConfig: { temperature: 0.7 }
});
const agent = await client.agents.retrieve(agentId);
const config = agent.llmConfig;
// After
await client.agents.update(agentId, {
model: "openai/gpt-4",
llm_config: { temperature: 0.7 }
});
const agent = await client.agents.retrieve(agentId);
const config = agent.llm_config;

Use this checklist to ensure a complete migration:

Core SDK Changes:

  • Update package version to 1.0.0-alpha.10 or later
  • Update all imports (client and types)
  • Replace LettaClient with Letta
  • Update client constructor params: tokenapiKey, baseUrlbaseURL
  • Add projectId to client constructor if using multi-project setup
  • Convert all property names from camelCase to snake_case
  • Replace enum references with string literals
  • Convert Date objects to ISO strings where required
  • Update type annotations to use new import paths

Method Renames:

  • Update modify() calls to update()
  • Update createStream() calls to create() with streaming: true
  • Rename summarize_agent_conversation()messages.compact()
  • Rename cancel_agent_run()messages.cancel()
  • Rename preview_raw_payload()messages.preview()
  • Rename list_agent_files()files.list()
  • Rename export_agent_serialized()export_file()
  • Rename import_agent_serialized()import_file()
  • Rename folder/provider method names (see section 2)
  • Update telemetry routes to use steps.trace.retrieve()

Pagination:

  • Update all list methods to access .items property
  • Replace sort_by with order_by in agents.list()
  • Replace ascending with order parameter
  • Update pagination parameters: before, after, limit, order
  • Handle cursor-based pagination for all list endpoints

Message Handling:

  • Handle tool_calls as an array instead of single object
  • Update identity_ids references to use identities (full objects)
  • Replace agent.memory with agent.blocks
  • Update step.messages to use steps.messages.list()
  • Consider using new input shorthand for simple messages

Deprecations:

  • Remove usage of deprecated search endpoints
  • Replace list_active() with list(active=True)
  • Remove use_assistant_message parameter
  • Replace tool_exec_environment_variables with secrets
  • Remove template-related fields from agent/block objects
  • Replace sources endpoints with folders
  • Replace passages endpoints with archives

New Features:

  • Update attach/detach methods (now return None)
  • Use new archive management APIs if needed
  • Update agent import to use override_name instead of append_copy_suffix
  • Move query parameters to request body for affected endpoints
  • Use new agent configuration parameters (temperature, top_p, etc.)

MCP (Model Context Protocol) Changes:

  • Migrate from client.tools.mcp.servers to client.mcp_servers
  • Update MCP server references to use IDs instead of names
  • Update MCP tool references to use IDs instead of names
  • Remove manual tool “add” operations (tools auto-sync on server create)
  • Replace resync() calls with refresh()
  • Replace execute() calls with run()
  • Add server/tool ID lookup logic if using names
  • Update OAuth connection flow to use server IDs

Testing:

  • Test all agent operations (create, update, message)
  • Test streaming and approval flows
  • Verify memory block operations still work
  • Test pagination on list endpoints
  • Test archive management if used
  • Verify identity/block attach/detach operations
  • Test agent import/export

Use this script to help automate common replacements:

Terminal window
# Install dependencies
npm install -g jscodeshift
# Run find-and-replace (adjust paths as needed)
find src -name "*.ts" -o -name "*.tsx" | xargs sed -i '' \
-e 's/LettaClient/Letta/g' \
-e 's/\.modify(/.update(/g' \
-e 's/\.createStream(/.create(/g' \
-e 's/\.messageType/.message_type/g' \
-e 's/\.toolCall/.tool_calls/g' \
-e 's/\.toolCallId/.tool_call_id/g' \
-e 's/\.toolReturn/.tool_return/g' \
-e 's/llmConfig/llm_config/g' \
-e 's/streamTokens/stream_tokens/g' \
-e 's/\.tools\.mcp\.servers/\.mcp_servers/g' \
-e 's/\.resync(/\.refresh(/g'
# Note: MCP server/tool name -> ID migration requires manual intervention
# as you need to fetch IDs from the API

Cause: Method renamed to update

Fix: Update all modify calls

- await client.agents.modify(agentId, updates)
+ await client.agents.update(agentId, updates)

”Property ‘llmConfig’ does not exist” (TypeScript)

Section titled “”Property ‘llmConfig’ does not exist” (TypeScript)”

Cause: Property renamed to llm_config

Fix: Update all references to use snake_case

- agent.llmConfig
+ agent.llm_config

”Cannot read property ‘toolCallId’ of undefined”

Section titled “”Cannot read property ‘toolCallId’ of undefined””

Cause: tool_call changed to tool_calls (array)

Fix: Access the first element of the array

- const id = message.toolCall.toolCallId;
+ const toolCalls = message.tool_calls || [];
+ const id = toolCalls[0]?.tool_call_id;

Cause: Trying to iterate over page object instead of items array

Fix: Access the .items property first

- for (const message of messages) {
+ const messagesPage = await client.agents.messages.list(agentId);
+ for (const message of messagesPage.items) {

”Cannot find module ‘@letta-ai/letta-client/resources/…’”

Section titled “”Cannot find module ‘@letta-ai/letta-client/resources/…’””

Cause: Types moved to subpath exports

Fix: Update imports to use new subpaths

- import { Letta } from "@letta-ai/letta-client";
+ import type { Block } from "@letta-ai/letta-client/resources/agents/agents";

”Cannot access property ‘identity_ids’”

Section titled “”Cannot access property ‘identity_ids’””

Cause: Field renamed to identities and now returns full objects

Fix: Access the identities array and extract IDs if needed

- const ids = agent.identity_ids;
+ const identities = agent.identities;
+ const ids = identities.map(i => i.id);

”Pagination parameters ‘sort_by’ or ‘ascending’ not recognized”

Section titled “”Pagination parameters ‘sort_by’ or ‘ascending’ not recognized””

Cause: Pagination parameters standardized to order_by and order

Fix: Update parameter names

- await client.agents.list({ sort_by: "created_at", ascending: true })
+ await client.agents.list({ order_by: "created_at", order: "asc" })

”Attach/detach methods return undefined”

Section titled “”Attach/detach methods return undefined””

Cause: These methods now return None/void instead of updated state

Fix: Fetch the object separately if you need the updated state

await client.agents.tools.attach(agentId, toolId);
const agent = await client.agents.retrieve(agentId); // Get updated state

”Cannot find method ‘summarize_agent_conversation’”

Section titled “”Cannot find method ‘summarize_agent_conversation’””

Cause: Method moved to messages subresource

Fix: Use the new path

- await client.agents.summarize_agent_conversation(agentId)
+ await client.agents.messages.compact(agentId)

”Query parameter ‘add_default_initial_messages’ not working”

Section titled “”Query parameter ‘add_default_initial_messages’ not working””

Cause: Parameter moved from query to request body

Fix: Pass as request body parameter

- await client.agents.messages.reset(agentId, { params: { add_default_initial_messages: false } })
+ await client.agents.messages.reset(agentId, { add_default_initial_messages: false })

”Cannot find ‘client.tools.mcp.servers’”

Section titled “”Cannot find ‘client.tools.mcp.servers’””

Cause: MCP routes moved to new namespace

Fix: Use new MCP server methods

TypeScript:

- await client.tools.mcp.servers.list()
+ await client.mcpServers.list()

Python:

- client.tools.mcp.servers.list()
+ client.mcp_servers.list()

Cause: MCP methods now use server IDs instead of names

Fix: Lookup server ID from name first

TypeScript:

// Get server ID from name
const servers = await client.mcpServers.list();
const myServer = servers.items.find(s => s.name === "my-server");
const serverId = myServer.id;
// Use ID for subsequent operations
await client.mcpServers.tools.list(serverId);

Python:

# Get server ID from name
servers = client.mcp_servers.list()
my_server = next(s for s in servers.items if s.name == "my-server")
server_id = my_server.id
# Use ID for subsequent operations
client.mcp_servers.tools.list(server_id)

Cause: MCP tool execution now uses tool IDs instead of names

Fix: Lookup tool ID from name first

TypeScript:

const tools = await client.mcpServers.tools.list(serverId);
const myTool = tools.items.find(t => t.name === "my-tool");
const toolId = myTool.id;
await client.mcpServers.tools.run(serverId, toolId, { args });

Python:

tools = client.mcp_servers.tools.list(server_id)
my_tool = next(t for t in tools.items if t.name == "my-tool")
tool_id = my_tool.id
client.mcp_servers.tools.run(server_id, tool_id, args=args)

“Method ‘execute’ not found on mcp_servers.tools”

Section titled ““Method ‘execute’ not found on mcp_servers.tools””

Cause: Method renamed from execute() to run()

Fix: Use the new method name

TypeScript:

- await client.mcpServers.tools.execute(serverId, toolId, { args })
+ await client.mcpServers.tools.run(serverId, toolId, { args })

Python:

- client.mcp_servers.tools.execute(server_id, tool_id, args=args)
+ client.mcp_servers.tools.run(server_id, tool_id, args=args)

If you encounter issues during migration:

  1. Check the Changelog for detailed release notes
  2. Search GitHub Issues for known problems
  3. Ask in Discord #dev-help for community support
  4. Contact support@letta.com for enterprise support