Skip to main content
Glama

MCP Todoist

by kentaroh7777
phase3_tools-section.md5.54 kB
# Task 3: ツールセクション実装 ## 概要 MCPTesterのツールセクションを実装し、MCPサーバーのツール一覧表示・実行機能を追加する。テストケースが期待するdata-testid要素に対応する。 ## 依存関係 - **前提タスク**: Task 1 (ExtendedConvexMCPClient), Task 2 (MCPTester基本構造) - **依存成果物**: `packages/web-ui/lib/mcp/extended-convex-client.ts`, `packages/web-ui/components/MCPTester.tsx` ### 前提条件 - ExtendedConvexMCPClient実装済み - MCPTester基本構造(5セクション)実装済み ### 成果物 - **修正**: `packages/web-ui/components/MCPTester.tsx` のToolsSection部分 ### 影響範囲 - ToolsSectionコンポーネントの実装 - MCPツール実行機能の追加 ## 実装要件 ### 【必須制約】追加すべきdata-testid要素 ```typescript // Phase 3で追加すべきdata-testid要素 const TOOLS_TEST_IDS = [ 'tool-select', // ツール選択セレクトボックス 'tool-params-form', // ツール実行パラメータフォーム 'execute-tool-button', // ツール実行ボタン 'tool-result-display' // ツール実行結果表示 ]; ``` ### 技術仕様 ```typescript interface MCPTool { name: string; description?: string; inputSchema: JSONSchema; } interface ToolExecution { toolName: string; parameters: Record<string, any>; result?: any; error?: string; timestamp: Date; } ``` ## 実装ガイド ### ステップ1: ツール一覧の取得と表示 ```typescript function ToolsSection({ state, setState, client }: SectionProps) { const [selectedTool, setSelectedTool] = useState<string>(''); const [toolParams, setToolParams] = useState<Record<string, any>>({}); const [executing, setExecuting] = useState(false); const [result, setResult] = useState<any>(null); // ツール一覧取得 useEffect(() => { if (state.connectionState === 'connected') { loadTools(); } }, [state.connectionState]); const loadTools = async () => { try { const tools = await client.listTools(); setState(prev => ({ ...prev, tools })); } catch (error) { console.error('ツール一覧取得エラー:', error); } }; return ( <div data-testid="tools-section" className="space-y-4"> {state.connectionState !== 'connected' ? ( <Alert message="MCPサーバーに接続してください" type="warning" /> ) : ( <> <div> <label className="block mb-2">ツール選択:</label> <Select data-testid="tool-select" value={selectedTool} onChange={setSelectedTool} placeholder="実行するツールを選択" style={{ width: '100%' }} > {state.tools.map(tool => ( <Select.Option key={tool.name} value={tool.name}> {tool.name} - {tool.description} </Select.Option> ))} </Select> </div> {selectedTool && ( <ToolParametersForm tool={selectedTool} toolSchema={getToolSchema(selectedTool)} parameters={toolParams} onChange={setToolParams} /> )} <Button data-testid="execute-tool-button" type="primary" onClick={handleExecuteTool} loading={executing} disabled={!selectedTool} > ツール実行 </Button> {result && ( <ToolResultDisplay result={result} /> )} </> )} </div> ); } ``` ### ステップ2: パラメータフォームの実装 ```typescript function ToolParametersForm({ tool, toolSchema, parameters, onChange }: { tool: string; toolSchema: any; parameters: Record<string, any>; onChange: (params: Record<string, any>) => void; }) { return ( <div data-testid="tool-params-form" className="space-y-4"> <h4>パラメータ</h4> {Object.entries(toolSchema.properties || {}).map(([key, schema]: [string, any]) => ( <div key={key}> <label className="block mb-1">{key}:</label> <Input value={parameters[key] || ''} onChange={e => onChange({ ...parameters, [key]: e.target.value })} placeholder={schema.description} /> </div> ))} </div> ); } ``` ### ステップ3: 実行結果表示の実装 ```typescript function ToolResultDisplay({ result }: { result: any }) { return ( <div data-testid="tool-result-display" className="space-y-2"> <h4>実行結果</h4> <pre className="bg-gray-100 p-4 rounded overflow-auto"> {JSON.stringify(result, null, 2)} </pre> </div> ); } ``` ## 検証基準 ### 機能検証 - [ ] MCPサーバー接続時にツール一覧が表示される - [ ] ツール選択時にパラメータフォームが表示される - [ ] ツール実行が正常に動作する - [ ] 実行結果が適切に表示される ### テスト互換性検証 - [ ] 以下のdata-testid要素が存在する: - [ ] tool-select - [ ] tool-params-form - [ ] execute-tool-button - [ ] tool-result-display ### 技術検証 - [ ] TypeScript strict modeでコンパイル成功 - [ ] ExtendedConvexMCPClientとの統合が正常動作 - [ ] エラーハンドリングが適切に実装されている

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/kentaroh7777/mcp-todoist'

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