import { Alert, AlertDescription } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; import { CodeEditor } from "@/components/ui/codeEditor"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { getExampleBaseUrl } from "@/lib/utils/port"; import { useCopyToClipboard } from "@/hooks/useCopyToClipboard"; import { AlertTriangle, Copy } from "lucide-react"; import { useMemo, useState } from "react"; type Language = "python" | "typescript"; type Examples = { manual: { [L in Language]: string; }; agentMode: { [L in Language]: string; }; }; // Common editor options to reduce duplication const EditorOptions = { scrollBeyondLastLine: false, minimap: { enabled: false }, lineNumbers: "off", folding: false, lineDecorationsWidth: 0, lineNumbersMinChars: 0, glyphMargin: false, } as const; interface CodeBlockProps { code: string; language: string; onLanguageChange?: (language: string) => void; showLanguageSelect?: boolean; readonly?: boolean; } function CodeBlock({ code, language, onLanguageChange, showLanguageSelect = false, readonly = true }: CodeBlockProps) { const { copy: copyToClipboard } = useCopyToClipboard(); return (
{showLanguageSelect && onLanguageChange && ( )}
); } interface MCPEmptyStateProps { error?: string | null; statusIndicator?: React.ReactNode; } export function MCPEmptyState({ error, statusIndicator }: MCPEmptyStateProps) { const [language, setLanguage] = useState("python"); // Generate examples dynamically using the port utility const examples: Examples = useMemo(() => { const baseUrl = getExampleBaseUrl(); return { manual: { python: `import openai import requests # Step 1: Initialize OpenAI client with Bifrost client = openai.OpenAI( base_url="${baseUrl}/openai", api_key="dummy-api-key" # Handled by Bifrost ) # Step 2: Send chat request response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "List files in current directory"}] ) # Step 3: Check for tool calls message = response.choices[0].message if message.tool_calls: for tool_call in message.tool_calls: # Step 4: Execute tool via Bifrost tool_result = requests.post( "${baseUrl}/v1/mcp/tool/execute", json={ "id": tool_call.id, "type": "function", "function": { "name": tool_call.function.name, "arguments": tool_call.function.arguments } } ).json() # Step 5: Continue conversation with results final_response = client.chat.completions.create( model="gpt-4o", messages=[ {"role": "user", "content": "List files in current directory"}, message, tool_result ] ) print(final_response.choices[0].message.content)`, typescript: `import OpenAI from "openai"; // Step 1: Initialize OpenAI client with Bifrost const openai = new OpenAI({ baseURL: "${baseUrl}/openai", apiKey: "dummy-api-key", // Handled by Bifrost }); // Step 2: Send chat request const response = await openai.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "List files in current directory" }], }); const message = response.choices[0].message; // Step 3: Check for tool calls if (message.tool_calls) { for (const toolCall of message.tool_calls) { // Step 4: Execute tool via Bifrost const toolResult = await fetch("${baseUrl}/v1/mcp/tool/execute", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: toolCall.id, type: "function", function: { name: toolCall.function.name, arguments: toolCall.function.arguments, }, }), }).then(res => res.json()); // Step 5: Continue conversation with results const finalResponse = await openai.chat.completions.create({ model: "gpt-4o", messages: [ { role: "user", content: "List files in current directory" }, message, toolResult, ], }); console.log(finalResponse.choices[0].message.content); } }`, }, agentMode: { python: `import openai # Agent Mode enables autonomous tool execution # Configure auto-executable tools in MCP Gateway settings client = openai.OpenAI( base_url="${baseUrl}/openai", api_key="dummy-api-key" ) # With agent mode enabled, Bifrost automatically: # 1. Receives tool calls from LLM # 2. Executes auto-approved tools (e.g., read_file, list_directory) # 3. Feeds results back to LLM # 4. Returns final response after all iterations response = client.chat.completions.create( model="gpt-4o", messages=[{ "role": "user", "content": "List all Python files and summarize their purpose" }] ) # The response includes results from all auto-executed tools # Non-auto-executable tools (e.g., write_file) are returned for manual approval print(response.choices[0].message.content) # If there are pending non-auto-executable tools: if response.choices[0].message.tool_calls: print("Pending tools requiring approval:", [tc.function.name for tc in response.choices[0].message.tool_calls])`, typescript: `import OpenAI from "openai"; // Agent Mode enables autonomous tool execution // Configure auto-executable tools in MCP Gateway settings const openai = new OpenAI({ baseURL: "${baseUrl}/openai", apiKey: "dummy-api-key", }); // With agent mode enabled, Bifrost automatically: // 1. Receives tool calls from LLM // 2. Executes auto-approved tools (e.g., read_file, list_directory) // 3. Feeds results back to LLM // 4. Returns final response after all iterations const response = await openai.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "List all Python files and summarize their purpose" }], }); // The response includes results from all auto-executed tools // Non-auto-executable tools (e.g., write_file) are returned for manual approval console.log(response.choices[0].message.content); // If there are pending non-auto-executable tools: if (response.choices[0].message.tool_calls) { console.log("Pending tools requiring approval:", response.choices[0].message.tool_calls.map(tc => tc.function.name) ); }`, }, }; }, []); const isUnexpectedError = error && error.includes("An unexpected error occurred"); return (
{error && ( {isUnexpectedError ? "Looks like you haven't configured the log store in your config file." : error} )}

Get Started with MCP Tool Execution

Execute your first MCP tool call to see logs appear

{statusIndicator}
Manual Tool Execution Agent Mode (Auto-Execute)

Full control over tool approval. You explicitly execute each tool call via the API.

setLanguage(newLang as Language)} showLanguageSelect />

Autonomous execution for pre-approved tools. Configure auto-executable tools in MCP Gateway settings.

setLanguage(newLang as Language)} showLanguageSelect />

Prerequisites

  • 1. Configure MCP servers in the MCP Gateway (e.g., filesystem, web_search)
  • 2. Set tools_to_execute to whitelist available tools
  • 3. For Agent Mode: Configure tools_to_auto_execute for autonomous execution
); }