diff --git a/api-reference/client-api/connection-management.mdx b/api-reference/client-api/connection-management.mdx index 7e7a22d..ee99918 100644 --- a/api-reference/client-api/connection-management.mdx +++ b/api-reference/client-api/connection-management.mdx @@ -1,5 +1,5 @@ --- -title: "Connection Management" +title: "Connection management" description: "Learn how to establish and manage MCP client connections" --- diff --git a/api-reference/client-api/resource-consumption.mdx b/api-reference/client-api/resource-consumption.mdx index e00a548..2cac05d 100644 --- a/api-reference/client-api/resource-consumption.mdx +++ b/api-reference/client-api/resource-consumption.mdx @@ -1,5 +1,5 @@ --- -title: "Resource Consumption" +title: "Resource consumption" description: "Learn how to consume resources from MCP servers" --- diff --git a/api-reference/client-api/tool-invocation.mdx b/api-reference/client-api/tool-invocation.mdx index 7d9f700..7c12613 100644 --- a/api-reference/client-api/tool-invocation.mdx +++ b/api-reference/client-api/tool-invocation.mdx @@ -1,5 +1,5 @@ --- -title: "Tool Invocation" +title: "Tool invocation" description: "Learn how to invoke tools through the MCP client API" --- diff --git a/api-reference/error-handling.mdx b/api-reference/error-handling.mdx index 3a8d864..1cf9e9a 100644 --- a/api-reference/error-handling.mdx +++ b/api-reference/error-handling.mdx @@ -1,5 +1,5 @@ --- -title: 'Error Handling' +title: 'Error handling' description: 'How to handle and respond to errors in the Model Context Protocol' --- diff --git a/api-reference/message-types.mdx b/api-reference/message-types.mdx index a5d2387..5690c7b 100644 --- a/api-reference/message-types.mdx +++ b/api-reference/message-types.mdx @@ -1,5 +1,5 @@ --- -title: 'Message Types' +title: 'Message types' description: 'Understanding the different types of messages in the Model Context Protocol' --- diff --git a/api-reference/protocol-overview.mdx b/api-reference/protocol-overview.mdx index a650ab5..b6677e7 100644 --- a/api-reference/protocol-overview.mdx +++ b/api-reference/protocol-overview.mdx @@ -1,5 +1,5 @@ --- -title: "Protocol Overview" +title: "Protocol overview" description: "Learn about the core concepts and architecture of the Model Context Protocol (MCP)" --- @@ -22,10 +22,8 @@ The Model Context Protocol (MCP) is a standardized protocol that enables AI appl -# Core concepts - +## Core concepts MCP defines several key primitives that form the foundation of the protocol: - Data that can be loaded as context for the AI model. Resources have URIs and can contain text or binary data. @@ -41,12 +39,10 @@ MCP defines several key primitives that form the foundation of the protocol: -# Protocol flow - -## Connection and initialization +## Protocol flow +### Connection and initialization When a client connects to an MCP server, they go through the following initialization sequence: - The client establishes a connection to the server using one of the supported transports. @@ -64,10 +60,8 @@ When a client connects to an MCP server, they go through the following initializ After initialization, the client can begin using the server's resources, tools, and other capabilities. -## Transport options - +### Transport options MCP supports multiple transport mechanisms for client-server communication: - - Server process reads from stdin and writes to stdout diff --git a/api-reference/python/class-reference.mdx b/api-reference/python/class-reference.mdx index 1ebd5bc..8887cde 100644 --- a/api-reference/python/class-reference.mdx +++ b/api-reference/python/class-reference.mdx @@ -1,9 +1,9 @@ --- -title: "Python Class Reference" +title: "Python class reference" description: "Complete Python SDK class documentation" --- -## Server Class +## Server class The main class for implementing MCP servers in Python. @@ -25,7 +25,7 @@ Creates a new MCP server instance. ### Decorators -#### Resource Handling +#### Resource handling ##### @server.list_resources() ```python @@ -72,7 +72,7 @@ async def unsubscribe_resource(uri: str) -> None: **Parameters:** - `uri` (str): Resource URI to unsubscribe from -#### Tool Support +#### Tool support ##### @server.list_tools() ```python @@ -99,7 +99,7 @@ async def call_tool(name: str, **kwargs) -> Any: **Returns:** Tool execution result (any JSON-serializable value) -#### Prompt Management +#### Prompt management ##### @server.list_prompts() ```python @@ -128,7 +128,7 @@ async def get_prompt(name: str, arguments: dict) -> PromptResponse: - `messages` (List[Message]): List of prompt messages - `description` (str, optional): Description of the prompt response -### Session Methods +### Session methods Methods available on the server session object: @@ -158,7 +158,7 @@ async def send_log_message( """Sends log messages to clients.""" ``` -## Data Classes +## Data classes ### Resource ```python @@ -204,7 +204,7 @@ class PromptResponse: description: Optional[str] = None ``` -## Example Usage +## Example usage Here's a complete example demonstrating the main features: @@ -263,7 +263,7 @@ if __name__ == "__main__": anyio.run(main) ``` -## Best Practices +## Best practices 1. **Error Handling**: Always implement proper error handling in your server methods: ```python @@ -303,15 +303,15 @@ if __name__ == "__main__": await session.send_resource_updated("example://resource1") ``` -## Transport Options +## Transport options -### stdio Transport +### Stdio transport ```python async with stdio_server() as (read_stream, write_stream): await server.run(read_stream, write_stream) ``` -### SSE Transport +### SSE transport ```python from mcp_python.transport import SSETransport @@ -327,7 +327,7 @@ async def message_endpoint(request: Request): return await transport.handle_message(request) ``` -### WebSocket Transport +### WebSocket transport ```python from mcp_python.transport import WebSocketTransport diff --git a/api-reference/python/type-hints.mdx b/api-reference/python/type-hints.mdx index 1b76006..edb07b5 100644 --- a/api-reference/python/type-hints.mdx +++ b/api-reference/python/type-hints.mdx @@ -1,11 +1,11 @@ --- -title: "Python Type Hints" +title: "Python type hints" description: "Python type system documentation" --- -## Core Types +## Core types -### Resource Types +### Resource types ```python from typing import TypedDict, Optional, Literal, Union, List @@ -38,7 +38,7 @@ class BlobResourceContents(ResourceContents): blob: bytes # Base64 encoded ``` -### Message Types +### Message types ```python class TextContent(TypedDict): @@ -60,7 +60,7 @@ class Message(TypedDict): content: MessageContent ``` -### Tool Types +### Tool types ```python class ToolParameter(TypedDict): @@ -82,7 +82,7 @@ class Tool(TypedDict): inputSchema: ToolSchema ``` -### Prompt Types +### Prompt types ```python class PromptArgument(TypedDict): @@ -103,7 +103,7 @@ class PromptResponse(TypedDict): messages: List[Message] ``` -### Progress Types +### Progress types ```python class Progress(TypedDict): @@ -112,7 +112,7 @@ class Progress(TypedDict): total: Optional[int] ``` -### Logging Types +### Logging types ```python LogLevel = Literal["debug", "info", "warning", "error"] @@ -124,9 +124,9 @@ class LogMessage(TypedDict): data: Any # JSON-serializable value ``` -## Request/Response Types +## Request/Response types -### Resource Requests +### Resource requests ```python class ListResourcesRequest(TypedDict): @@ -155,7 +155,7 @@ class UnsubscribeRequest(TypedDict): uri: str ``` -### Tool Requests +### Tool requests ```python class ListToolsRequest(TypedDict): @@ -177,7 +177,7 @@ class CallToolResponse(TypedDict): toolResult: Any # JSON-serializable value ``` -### Prompt Requests +### Prompt requests ```python class ListPromptsRequest(TypedDict): @@ -195,7 +195,7 @@ class GetPromptRequest(TypedDict): arguments: Optional[dict[str, str]] ``` -## Protocol Types +## Protocol types ### Implementation Info @@ -231,9 +231,9 @@ class ServerCapabilities(TypedDict): tools: Optional[ToolCapabilities] ``` -## Transport Types +## Transport types -### Stream Types +### Stream types ```python class ReadStream(Protocol): @@ -245,7 +245,7 @@ class WriteStream(Protocol): async def write(self, data: bytes) -> None: ... ``` -### Session Types +### Session types ```python class ServerSession(Protocol): @@ -259,9 +259,9 @@ class ServerSession(Protocol): ) -> None: ... ``` -## Usage Examples +## Usage examples -### Type Usage in Handlers +### Type usage in handlers ```python from mcp_python.server import Server @@ -314,7 +314,7 @@ async def get_prompt(name: str, arguments: dict) -> PromptResponse: } ``` -### Type Checking +### Type checking ```python from typing import TypeGuard @@ -330,7 +330,7 @@ def process_message(message: Message) -> str: return f"Image message with type: {content['mimeType']}" ``` -## Additional Notes +## Additional notes - All types are compatible with standard Python type checkers (mypy, pyright) - TypedDict is used extensively to ensure proper structure of JSON-like objects diff --git a/api-reference/server-api/event-handling.mdx b/api-reference/server-api/event-handling.mdx index 674ae4d..f870ebe 100644 --- a/api-reference/server-api/event-handling.mdx +++ b/api-reference/server-api/event-handling.mdx @@ -1,11 +1,11 @@ --- -title: "Event Handling" +title: "Event handling" description: "Handle events and manage state in your MCP server" --- MCP servers process various events including requests, notifications, and connection lifecycle events. This guide explains how to implement event handlers effectively in your server. -## Request handlers +## Request handling Request handlers process incoming requests from clients and must return a response. Each handler is associated with a specific method name. @@ -62,7 +62,7 @@ async def handle_list_tools(request: ListToolsRequest) -> ListToolsResult: ``` -## Notification handlers +## Notification handling Notification handlers process one-way messages that don't require responses. They're useful for handling events like resource updates or logging messages. diff --git a/api-reference/server-api/resource-management.mdx b/api-reference/server-api/resource-management.mdx index 380695a..1bcbf1c 100644 --- a/api-reference/server-api/resource-management.mdx +++ b/api-reference/server-api/resource-management.mdx @@ -1,5 +1,5 @@ --- -title: "Resource Management" +title: "Resource management" description: "How to implement resource management in your MCP server" --- diff --git a/api-reference/server-api/tool-implementation.mdx b/api-reference/server-api/tool-implementation.mdx index 2cb51ed..b98b3c2 100644 --- a/api-reference/server-api/tool-implementation.mdx +++ b/api-reference/server-api/tool-implementation.mdx @@ -1,5 +1,5 @@ --- -title: "Tool Implementation" +title: "Tool implementation" description: "Learn how to implement tools in your MCP server" --- diff --git a/api-reference/typescript/class-reference.mdx b/api-reference/typescript/class-reference.mdx index 2c2bb3f..3f93aad 100644 --- a/api-reference/typescript/class-reference.mdx +++ b/api-reference/typescript/class-reference.mdx @@ -1,9 +1,9 @@ --- -title: "TypeScript Class Reference" +title: "TypeScript class reference" description: "Complete TypeScript SDK class documentation" --- -## Client Classes +## Client classes ### Client @@ -65,7 +65,7 @@ getServerVersion(): Implementation | undefined ``` Returns the server's version information after connection. -### Transport Classes +### Transport classes #### StdioClientTransport ```typescript @@ -103,7 +103,7 @@ import { WebSocketClientTransport } from "@modelcontextprotocol/sdk/client/webso constructor(url: URL) ``` -## Server Classes +## Server classes ### Server @@ -173,7 +173,7 @@ getClientVersion(): Implementation | undefined ``` Returns the client's version information after connection. -### Transport Classes +### Transport classes #### StdioServerTransport ```typescript @@ -197,7 +197,7 @@ constructor(endpoint: string, res: ServerResponse) ## Examples -### Client Implementation +### Client implementation ```typescript import { Client } from "@modelcontextprotocol/sdk/client"; @@ -269,7 +269,7 @@ async function main() { } ``` -### Server Implementation +### Server implementation ```typescript import { Server } from "@modelcontextprotocol/sdk/server"; @@ -363,7 +363,7 @@ async function main() { } ``` -## Best Practices +## Best practices 1. **Error Handling** ```typescript diff --git a/api-reference/typescript/type-definitions.mdx b/api-reference/typescript/type-definitions.mdx index 9b02a44..f028fd3 100644 --- a/api-reference/typescript/type-definitions.mdx +++ b/api-reference/typescript/type-definitions.mdx @@ -1,11 +1,11 @@ --- -title: "TypeScript Type Definitions" +title: "TypeScript type definitions" description: "TypeScript type system documentation" --- -## Core Protocol Types +## Core protocol types -### JSON-RPC Types +### JSON-RPC types ```typescript export const JSONRPC_VERSION = "2.0"; @@ -53,7 +53,7 @@ export type JSONRPCMessage = | JSONRPCError; ``` -### Message Content Types +### Message content types ```typescript /** Text provided to or from an LLM */ @@ -84,7 +84,7 @@ export interface Progress { export type ProgressCallback = (progress: Progress) => void; ``` -### Resource Types +### Resource types ```typescript /** The contents of a specific resource */ @@ -120,7 +120,7 @@ export interface ResourceTemplate { } ``` -### Tool Types +### Tool types ```typescript /** Definition for a tool the client can call */ @@ -134,7 +134,7 @@ export interface Tool { } ``` -### Prompt Types +### Prompt types ```typescript /** Describes an argument that a prompt can accept */ @@ -152,9 +152,9 @@ export interface Prompt { } ``` -## Request/Response Types +## Request/response types -### Resource Requests +### Resource requests ```typescript export interface ListResourcesRequest { @@ -195,7 +195,7 @@ export interface UnsubscribeRequest { } ``` -### Tool Requests +### Tool requests ```typescript export interface ListToolsRequest { @@ -226,7 +226,7 @@ export interface CallToolResult { } ``` -### Prompt Requests +### Prompt requests ```typescript export interface ListPromptsRequest { @@ -255,9 +255,9 @@ export interface GetPromptResult { } ``` -## Protocol Types +## Protocol types -### Implementation Info +### Implementation info ```typescript export interface Implementation { @@ -266,7 +266,7 @@ export interface Implementation { } ``` -### Capability Types +### Capability types ```typescript export interface ResourceCapabilities { @@ -296,7 +296,7 @@ export interface ClientCapabilities { } ``` -### Notification Types +### Notification types ```typescript export interface ResourceUpdatedNotification { @@ -328,7 +328,7 @@ export type ServerNotification = | LogMessageNotification; ``` -## Error Types +## Error types ```typescript export enum ErrorCode { @@ -354,7 +354,7 @@ export class McpError extends Error { } ``` -## Transport Types +## Transport types ```typescript export interface Transport { @@ -373,9 +373,9 @@ export interface StdioServerParameters { } ``` -## Usage Examples +## Usage examples -### Type Guards +### Type guards ```typescript function isTextContent(content: @@ -391,7 +391,7 @@ function isResourceUpdatedNotification( } ``` -### Type Assertions +### Type assertions ```typescript function assertResource(data: unknown): asserts data is Resource { @@ -409,7 +409,7 @@ function assertResource(data: unknown): asserts data is Resource { } ``` -### Using Generics +### Using generics ```typescript async function handleResourceContent( @@ -425,7 +425,7 @@ async function handleResourceContent( } ``` -### Working with Union Types +### Working with union types ```typescript function processMessage(message: SamplingMessage): string { @@ -442,7 +442,7 @@ function processMessage(message: SamplingMessage): string { } ``` -## Type Utilities +## Type utilities ```typescript /** Helper type to extract request params from method name */ diff --git a/docs/unused/integrate-python.mdx b/docs/unused/integrate-python.mdx deleted file mode 100644 index 1ca1919..0000000 --- a/docs/unused/integrate-python.mdx +++ /dev/null @@ -1,442 +0,0 @@ ---- -title: "Integrate MCP into Your Python App" -description: "Add MCP support to your LLM application in Python" ---- - -Learn how to integrate MCP into your Python LLM application. We'll build a simple web analyzer that uses Claude to analyze websites, enhanced with MCP's web automation capabilities. - - -This guide uses an existing MCP server ([puppeteer](/servers/puppeteer)) rather than building one from scratch. This lets us focus on the integration patterns. - - -## The example app - -We'll build an "AI Web Analyzer" that: -1. Takes a URL from the user -2. Captures the webpage using MCP -3. Has the LLM analyze the page's content, design, and accessibility - - - Screenshot of the Web Analyzer CLI interface - - -## Prerequisites - - - - ```bash - pip install modelcontextprotocol-sdk anthropic click rich - ``` - - - - ```bash - # Install example MCP servers - git clone https://github.com/modelcontextprotocol/servers - cd servers - npm install - npm run build - npm install -g - ``` - - - - ```bash - # Set your Anthropic API key - export ANTHROPIC_API_KEY='your-key-here' - ``` - - - -## Building the base app - -First, let's create a basic version without MCP: - - - - ```bash - mkdir web-analyzer - cd web-analyzer - touch analyzer.py - ``` - - - - ```python - # analyzer.py - import click - import anthropic - from rich.console import Console - from rich.panel import Panel - from rich import print as rprint - - console = Console() - client = anthropic.Client() - - def analyze_url(url: str) -> str: - messages = [{ - "role": "user", - "content": f"Please analyze this website: {url}\n\n" - f"I'd like to know about:\n" - f"1. Content quality and organization\n" - f"2. Visual design (based on the URL/description)\n" - f"3. Potential improvements" - }] - - response = client.messages.create( - model="claude-3-opus-20240229", - max_tokens=1000, - messages=messages - ) - return response.content[0].text - - @click.command() - @click.argument('url') - def main(url: str): - with console.status("[bold green]Analyzing website..."): - analysis = analyze_url(url) - - rprint(Panel.fit( - analysis, - title="Website Analysis", - border_style="blue" - )) - - if __name__ == '__main__': - main() - ``` - - - - ```bash - python analyzer.py https://example.com - ``` - - - -## Adding MCP support - -Now let's enhance the app with MCP capabilities: - - - - ```python - # At the top of analyzer.py - from modelcontextprotocol.client import Client - from modelcontextprotocol.client.stdio import StdioClientTransport - import asyncio - import json - from typing import Optional - - class MCPWebClient: - def __init__(self): - self.client = Client( - client_info={ - "name": "web-analyzer", - "version": "0.1.0" - } - ) - self.transport = None - - async def connect(self): - self.transport = StdioClientTransport( - server={ - "command": "mcp-server-puppeteer", - } - ) - await self.client.connect(self.transport) - - async def navigate(self, url: str) -> Optional[str]: - try: - result = await self.client.request( - { - "method": "tools/call", - "params": { - "name": "navigate", - "arguments": {"url": url} - } - }, - schema=CallToolResultSchema - ) - return result.get("toolResult") - except Exception as e: - console.print(f"[red]Error navigating to URL: {e}") - return None - - async def get_console_logs(self) -> str: - result = await self.client.request( - { - "method": "resources/read", - "params": {"uri": "console://logs"} - }, - schema=ReadResourceResultSchema - ) - return result["contents"][0]["text"] - - async def close(self): - if self.transport: - await self.client.close() - ``` - - - ```python - async def analyze_url_with_mcp(url: str) -> str: - # Create and connect MCP client - mcp = MCPWebClient() - await mcp.connect() - # Navigate to the URL - await mcp.navigate(url) - - # Get console logs (includes errors, warnings, etc.) - console_logs = await mcp.get_console_logs() - - # Close the connection - await mcp.close() - - # Analyze with Claude - messages = [{ - "role": "user", - "content": ( - f"Please analyze this website: {url}\n\n" - f"Here are the browser console logs:\n{console_logs}\n\n" - f"Please analyze:\n" - f"1. Content quality and organization\n" - f"2. Visual design\n" - f"3. Technical issues (based on console logs)\n" - f"4. Potential improvements" - ) - }] - - response = client.messages.create( - model="claude-3-opus-20240229", - max_tokens=1000, - messages=messages - ) - return response.content[0].text - - @click.command() - @click.argument('url') - def main(url: str): - with console.status("[bold green]Analyzing website..."): - analysis = asyncio.run(analyze_url_with_mcp(url)) - - rprint(Panel.fit( - analysis, - title="Website Analysis", - border_style="blue" - )) - ``` - - - ```bash - python analyzer.py https://example.com - ``` - - - -## Understanding MCP integration - -Let's break down the key components of MCP integration: - - - ```python - class MCPWebClient: - def __init__(self): - self.client = Client( - client_info={ - "name": "web-analyzer", - "version": "0.1.0" - } - ) - ``` - The MCP client identifies your application and manages the connection to MCP servers. - - - ```python - self.transport = StdioClientTransport( - server={ - "command": "mcp-server-puppeteer", - } - ) - ``` - The transport layer handles communication with the MCP server. Here we're using stdio to talk to the puppeteer server. - - - ```python - result = await self.client.request( - { - "method": "tools/call", - "params": { - "name": "navigate", - "arguments": {"url": url} - } - }, - schema=CallToolResultSchema - ) - ``` - Tools let you take actions through MCP servers. Here we're using puppeteer's navigate tool. - - - ```python - result = await self.client.request( - { - "method": "resources/read", - "params": {"uri": "console://logs"} - }, - schema=ReadResourceResultSchema - ) - ``` - Resources provide data from MCP servers. Here we're reading console logs that puppeteer collected. - - - -## Enhancement ideas - -Now that you have MCP working, here are some ways to enhance the analyzer: - - - ```python - # Take screenshots with puppeteer - await client.request({ - "method": "tools/call", - "params": { - "name": "screenshot", - "arguments": {...} - } - }) - ``` - - - ```python - # Analyze multiple pages in sequence - for url in urls: - await navigate(url) - await analyze() - ``` - - - ```python - # Test interactive features - await client.request({ - "method": "tools/call", - "params": { - "name": "click", - "arguments": {"selector": "button"} - } - }) - ``` - - - -Common Patterns -Here are some patterns you'll often use when integrating MCP: - - - When you need to wait for resource updates: - ```python - async def wait_for_resource(uri: str, timeout: int = 30): - start = time.time() - while time.time() - start < timeout: - result = await client.request( - { - "method": "resources/read", - "params": {"uri": uri} - }, - schema=ReadResourceResultSchema - ) - if some_condition(result): - return result - await asyncio.sleep(1) - raise TimeoutError() - ``` - - - Robust error handling for MCP operations: - ```python - try: - await client.request(...) - except MCPError as e: - if e.code == ErrorCode.ResourceNotFound: - # Handle missing resource - elif e.code == ErrorCode.InvalidRequest: - # Handle invalid parameters - else: - # Handle other errors - ``` - - - Subscribe to resource updates: - ```python - await client.request( - { - "method": "resources/subscribe", - "params": {"uri": "console://logs"} - }, - schema=EmptyResultSchema - ) - # Now you'll get notifications when logs change - ``` - - - -## Troubleshooting - - - - ```python - # Enable debug logging - import logging - logging.basicConfig(level=logging.DEBUG) - ``` - Watch for connection errors and MCP protocol messages. - - - 1. Check if the resource exists: - ```python - resources = await client.request( - {"method": "resources/list"}, - schema=ListResourcesResultSchema - ) - print(resources) - ``` - 2. Verify URI format - 3. Check server logs - - - 1. List available tools: - ```python - tools = await client.request( - {"method": "tools/list"}, - schema=ListToolsResultSchema - ) - print(tools) - ``` - 2. Check argument schema - 3. Verify server capabilities - - - -## Next steps - - - - Connect to additional MCP servers for more capabilities - - -Create your own MCP server for custom functionality - - \ No newline at end of file diff --git a/docs/unused/integrate-ts.mdx b/docs/unused/integrate-ts.mdx deleted file mode 100644 index 45dc832..0000000 --- a/docs/unused/integrate-ts.mdx +++ /dev/null @@ -1,885 +0,0 @@ ---- -title: "Integrate MCP into Your TypeScript App" -description: "Add MCP support to your LLM application in TypeScript" ---- - -Learn how to integrate MCP into your TypeScript/React application. We'll build an AI Web Analyzer that uses Claude to analyze websites, enhanced with MCP's web automation capabilities. - - -This guide uses an existing MCP server ([puppeteer](/servers/puppeteer)) rather than building one from scratch. This lets us focus on the integration patterns. - - -## The example app - -We'll build an "AI Web Analyzer" that: -1. Takes a URL from the user -2. Captures the webpage using MCP -3. Has Claude analyze the page's content, design, and accessibility - - - Screenshot of the Web Analyzer interface - - -## Prerequisites - - - - ```bash - # Create new Next.js project with TypeScript - npx create-next-app@latest web-analyzer --typescript --tailwind - cd web-analyzer - ``` - - - - ```bash - npm install @modelcontextprotocol/sdk @anthropic-ai/sdk - ``` - - - - ```bash - # Install example MCP servers - git clone https://github.com/modelcontextprotocol/servers - cd servers - npm install - npm run build - npm install -g - ``` - - - -## Building the base app - -First, let's create a basic version without MCP: - - - - Create `components/WebAnalyzer.tsx`: - - ```tsx - import { useState } from 'react'; - import Anthropic from '@anthropic-ai/sdk'; - - const anthropic = new Anthropic({ - apiKey: process.env.NEXT_PUBLIC_ANTHROPIC_API_KEY - }); - - export default function WebAnalyzer() { - const [url, setUrl] = useState(''); - const [analysis, setAnalysis] = useState(''); - const [loading, setLoading] = useState(false); - - const analyzeUrl = async () => { - setLoading(true); - try { - const response = await anthropic.messages.create({ - model: 'claude-3-opus-20240229', - max_tokens: 1000, - messages: [{ - role: 'user', - content: `Please analyze this website: ${url}\n\n` - + `I'd like to know about:\n` - + `1. Content quality and organization\n` - + `2. Visual design (based on URL/description)\n` - + `3. Potential improvements` - }] - }); - setAnalysis(response.content[0].text); - } catch (error) { - console.error('Error:', error); - setAnalysis('Error analyzing website'); - } - setLoading(false); - }; - - return ( -
-

