Documentation Index Fetch the complete documentation index at: https://mintlify.com/mcp-use/mcp-use/llms.txt
Use this file to discover all available pages before exploring further.
Overview
MCPClient supports multiple transport protocols for connecting to MCP servers. The client automatically selects the appropriate connector based on your configuration and handles connection lifecycle, retries, and fallbacks.
Transport Types
The mcp-use client supports three main transport types:
Stdio Process-based communication via stdin/stdout. Best for local Node.js servers.
HTTP Streamable HTTP with automatic SSE fallback. Best for remote servers.
WebSocket Bidirectional streaming (browser-only).
Stdio Connector
The StdioConnector spawns a local process and communicates via standard input/output streams. This is the most efficient method for local servers.
Configuration
{
"mcpServers" : {
"filesystem" : {
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/tmp" ],
"env" : {
"DEBUG" : "mcp:*" ,
"NODE_ENV" : "production"
}
}
}
}
How It Works
Process Spawn (src/connectors/stdio.ts:49): Client spawns the command with provided args
Stream Setup : Creates bidirectional stdio transport
MCP Handshake : Performs initialization protocol
Ready : Session is ready for tool calls
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ({
mcpServers: {
'python-server' : {
command: 'python' ,
args: [ 'server.py' ],
env: {
PYTHONPATH: '/app/lib' ,
LOG_LEVEL: 'INFO'
}
},
'node-server' : {
command: 'node' ,
args: [ 'dist/server.js' , '--port' , '3000' ]
}
}
});
const session = await client . createSession ( 'python-server' );
console . log ( 'Connected via stdio' );
Stdio Options
Executable command. Can be absolute path or PATH-resolved binary. "command" : "npx" // or "node", "python", "/usr/bin/python3"
Command line arguments passed to the process. "args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/data" ]
Environment variables. Merged with process.env (src/connectors/stdio.ts:60). "env" : {
"DEBUG" : "*" ,
"API_KEY" : "secret"
}
Stdio Best Practices
Launch npm-published MCP servers easily: {
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/home" ]
}
Always close sessions to terminate child processes: const session = await client . createSession ( 'my-server' );
try {
// Use session...
} finally {
await client . closeSession ( 'my-server' ); // Kills process
}
Server logs go to stderr by default: import { StdioConnector } from 'mcp-use' ;
import { Writable } from 'stream' ;
const logStream = new Writable ({
write ( chunk , encoding , callback ) {
console . log ( '[SERVER]' , chunk . toString ());
callback ();
}
});
const connector = new StdioConnector ({
command: 'node' ,
args: [ 'server.js' ],
errlog: logStream
});
HTTP Connector
The HttpConnector communicates with remote MCP servers over HTTP. It automatically tries streamable HTTP first, then falls back to SSE (Server-Sent Events) for maximum compatibility.
Configuration
{
"mcpServers" : {
"brave-search" : {
"url" : "https://mcp.brave.com/mcp" ,
"authToken" : "${BRAVE_API_KEY}" ,
"preferSse" : false ,
"headers" : {
"X-Client-ID" : "my-app"
}
}
}
}
Transport Selection
The HttpConnector follows this connection flow (src/connectors/http.ts:185):
Streamable HTTP vs SSE
Streamable HTTP (src/connectors/http.ts:276):
Uses HTTP POST for requests and responses
Lower latency for request/response patterns
Requires server support for mcp-session-id header
Automatically extracts session ID from initialize response
SSE (Server-Sent Events) (src/connectors/http.ts:418):
Uses HTTP POST + EventSource for streaming
Better compatibility with existing HTTP servers
Fallback when streamable HTTP is not available
Works with FastMCP and other SSE-based servers
HTTP Options
Base URL of the MCP server endpoint. "url" : "https://api.example.com/mcp"
Bearer token for authentication. Added as Authorization: Bearer <token> header. "authToken" : "sk-1234567890abcdef"
Additional HTTP headers for all requests. "headers" : {
"X-API-Key" : "key" ,
"X-Client-Version" : "1.0.0"
}
Force SSE transport instead of trying streamable HTTP first. Default: false. "preferSse" : true // Skip streamable HTTP attempt
Disable automatic SSE fallback when streamable HTTP fails. Default: false. "disableSseFallback" : true // Fail if streamable HTTP doesn't work
Explicit transport selection. Default: "http" with auto-fallback.
Custom fetch implementation for proxying or testing. import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ({
mcpServers: {
'api' : {
url: 'https://api.example.com/mcp' ,
fetch : async ( url , init ) => {
console . log ( 'Fetching:' , url );
return fetch ( url , init );
}
}
}
});
Authentication
Bearer Token
Simplest method for API keys:
const client = new MCPClient ({
mcpServers: {
'api' : {
url: 'https://api.example.com/mcp' ,
authToken: process . env . API_TOKEN
}
}
});
OAuth
For OAuth-based servers (src/connectors/http.ts:424):
const client = new MCPClient ({
mcpServers: {
'github' : {
url: 'https://mcp.github.com/mcp' ,
authProvider: {
type: 'oauth' ,
serverUrl: 'https://oauth.github.com' ,
clientId: process . env . GITHUB_CLIENT_ID ,
clientSecret: process . env . GITHUB_CLIENT_SECRET ,
scopes: [ 'repo' , 'user' ],
redirectUri: 'http://localhost:3000/callback'
}
}
}
});
try {
const session = await client . createSession ( 'github' );
} catch ( error ) {
if ( error . code === 401 ) {
console . error ( 'OAuth authentication required' );
// Implement OAuth flow
}
}
For API key authentication:
const client = new MCPClient ({
mcpServers: {
'api' : {
url: 'https://api.example.com/mcp' ,
headers: {
'X-API-Key' : process . env . API_KEY ,
'X-Client-ID' : 'my-app'
}
}
}
});
Error Handling
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ({
mcpServers: {
'remote' : { url: 'https://api.example.com/mcp' }
}
});
try {
const session = await client . createSession ( 'remote' );
console . log ( 'Connected via:' , session . connector . getTransportType ());
} catch ( error : any ) {
if ( error . code === 401 ) {
console . error ( 'Authentication required' );
} else if ( error . code === 404 ) {
console . error ( 'Server endpoint not found' );
} else if ( error . message ?. includes ( 'SSE fallback' )) {
console . error ( 'Streamable HTTP and SSE both failed' );
} else {
console . error ( 'Connection failed:' , error . message );
}
}
HTTP Best Practices
Don’t disable SSE fallback unless you’re sure the server supports streamable HTTP: // Good: Automatic fallback
{ url : 'https://api.example.com/mcp' }
// Risky: Fails if streamable HTTP not supported
{ url : 'https://api.example.com/mcp' , disableSseFallback : true }
Use preferSse for Known SSE Servers
Handle Authentication Errors
Properly handle 401 responses: try {
await client . createSession ( 'api' );
} catch ( error : any ) {
if ( error . code === 401 ) {
// Refresh token or re-authenticate
await refreshAuthentication ();
await client . createSession ( 'api' );
}
}
Know which transport succeeded: const session = await client . createSession ( 'api' );
const transport = session . connector . getTransportType ();
console . log ( `Connected via: ${ transport } ` );
// "streamable-http" or "sse"
Connection Lifecycle
Creating Sessions
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ( './mcp-config.json' );
// Create single session (auto-initializes)
const session1 = await client . createSession ( 'server1' );
// Create without auto-initialization
const session2 = await client . createSession ( 'server2' , false );
await session2 . connect ();
await session2 . initialize ();
// Create all configured sessions
const sessions = await client . createAllSessions ();
Connection States
Each session goes through these states (src/session.ts:55):
Created : Session object exists but not connected
Connecting : Establishing transport connection
Connected : Transport ready, performing MCP handshake
Initialized : Ready for operations
Disconnected : Connection closed
const session = new MCPSession ( connector , false );
console . log ( session . isConnected ); // false
await session . connect ();
console . log ( session . isConnected ); // true
await session . initialize ();
console . log ( 'Ready for operations' );
await session . disconnect ();
console . log ( session . isConnected ); // false
Graceful Shutdown
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ( './config.json' );
try {
await client . createAllSessions ();
// Use client...
} finally {
// Always cleanup
await client . close (); // Closes executors and all sessions
}
// Or in shutdown handler
process . on ( 'SIGINT' , async () => {
console . log ( 'Shutting down...' );
await client . close ();
process . exit ( 0 );
});
Connection Examples
Multi-Transport Setup
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ({
mcpServers: {
// Local stdio servers
'filesystem' : {
command: 'npx' ,
args: [ '-y' , '@modelcontextprotocol/server-filesystem' , '/data' ]
},
'postgres' : {
command: 'npx' ,
args: [ '-y' , '@modelcontextprotocol/server-postgres' ],
env: { DATABASE_URL: process . env . DATABASE_URL }
},
// Remote HTTP servers
'brave-search' : {
url: 'https://mcp.brave.com/mcp' ,
authToken: process . env . BRAVE_API_KEY
},
'anthropic' : {
url: 'https://api.anthropic.com/mcp' ,
headers: {
'X-API-Key' : process . env . ANTHROPIC_API_KEY
},
preferSse: true
}
}
});
// Create all sessions
const sessions = await client . createAllSessions ();
console . log ( `Connected to ${ Object . keys ( sessions ). length } servers` );
Connection with Retry
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ( './config.json' );
async function connectWithRetry (
serverName : string ,
maxRetries : number = 3
) : Promise < MCPSession | null > {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
const session = await client . createSession ( serverName );
console . log ( `Connected to ${ serverName } ` );
return session ;
} catch ( error ) {
console . error ( `Attempt ${ i + 1 } failed:` , error . message );
if ( i < maxRetries - 1 ) {
await new Promise ( resolve => setTimeout ( resolve , 1000 * ( i + 1 )));
}
}
}
return null ;
}
const session = await connectWithRetry ( 'my-server' );
if ( ! session ) {
console . error ( 'Failed to connect after retries' );
}
Conditional Connection
import { MCPClient } from 'mcp-use' ;
const client = new MCPClient ( './config.json' );
const results = await Promise . allSettled (
client . getServerNames (). map ( name =>
client . createSession ( name )
)
);
const connected = results
. filter ( r => r . status === 'fulfilled' )
. map ( r => ( r as PromiseFulfilledResult < MCPSession >). value );
const failed = results
. filter ( r => r . status === 'rejected' )
. map ( r => ( r as PromiseRejectedResult ). reason );
console . log ( `Connected: ${ connected . length } ` );
console . log ( `Failed: ${ failed . length } ` );
Next Steps
Sessions Learn about session management and operations
Configuration Master configuration options and formats