React
The useMcp hook provides a simple way to manage MCP connections in React applications.
Basic Usage
import { useMcp } from '@mcp-ts/sdk/client';
function MyComponent() {
const { connections, connect, disconnect, status } = useMcp({
url: '/api/mcp',
identity: 'user-123',
});
return (
<div>
<p>Status: {status}</p>
{connections.map(conn => (
<div key={conn.sessionId}>
<h3>{conn.serverName}</h3>
<p>{conn.state}</p>
</div>
))}
</div>
);
}
Configuration Options
useMcp({
// Required: SSE endpoint URL
url: '/api/mcp',
// Required: User identifier
identity: 'user-123',
// Optional: Authentication token
authToken: 'your-auth-token',
// Optional: Auto-connect SSE on mount (default: true)
autoConnect: true,
// Optional: Auto-load sessions on mount (default: true)
autoInitialize: true,
// Optional: Connection event handler
onConnectionEvent: (event) => {
console.log('Event:', event);
},
// Optional: Debug log handler
onLog: (level, message, metadata) => {
console.log(`[${level}] ${message}`, metadata);
},
})
Return Values
State
const {
// Connection list
connections, // Connection[] - All active connections
status, // SSEStatus - SSE connection status
isInitializing, // boolean - Loading initial sessions
// ... methods below
} = useMcp({...});
Connection Methods
// Connect to an MCP server
const sessionId = await connect({
serverId: 'server-id',
serverName: 'My Server',
serverUrl: 'https://mcp.example.com',
callbackUrl: window.location.origin + '/callback',
// transportType: 'auto', // optional: defaults to auto-negotiate (Streamable -> SSE)
});
// Disconnect from a server
await disconnect(sessionId);
// Reload all sessions
await refresh();
// Manually control SSE connection
connectSSE();
disconnectSSE();
// Complete OAuth flow
await finishAuth(code, state);
Tool Operations
// Call a tool
const result = await callTool(sessionId, 'tool_name', {
arg1: 'value',
});
// List available tools
const tools = await listTools(sessionId);
Prompt Operations
// List available prompts
const { prompts } = await listPrompts(sessionId);
// Get a specific prompt
const prompt = await getPrompt(sessionId, 'prompt_name', {
arg1: 'value',
});
Resource Operations
// List available resources
const { resources } = await listResources(sessionId);
// Read a specific resource
const resource = await readResource(sessionId, 'file:///path');
Utility Methods
// Get connection by session ID
const conn = getConnection(sessionId);
// Get connection by server ID
const conn = getConnectionByServerId(serverId);
// Check if server is connected
const isConnected = isServerConnected(serverId);
// Get tools for a session
const tools = getTools(sessionId);
Connection Object
Each connection has the following structure:
interface Connection {
sessionId: string;
serverId: string;
serverName: string;
serverUrl: string;
state: McpConnectionState;
tools: ToolInfo[];
error?: string;
timestamp: number;
}
Connection States
Connections progress through these states:
type McpConnectionState =
| 'DISCONNECTED' // Not connected
| 'CONNECTING' // Attempting to connect
| 'AUTHENTICATING' // OAuth in progress
| 'AUTHENTICATED' // OAuth complete
| 'DISCOVERING' // Loading tools
| 'CONNECTED' // Fully connected
| 'VALIDATING' // Validating session
| 'RECONNECTING' // Reconnecting
| 'FAILED'; // Connection failed
Event Handling
Handle connection events for custom logic:
const { connections } = useMcp({
url: '/api/mcp',
identity: 'user-123',
onConnectionEvent: (event) => {
switch (event.type) {
case 'state_changed':
console.log('State:', event.state);
break;
case 'tools_discovered':
console.log('Tools:', event.tools);
break;
case 'auth_required':
// Redirect to OAuth
window.location.href = event.authUrl;
break;
case 'error':
console.error('Error:', event.error);
break;
case 'disconnected':
console.log('Disconnected:', event.reason);
break;
}
},
});
Examples
Connect and Call Tool
function ToolCaller() {
const { connections, connect, callTool } = useMcp({
url: '/api/mcp',
identity: 'user-123',
});
const handleConnect = async () => {
const sessionId = await connect({
serverId: 'weather-server',
serverName: 'Weather Server',
serverUrl: 'https://weather-mcp.example.com',
callbackUrl: window.location.origin + '/api/mcp/callback',
});
// Call a tool after connecting
const result = await callTool(sessionId, 'get_weather', {
location: 'San Francisco',
});
console.log('Weather:', result);
};
return <button onClick={handleConnect}>Get Weather</button>;
}
Display Connection Status
function ConnectionStatus() {
const { connections, status } = useMcp({
url: '/api/mcp',
identity: 'user-123',
});
return (
<div>
<p>SSE Status: {status}</p>
{connections.map(conn => (
<div key={conn.sessionId}>
<h3>{conn.serverName}</h3>
<div>
State: <span style={{
color: conn.state === 'CONNECTED' ? 'green' : 'orange'
}}>
{conn.state}
</span>
</div>
{conn.state === 'CONNECTED' && (
<p>Tools: {conn.tools.length}</p>
)}
{conn.error && (
<p style={{ color: 'red' }}>Error: {conn.error}</p>
)}
</div>
))}
</div>
);
}
Handle OAuth Redirect
function McpWithAuth() {
const { connect } = useMcp({
url: '/api/mcp',
identity: 'user-123',
onConnectionEvent: (event) => {
if (event.type === 'auth_required') {
// Redirect to OAuth page
window.location.href = event.authUrl;
}
},
});
return (
<button onClick={() => connect({
serverId: 'protected-server',
serverName: 'Protected Server',
serverUrl: 'https://secure-mcp.example.com',
callbackUrl: window.location.origin + '/oauth/callback-popup',
})}>
Connect (will redirect for auth)
</button>
);
}
TypeScript Types
Import types for better type safety:
import type {
McpConnectionState,
McpConnectionEvent,
ToolInfo,
} from '@mcp-ts/sdk/shared';
import type {
McpClient, // Return type of useMcp
} from '@mcp-ts/sdk/client';
Next Steps
- API Reference - Complete API documentation
- Examples - More practical examples