Interactive CLI client and library for Model Context Protocol (MCP) servers with OAuth 2.0 support.
- Dual Purpose: Use as CLI tool or integrate as a library
- OAuth 2.0 Authentication: Seamless browser-based OAuth flow
- Transport Fallback: Automatic fallback from Streamable HTTP to SSE
- Interactive Shell: Command-line interface for tool discovery and execution
- Real-time Notifications: Support for server-sent notifications
- Event-driven API: Clean library interface with event emitters
- TypeScript Support: Full TypeScript definitions included
- Cross-platform: Works on Windows, macOS, and Linux
# Connect to default server (http://localhost:3000/mcp)
mcp-cli
# Connect to specific server
mcp-cli http://localhost:8080/mcp
mcp-cli https://example.com/mcp
# Set default server URL
export MCP_SERVER_URL=http://localhost:8080/mcp
mcp-cli
Once connected, you can use these commands:
- list - List available tools
- tool-details <name> - Show detailed schema for a tool
- call <tool_name> [args] - Call a tool with JSON arguments
- notifications [interval] [count] - Start notification stream
- status - Show connection status
- help - Show help message
- quit - Exit the client
# List all available tools
mcp> list
# Get details about a specific tool
mcp> tool-details file-operations
# Call a tool with arguments
mcp> call my-tool {"param": "value", "number": 42}
# Start notification stream (interval: 1000ms, count: 10)
mcp> notifications 1000 10
import { MCPClient, BrowserOAuthHandler } from 'mcp-cli';
const client = new MCPClient({
callbackPort: 8090,
oauthHandler: new BrowserOAuthHandler()
});
// Set up event handlers
client.on('connected', (transport) => {
console.log(`Connected via ${transport}`);
});
client.on('error', (error) => {
console.error('Connection error:', error);
});
// Connect to server
await client.connect('http://localhost:3000/mcp');
// List available tools
const tools = await client.listTools();
console.log('Available tools:', tools);
// Call a tool
const result = await client.callTool('my-tool', { param: 'value' });
console.log('Tool result:', result);
// Clean up
await client.close();
interface MCPClientConfig {
callbackPort?: number; // OAuth callback port (default: 8090)
oauthMetadata?: OAuthClientMetadata; // Custom OAuth metadata
transportPriority?: TransportType[]; // Transport preference order
connectionTimeout?: number; // Connection timeout in ms
oauthHandler?: OAuthHandler; // Custom OAuth handler
}
import { CustomOAuthHandler } from 'mcp-cli';
class MyOAuthHandler extends CustomOAuthHandler {
async handleRedirect(url: string): Promise<void> {
// Custom redirect handling (e.g., show in app UI)
console.log('Please visit:', url);
}
async waitForCallback(): Promise<string> {
// Custom callback handling (e.g., from app UI)
return await getAuthCodeFromUI();
}
}
const client = new MCPClient({
oauthHandler: new MyOAuthHandler()
});
client.on('connected', (transport) => {
console.log(`Connected using ${transport} transport`);
});
client.on('disconnected', () => {
console.log('Disconnected from server');
});
client.on('oauth-redirect', (url) => {
console.log('OAuth redirect:', url);
});
client.on('oauth-callback-received', (code) => {
console.log('OAuth code received');
});
client.on('notification', (notification) => {
console.log('Server notification:', notification);
});
client.on('error', (error) => {
console.error('Client error:', error);
});
// Get connection status
const status = client.getConnectionStatus();
console.log('Connected:', status.isConnected);
console.log('Transport:', status.transportType);
console.log('Has OAuth:', status.hasOAuth);
// Get tool details
const toolDetails = await client.getToolDetails('my-tool');
if (toolDetails) {
console.log('Tool schema:', toolDetails.inputSchema);
}
// Access underlying SDK client (for advanced usage)
const sdkClient = client.getClient();
if (sdkClient) {
// Use SDK client directly
}
The system automatically handles OAuth 2.0 authentication:
- When connecting to a server that requires OAuth, the system will trigger the OAuth handler
- Default handler opens your browser for authorization
- Custom handlers can implement different flows (mobile apps, web apps, etc.)
- The system automatically receives the authorization code and completes the connection
- Tokens are managed automatically for the session duration
The client tries connection methods in this order:
- Streamable HTTP with OAuth - Primary method with full OAuth support
- SSE (Server-Sent Events) - Fallback method with limited OAuth support
Full TypeScript definitions are included:
import {
MCPClient,
BrowserOAuthHandler,
CustomOAuthHandler,
MCPClientConfig,
OAuthHandler,
TransportType,
ToolDetails,
Tool,
OAuthClientMetadata
} from 'mcp-cli';
The library and CLI provide comprehensive error handling:
- Connection refused errors include server status checks
- Timeout errors suggest network troubleshooting
- OAuth errors provide authorization guidance
- All errors are properly typed and include helpful messages
git clone <repository-url>
cd mcp-cli
npm install
npm run build
npm run dev # Watch mode
npm start # Run built CLI version
src/
├── lib/ # Library code
│ ├── mcp-client.ts # Main client class
│ ├── connection-manager.ts # Connection handling
│ ├── oauth-handlers.ts # OAuth implementations
│ ├── types.ts # TypeScript interfaces
│ └── index.ts # Public API exports
├── cli/ # CLI-specific code
│ ├── cli.ts # CLI entry point
│ └── commands/ # CLI commands
├── client/ # Interactive client
└── auth/ # Authentication utilities
- Node.js 18.0.0 or higher
- Modern web browser (for default OAuth flow)
MIT