Skip to main content
Glama
client-setup.md15.3 kB
--- sidebar_position: 3 --- # Client Setup Learn how to set up various clients to work with Brummer's MCP server. ## VSCode Extension ### Installation 1. Install the MCP VSCode extension: ```bash code --install-extension mcp.vscode-mcp-client ``` 2. Configure MCP settings in VSCode: ```json { "mcp.servers": { "brummer": { "command": "brum", "args": ["--mcp"], "env": { "BRUMMER_MCP_MODE": "stdio" } } } } ``` ### Usage Access Brummer from VSCode: 1. Open Command Palette (`Ctrl+Shift+P`) 2. Type "MCP: Connect to Brummer" 3. Use MCP panel to interact with processes ### Features - View running processes - Start/stop scripts - Search logs - View errors inline - Quick navigation to error locations ## Claude Code ### Configuration 1. Add Brummer to Claude Code's MCP config: ```json // ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) // ~/.config/Claude/claude_desktop_config.json (Linux) // %APPDATA%\Claude\claude_desktop_config.json (Windows) { "mcpServers": { "brummer": { "command": "brum", "args": ["--mcp"], "env": { "BRUMMER_MCP_MODE": "stdio" } } } } ``` 2. Restart Claude Code ### Available Commands Claude can now: - Monitor your development processes - Access build logs and errors - Execute npm scripts - Check server status - Debug issues with full context Example prompts: - "Check if the dev server is running" - "Show me recent errors from the build process" - "Restart the API server" - "What's causing the test failures?" ## Cursor ### Setup 1. Install Cursor MCP extension 2. Add Brummer configuration: ```json // .cursor/settings.json { "mcp.servers": [ { "name": "brummer", "command": "brum", "args": ["--mcp"], "env": { "BRUMMER_MCP_MODE": "stdio" } } ] } ``` ### Integration Features - Inline error display - Quick fixes from Brummer errors - Process status in status bar - Log search from editor ## Node.js Client ### Installation ```bash npm install @modelcontextprotocol/sdk ``` ### Basic Client ```javascript import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; const transport = new StdioClientTransport({ command: 'brum', args: ['--mcp'] }); const client = new Client({ name: 'my-mcp-client', version: '1.0.0' }, { capabilities: {} }); await client.connect(transport); // Make requests using tools/call const result = await client.request({ method: 'tools/call', params: { name: 'scripts_status' } }, {}); console.log(result); ``` ### Advanced Client ```javascript class BrummerClient { constructor() { this.client = null; this.transport = null; } async connect() { this.transport = new StdioClientTransport({ command: 'brum', args: ['--mcp'], env: { ...process.env, BRUMMER_MCP_MODE: 'stdio' } }); this.client = new Client({ name: 'brummer-client', version: '1.0.0' }, { capabilities: { tools: true, resources: true } }); await this.client.connect(this.transport); // Client is now ready for tool calls } async getProcesses() { const response = await this.client.request({ method: 'tools/call', params: { name: 'scripts_status' } }, {}); return response.result; } async startProcess(name, options = {}) { return await this.client.request({ method: 'tools/call', params: { name: 'scripts_run', arguments: { name, ...options } } }, {}); } async getLogs(options = {}) { return await this.client.request({ method: 'tools/call', params: { name: 'logs_stream', arguments: options } }, {}); } handleEvent(event) { console.log('Event:', event.type, event.data); } async disconnect() { await this.client.close(); } } // Usage const brummer = new BrummerClient(); await brummer.connect(); const processes = await brummer.getProcesses(); console.log('Running processes:', processes); await brummer.disconnect(); ``` ## Python Client ### Installation ```bash pip install mcp-client ``` ### Example Client ```python import asyncio from mcp import Client, StdioTransport class BrummerClient: def __init__(self): self.client = None async def connect(self): transport = StdioTransport( command="brum", args=["--mcp"] ) self.client = Client( name="python-brummer-client", version="1.0.0" ) await self.client.connect(transport) async def get_processes(self): response = await self.client.request( method="tools/call", params={ "name": "scripts_status" } ) return response["result"] async def start_process(self, name, **kwargs): return await self.client.request( method="tools/call", params={ "name": "scripts_run", "arguments": {"name": name, **kwargs} } ) async def get_logs(self, **filters): return await self.client.request( method="tools/call", params={ "name": "logs_stream", "arguments": filters } ) async def stream_logs(self, process_name=None): # Note: Streaming requires HTTP transport response = await self.client.request( method="tools/call", params={ "name": "logs_stream", "arguments": {"processId": process_name, "follow": True} } ) return response["result"] async def disconnect(self): await self.client.close() # Usage async def main(): client = BrummerClient() await client.connect() # Get all processes processes = await client.get_processes() for process in processes: print(f"{process['name']}: {process['status']}") # Start a process result = await client.start_process("dev") print(f"Started: {result['success']}") # Stream logs async for log in client.stream_logs("dev"): print(f"[{log['level']}] {log['message']}") await client.disconnect() if __name__ == "__main__": asyncio.run(main()) ``` ## Browser Client (HTTP) ### Vanilla JavaScript ```javascript class BrummerHTTPClient { constructor(baseUrl = 'http://localhost:7777') { this.baseUrl = baseUrl; this.requestId = 0; } async request(method, params = {}) { const id = ++this.requestId; const response = await fetch(`${this.baseUrl}/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id, method, params }) }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const result = await response.json(); if (result.error) { throw new Error(result.error.message); } return result.result; } async getProcesses() { return this.request('tools/call', { name: 'scripts_status' }); } async startProcess(name, options = {}) { return this.request('tools/call', { name: 'scripts_run', arguments: { name, ...options } }); } async getLogs(filters = {}) { return this.request('tools/call', { name: 'logs_stream', arguments: filters }); } async streamLogs(filters = {}) { // Server-Sent Events for streaming const eventSource = new EventSource(`${this.baseUrl}/mcp`); return new Promise((resolve, reject) => { eventSource.onmessage = (event) => { try { const data = JSON.parse(event.data); if (data.type === 'log') { // Handle log entry console.log('Log:', data.data); } } catch (error) { reject(error); } }; eventSource.onerror = (error) => { reject(error); }; }); } } // Usage const client = new BrummerHTTPClient(); const processes = await client.getProcesses(); console.log('Processes:', processes); // Start streaming logs client.streamLogs({ follow: true }); ``` ### React Hook ```jsx import { useState, useEffect, useCallback } from 'react'; function useBrummer(baseUrl = 'http://localhost:7777') { const [client, setClient] = useState(null); const [connected, setConnected] = useState(false); const [processes, setProcesses] = useState([]); const [logs, setLogs] = useState([]); useEffect(() => { const brummerClient = new BrummerHTTPClient(baseUrl); setClient(brummerClient); setConnected(true); // Initial data fetch brummerClient.getProcesses().then((result) => { setProcesses(Array.isArray(result) ? result : [result]); }).catch(console.error); }, [baseUrl]); const startProcess = useCallback(async (name) => { if (!client) return; try { const result = await client.startProcess(name); // Refresh processes list const updatedProcesses = await client.getProcesses(); setProcesses(Array.isArray(updatedProcesses) ? updatedProcesses : [updatedProcesses]); return result; } catch (error) { console.error('Failed to start process:', error); throw error; } }, [client]); const stopProcess = useCallback(async (processId) => { if (!client) return; try { const result = await client.request('tools/call', { name: 'scripts_stop', arguments: { processId } }); // Refresh processes list const updatedProcesses = await client.getProcesses(); setProcesses(Array.isArray(updatedProcesses) ? updatedProcesses : [updatedProcesses]); return result; } catch (error) { console.error('Failed to stop process:', error); throw error; } }, [client]); const fetchLogs = useCallback(async (filters = {}) => { if (!client) return; try { const result = await client.getLogs(filters); setLogs(result); return result; } catch (error) { console.error('Failed to fetch logs:', error); throw error; } }, [client]); return { connected, processes, logs, startProcess, stopProcess, fetchLogs }; } // Component usage function ProcessManager() { const { connected, processes, startProcess, stopProcess } = useBrummer(); if (!connected) { return <div>Connecting to Brummer...</div>; } return ( <div> <h2>Processes</h2> {processes.map(process => ( <div key={process.processId || process.name}> <span>{process.name}</span> <span>{process.status}</span> {process.status === 'running' ? ( <button onClick={() => stopProcess(process.processId)}>Stop</button> ) : ( <button onClick={() => startProcess(process.name)}>Start</button> )} </div> ))} </div> ); } ``` ## CLI Client ### Direct Commands ```bash # Send MCP request via curl curl -X POST http://localhost:7777/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scripts_status"}}' # Start a process curl -X POST http://localhost:7777/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"scripts_run","arguments":{"name":"dev"}}}' # Get logs with pretty print curl -X POST http://localhost:7777/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"logs_search","arguments":{"query":".*","limit":10}}}' | jq ``` ### Shell Script Client ```bash #!/bin/bash # brummer-client.sh brummer_request() { local tool_name=$1 local args=${2:-'{}'} curl -s -X POST http://localhost:7777/mcp \ -H "Content-Type: application/json" \ -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"$tool_name\",\"arguments\":$args}}" | \ jq -r '.result' } # Get all processes processes=$(brummer_request "scripts_status") echo "Processes: $processes" # Start a process result=$(brummer_request "scripts_run" '{"name": "dev"}') echo "Start result: $result" # Get recent errors errors=$(brummer_request "logs_search" '{"query": "error", "level": "error", "limit": 5}') echo "Recent errors: $errors" ``` ## Testing MCP Integration ### Test Script ```javascript // test-mcp.js import { BrummerClient } from './brummer-client.js'; async function testMCPIntegration() { const client = new BrummerClient(); try { console.log('Connecting to Brummer MCP server...'); await client.connect(); console.log('✅ Connected'); // Test getting processes console.log('\nTesting scripts_status...'); const processes = await client.getProcesses(); console.log('✅ Processes:', processes); // Test starting a process console.log('\nTesting scripts_run...'); const startResult = await client.startProcess('dev'); console.log('✅ Start result:', startResult); // Test getting logs console.log('\nTesting logs_stream...'); const logs = await client.getLogs({ limit: 5 }); console.log('✅ Logs:', logs); // Test log search console.log('\nTesting logs_search...'); const errors = await client.request('tools/call', { name: 'logs_search', arguments: { query: 'error', level: 'error', limit: 5 } }); console.log('✅ Errors:', errors); console.log('\n✅ All tests passed!'); } catch (error) { console.error('❌ Test failed:', error); } finally { await client.disconnect(); } } testMCPIntegration(); ``` ## Troubleshooting ### Connection Issues 1. **Verify Brummer is running with MCP**: ```bash ps aux | grep "brum --mcp" ``` 2. **Check if MCP server is responding**: ```bash curl -X POST http://localhost:7777/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' ``` 3. **Enable debug logging**: ```bash BRUMMER_MCP_DEBUG=true brum --mcp ``` ### Common Errors - **"Method not found"**: Ensure you're using the correct method name - **"Invalid params"**: Check parameter types and required fields - **"Connection refused"**: Verify Brummer is running and MCP is enabled - **"Timeout"**: Increase client timeout or check system resources ## Best Practices 1. **Always handle connection errors** gracefully 2. **Implement reconnection logic** for long-running clients 3. **Use request IDs** for tracking multiple concurrent requests 4. **Subscribe to events** instead of polling for real-time updates 5. **Batch requests** when fetching multiple resources 6. **Clean up connections** properly when done 7. **Log MCP interactions** for debugging

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/standardbeagle/brummer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server