208 lines
6.0 KiB
TypeScript
208 lines
6.0 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* MCP Playground Component
|
|
*
|
|
* Interactive demo of Vibn's MCP capabilities
|
|
*/
|
|
|
|
import { useState } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Textarea } from '@/components/ui/textarea';
|
|
import { auth } from '@/lib/firebase/config';
|
|
import { toast } from 'sonner';
|
|
import { Code2, Database, MessageSquare, Zap } from 'lucide-react';
|
|
|
|
interface MCPRequest {
|
|
action: string;
|
|
params?: any;
|
|
}
|
|
|
|
export function MCPPlayground() {
|
|
const [loading, setLoading] = useState(false);
|
|
const [result, setResult] = useState<any>(null);
|
|
const [selectedTool, setSelectedTool] = useState<string | null>(null);
|
|
|
|
const callMCP = async (request: MCPRequest) => {
|
|
setLoading(true);
|
|
setResult(null);
|
|
|
|
try {
|
|
const user = auth.currentUser;
|
|
if (!user) {
|
|
toast.error('Please sign in to use MCP');
|
|
return;
|
|
}
|
|
|
|
const token = await user.getIdToken();
|
|
|
|
const response = await fetch('/api/mcp', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(request),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const error = await response.json();
|
|
throw new Error(error.error || 'MCP request failed');
|
|
}
|
|
|
|
const data = await response.json();
|
|
setResult(data);
|
|
toast.success('MCP request completed');
|
|
} catch (error) {
|
|
console.error('MCP error:', error);
|
|
toast.error(error instanceof Error ? error.message : 'MCP request failed');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const tools = [
|
|
{
|
|
id: 'list_resources',
|
|
name: 'List Resources',
|
|
description: 'View all available MCP resources',
|
|
icon: Database,
|
|
action: () => callMCP({ action: 'list_resources' }),
|
|
},
|
|
{
|
|
id: 'read_projects',
|
|
name: 'Read Projects',
|
|
description: 'Get all your projects via MCP',
|
|
icon: Code2,
|
|
action: () => {
|
|
const user = auth.currentUser;
|
|
if (!user) {
|
|
toast.error('Please sign in');
|
|
return;
|
|
}
|
|
callMCP({
|
|
action: 'read_resource',
|
|
params: { uri: `vibn://projects/${user.uid}` },
|
|
});
|
|
},
|
|
},
|
|
{
|
|
id: 'read_sessions',
|
|
name: 'Read Sessions',
|
|
description: 'Get all your coding sessions',
|
|
icon: Zap,
|
|
action: () => {
|
|
const user = auth.currentUser;
|
|
if (!user) {
|
|
toast.error('Please sign in');
|
|
return;
|
|
}
|
|
callMCP({
|
|
action: 'read_resource',
|
|
params: { uri: `vibn://sessions/${user.uid}` },
|
|
});
|
|
},
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="space-y-2">
|
|
<h2 className="text-2xl font-bold">MCP Playground</h2>
|
|
<p className="text-muted-foreground">
|
|
Test Vibn's Model Context Protocol capabilities. This is what AI assistants see when they
|
|
query your project data.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Tool Cards */}
|
|
<div className="grid gap-4 md:grid-cols-3">
|
|
{tools.map((tool) => (
|
|
<Card
|
|
key={tool.id}
|
|
className="cursor-pointer transition-all hover:shadow-md"
|
|
onClick={() => {
|
|
setSelectedTool(tool.id);
|
|
tool.action();
|
|
}}
|
|
>
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center gap-2">
|
|
<tool.icon className="h-5 w-5 text-primary" />
|
|
<CardTitle className="text-base">{tool.name}</CardTitle>
|
|
</div>
|
|
<CardDescription className="text-xs">{tool.description}</CardDescription>
|
|
</CardHeader>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
|
|
{/* Loading State */}
|
|
{loading && (
|
|
<Card>
|
|
<CardContent className="pt-6">
|
|
<div className="flex items-center justify-center p-8">
|
|
<div className="flex items-center gap-2">
|
|
<div className="h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" />
|
|
<span className="text-sm text-muted-foreground">Processing MCP request...</span>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Results */}
|
|
{result && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>MCP Response</CardTitle>
|
|
<CardDescription>
|
|
This is the data that would be sent to an AI assistant
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Textarea
|
|
value={JSON.stringify(result, null, 2)}
|
|
readOnly
|
|
className="min-h-[400px] font-mono text-xs"
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{/* Info Card */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base">About MCP</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2 text-sm text-muted-foreground">
|
|
<p>
|
|
The Model Context Protocol (MCP) is a standard that allows AI assistants to access your
|
|
project data in a secure and structured way.
|
|
</p>
|
|
<p>
|
|
With Vibn's MCP server, AI assistants like Claude or ChatGPT can:
|
|
</p>
|
|
<ul className="ml-6 list-disc space-y-1">
|
|
<li>View your projects and coding sessions</li>
|
|
<li>Analyze your development patterns</li>
|
|
<li>Reference past AI conversations for context</li>
|
|
<li>Provide insights based on your actual work</li>
|
|
</ul>
|
|
<p className="pt-2">
|
|
<a
|
|
href="/MCP_SETUP.md"
|
|
target="_blank"
|
|
className="text-primary hover:underline"
|
|
>
|
|
Learn how to set up MCP with your AI assistant →
|
|
</a>
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|
|
|