- AI Web Analyzer -

- -
- setUrl(e.target.value)} - placeholder="Enter website URL" - className="flex-1 p-2 border rounded" - /> - -
- - {loading && ( -
- Analyzing website... -
- )} - - {analysis && ( -
-
{analysis}
-
- )} -
- ); - } - ``` -
- - - Update `app/page.tsx`: - - ```tsx - import WebAnalyzer from '@/components/WebAnalyzer'; - - export default function Home() { - return ( -
- -
- ); - } - ``` -
- - - Create `.env.local`: - - ```bash - NEXT_PUBLIC_ANTHROPIC_API_KEY=your-key-here - ``` - -
- -## Adding MCP support - -Now let's enhance the app with MCP capabilities: - - - - Create `lib/mcp.ts`: - - ```typescript - import { Client } from '@modelcontextprotocol/sdk/client'; - import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio'; - import { - CallToolResultSchema, - ReadResourceResultSchema - } from '@modelcontextprotocol/sdk/types'; - - export class MCPWebClient { - private client: Client; - private transport: StdioClientTransport | null = null; - - constructor() { - this.client = new Client({ - name: 'web-analyzer', - version: '0.1.0' - }); - } - - async connect() { - this.transport = new StdioClientTransport({ - command: 'mcp-server-puppeteer' - }); - await this.client.connect(this.transport); - } - - async navigate(url: string): Promise { - try { - const result = await this.client.request( - { - method: 'tools/call', - params: { - name: 'navigate', - arguments: { url } - } - }, - CallToolResultSchema - ); - return result.toolResult as string; - } catch (error) { - console.error('Error navigating:', error); - return null; - } - } - - async getConsoleLogs(): Promise { - const result = await this.client.request( - { - method: 'resources/read', - params: { uri: 'console://logs' } - }, - ReadResourceResultSchema - ); - return result.contents[0].text; - } - - async close() { - if (this.transport) { - await this.client.close(); - } - } - } - ``` - - - - Create `contexts/MCPContext.tsx`: - - ```typescript - import { createContext, useContext, useEffect, useRef } from 'react'; - import { MCPWebClient } from '@/lib/mcp'; - - const MCPContext = createContext(null); - - export function MCPProvider({ children }: { children: React.ReactNode }) { - const clientRef = useRef(null); - - useEffect(() => { - const initMCP = async () => { - clientRef.current = new MCPWebClient(); - await clientRef.current.connect(); - }; - - initMCP(); - - return () => { - if (clientRef.current) { - clientRef.current.close(); - } - }; - }, []); - - return ( - - {children} - - ); - } - - export function useMCP() { - const context = useContext(MCPContext); - if (!context) { - throw new Error('useMCP must be used within MCPProvider'); - } - return context; - } - ``` - - - - Update `components/WebAnalyzer.tsx`: - - ```typescript - import { useState } from 'react'; - import Anthropic from '@anthropic-ai/sdk'; - import { useMCP } from '@/contexts/MCPContext'; - - const anthropic = new Anthropic({ - apiKey: process.env.NEXT_PUBLIC_ANTHROPIC_API_KEY - }); - - export default function WebAnalyzer() { - const mcp = useMCP(); - const [url, setUrl] = useState(''); - const [analysis, setAnalysis] = useState(''); - const [loading, setLoading] = useState(false); - - const analyzeUrl = async () => { - setLoading(true); - try { - // Navigate to the URL with MCP - await mcp.navigate(url); - - // Get console logs - const consoleLogs = await mcp.getConsoleLogs(); - - // Analyze with Claude - const response = await anthropic.messages.create({ - model: 'claude-3-opus-20240229', - max_tokens: 1000, - messages: [{ - role: 'user', - content: `Please analyze this website: ${url}\n\n` - + `Here are the browser console logs:\n${consoleLogs}\n\n` - + `Please analyze:\n` - + `1. Content quality and organization\n` - + `2. Visual design\n` - + `3. Technical issues (based on console logs)\n` - + `4. Potential improvements` - }] - }); - setAnalysis(response.content[0].text); - } catch (error) { - console.error('Error:', error); - setAnalysis('Error analyzing website'); - } - setLoading(false); - }; - - // ... rest of the component remains the same - } - ``` - - - - Update `app/layout.tsx`: - - ```typescript - import { MCPProvider } from '@/contexts/MCPContext'; - - export default function RootLayout({ - children, - }: { - children: React.ReactNode - }) { - return ( - - - - {children} - - - - ); - } - ``` - - - -## Understanding MCP integration - -Let's break down the key components: - - - - ```typescript - export class MCPWebClient { - private client: Client; - - constructor() { - this.client = new Client({ - name: 'web-analyzer', - version: '0.1.0' - }); - } - } - ``` - The MCP client manages the connection to MCP servers and handles requests. - - - - ```typescript - export function MCPProvider({ children }: { children: React.ReactNode }) { - const clientRef = useRef(null); - - useEffect(() => { - const initMCP = async () => { - clientRef.current = new MCPWebClient(); - await clientRef.current.connect(); - }; - - initMCP(); - // ... cleanup - }, []); - } - ``` - The context provider manages the MCP client lifecycle. - - - - ```typescript - async navigate(url: string): Promise { - const result = await this.client.request( - { - method: 'tools/call', - params: { - name: 'navigate', - arguments: { url } - } - }, - CallToolResultSchema - ); - return result.toolResult as string; - } - ``` - Tools let you take actions through MCP servers. - - - - ```typescript - async getConsoleLogs(): Promise { - const result = await this.client.request( - { - method: 'resources/read', - params: { uri: 'console://logs' } - }, - ReadResourceResultSchema - ); - return result.contents[0].text; - } - ``` - Resources provide data from MCP servers. - - - -## Enhancement ideas - -Here are some ways to enhance the analyzer: - - - - ```typescript - // Add screenshot capability - async function captureScreenshot() { - const result = await mcp.client.request({ - method: 'tools/call', - params: { - name: 'screenshot', - arguments: { /* ... */ } - } - }); - } - ``` - - - - ```typescript - // Analyze multiple pages - async function analyzeBatch(urls: string[]) { - const results = []; - for (const url of urls) { - await mcp.navigate(url); - // ... analyze - } - } - ``` - - - - ```typescript - // Test interactive elements - async function testInteraction() { - await mcp.client.request({ - method: 'tools/call', - params: { - name: 'click', - arguments: { selector: 'button' } - } - }); - } - ``` - - - - ```typescript - // Add performance metrics - async function getPerformance() { - const metrics = await mcp.client.request({ - method: 'resources/read', - params: { uri: 'metrics://performance' } - }); - } - ``` - - - -## Common patterns - -Here are some patterns you'll often use with MCP in React: - - - - ```typescript - function useResourcePolling(uri: string, interval = 1000) { - const [data, setData] = useState(null); - - useEffect(() => { - let mounted = true; - - async function poll() { - while (mounted) { - const result = await mcp.client.request({ - method: 'resources/read', - params: { uri } - }); - if (mounted) { - setData(result); - await new Promise(r => setTimeout(r, interval)); - } - } - } - - poll(); - return () => { mounted = false; }; - }, [uri, interval]); - - return data; - } - ``` - - - - ```typescript - class MCPErrorBoundary extends React.Component { - state = { hasError: false }; - - static getDerivedStateFromError(error) { - return { hasError: true }; - } - - componentDidCatch(error, errorInfo) { - if (error instanceof MCPError) { - // Handle MCP-specific errors - } - } - - render() { - if (this.state.hasError) { - return ; - } - return this.props.children; - } - } - ``` - - - - ```typescript - function useResourceSubscription(uri: string) { - useEffect(() => { - mcp.client.request({ - method: 'resources/subscribe', - params: { uri } - }); - - return () => { - mcp.client.request({ - method: 'resources/unsubscribe', - params: { uri } - }); - }; - }, [uri]); - } - ``` - - - -## Troubleshooting - - - - ```typescript - // Enable debug logging - const initMCP = async () => { - const client = new MCPWebClient({ - debug: true, // Enable debug logging - onError: (error) => { - console.error('MCP Error:', error); - } - }); - await client.connect(); - }; - ``` - Watch the browser console for connection errors and protocol messages. - - - - Common issues and solutions: - ```typescript - function WebAnalyzer() { - // Don't create client on every render - const mcpRef = useRef(null); - - // Initialize in useEffect - useEffect(() => { - const init = async () => { - mcpRef.current = new MCPWebClient(); - await mcpRef.current.connect(); - }; - init(); - - // Clean up properly - return () => { - if (mcpRef.current) { - mcpRef.current.close(); - } - }; - }, []); - } - ``` - - - - Use TypeScript to catch MCP issues early: - ```typescript - // Define expected response types - interface ToolResponse { - toolResult: { - screenshot?: string; - logs?: string[]; - error?: string; - }; - } - - // Use with request - const result = await client.request({ - method: 'tools/call', - params: { - name: 'screenshot', - arguments: { /* ... */ } - } - }); - - // TypeScript will catch missing properties - console.log(result.toolResult.screenshot); - ``` - - - -## Performance optimization - - - - ```typescript - function useCachedResource(uri: string) { - const [data, setData] = useState(null); - const cache = useRef(new Map()); - - useEffect(() => { - async function fetchResource() { - if (cache.current.has(uri)) { - setData(cache.current.get(uri)!); - return; - } - - const result = await mcp.client.request({ - method: 'resources/read', - params: { uri } - }); - - cache.current.set(uri, result.contents[0].text); - setData(result.contents[0].text); - } - - fetchResource(); - }, [uri]); - - return data; - } - ``` - - - - ```typescript - class BatchedMCPClient extends MCPWebClient { - private batchQueue: Map>; - - async request(method: string, params: any) { - const key = JSON.stringify({ method, params }); - - if (!this.batchQueue.has(key)) { - this.batchQueue.set( - key, - super.request(method, params) - ); - - // Clear after resolution - this.batchQueue.get(key)!.finally(() => { - this.batchQueue.delete(key); - }); - } - - return this.batchQueue.get(key); - } - } - ``` - - - -## Building for production - - - - Add proper error boundaries: - - ```typescript - import { ErrorBoundary } from 'react-error-boundary'; - - function ErrorFallback({ error, resetErrorBoundary }) { - return ( -
-

Something went wrong:

-
{error.message}
- -
- ); - } - - export default function App() { - return ( - { - // Reset application state - }} - > - - - ); - } - ``` -
- - - Add proper loading indicators: - - ```typescript - function WebAnalyzer() { - const [state, setState] = useState<{ - status: 'idle' | 'loading' | 'success' | 'error'; - error?: Error; - data?: string; - }>({ - status: 'idle' - }); - - return ( -
- {state.status === 'loading' && ( -
-
-
-
-
-
-
- )} - - {state.status === 'error' && ( -
- {state.error?.message} -
- )} - - {state.status === 'success' && ( -
{state.data}
- )} -
- ); - } - ``` -
- - - Set up proper environment variables: - - ```typescript - // next.config.js - module.exports = { - env: { - NEXT_PUBLIC_ANTHROPIC_API_KEY: process.env.NEXT_PUBLIC_ANTHROPIC_API_KEY, - MCP_DEBUG: process.env.NODE_ENV === 'development' - } - }; - - // Usage in code - const mcpClient = new MCPWebClient({ - debug: process.env.MCP_DEBUG === 'true' - }); - ``` - -
- -## Security considerations - - -Always validate and sanitize URLs before passing them to MCP servers. The puppeteer server has access to execute JavaScript and interact with web pages. - - -```typescript -function validateUrl(url: string): boolean { - try { - const parsed = new URL(url); - // Add your validation rules - return parsed.protocol === 'https:'; - } catch { - return false; - } -} - -function WebAnalyzer() { - const analyzeUrl = async () => { - if (!validateUrl(url)) { - setError('Please enter a valid HTTPS URL'); - return; - } - // ... rest of the analysis code - }; -} -``` - -## Next steps - - - - Learn how to handle authenticated web pages with MCP - - - Build your own MCP server for custom functionality - - - Learn how to test MCP integrations - - - Deploy your MCP-enabled app to production - - - - - - diff --git a/mint.json b/mint.json index 3f2df25..4e6e2f8 100644 --- a/mint.json +++ b/mint.json @@ -21,10 +21,6 @@ { "name": "API Reference", "url": "api-reference" - }, - { - "name": "Specification", - "url": "specification" } ], "anchors": [ @@ -101,22 +97,6 @@ "api-reference/typescript/class-reference", "api-reference/typescript/type-definitions" ] - }, - { - "group": "Specification", - "pages": [ - "specification/overview", - "specification/jsonrpc", - "specification/lifecycle", - "specification/prompts", - "specification/resources", - "specification/cancellation", - "specification/logging", - "specification/tools", - "specification/completion", - "specification/sampling", - "specification/roots" - ] } ], "footerSocials": {