diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..44ac576 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,50 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'pnpm' + + - name: Install dependencies - root + run: pnpm install + + - name: Install dependencies - inspector example + run: pnpm install + working-directory: examples/inspector + + - name: Install dependencies - cf-agents example + run: pnpm install + working-directory: examples/servers/cf-agents + + - name: Install dependencies - hono-mcp example + run: pnpm install + working-directory: examples/servers/hono-mcp + + - name: Install dependencies - test + run: pnpm install && pnpm exec playwright install + working-directory: test + + - name: Run tests + run: pnpm test:headless + working-directory: test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3e947d1..e335d95 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,12 +1,11 @@ name: Publish Any Commit on: - # Temporarily disabled - uncomment to re-enable - # pull_request: - # push: - # branches: - # - '**' - # tags: - # - '!**' + pull_request: + push: + branches: + - '**' + tags: + - '!**' jobs: build: diff --git a/.gitignore b/.gitignore index 8aa36e2..73d103a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ dist .aider* **/.claude/settings.local.json -public +/public diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..8ec9dd5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +./scripts/pre-commit diff --git a/.prettierignore b/.prettierignore index b7a1ccc..c75da94 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,5 @@ pnpm-lock.yaml *.md -examples +.wrangler +.vscode +test-results diff --git a/AGENT.md b/AGENT.md index 759766b..5dffb50 100644 --- a/AGENT.md +++ b/AGENT.md @@ -1,10 +1,21 @@ # use-mcp Project Guidelines ## Build, Lint, and Test Commands -- `pnpm dev`: Run development build with watch mode +- `pnpm dev`: Run development build with watch mode and start all examples/servers + - Chat UI: http://localhost:5002 + - Inspector: http://localhost:5001 + - Hono MCP Server: http://localhost:5101 + - CF Agents MCP Server: http://localhost:5102 - `pnpm build`: Build the project - `pnpm check`: Run prettier checks and TypeScript type checking +### Integration Tests (in /test directory) +- `cd test && pnpm test`: Run integration tests headlessly (default) +- `cd test && pnpm test:headed`: Run integration tests with visible browser +- `cd test && pnpm test:headless`: Run integration tests headlessly +- `cd test && pnpm test:watch`: Run integration tests in watch mode +- `cd test && pnpm test:ui`: Run integration tests with interactive UI + ## Code Style Guidelines ### Imports @@ -27,6 +38,10 @@ - Log errors with appropriate levels (debug, info, warn, error) - Defensive error handling with specific error types when available +## Development Workflow +- **Commit changes frequently** after each logical change or debugging step +- Use descriptive commit messages that explain what was changed and why + ### React Patterns - Use React hooks with useRef for mutable values - Stable callbacks with useCallback and appropriate dependencies \ No newline at end of file diff --git a/README.md b/README.md index 6f94dbb..b247654 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A lightweight React hook for connecting to [Model Context Protocol (MCP)](https://github.com/modelcontextprotocol) servers. Simplifies authentication and tool calling for AI systems implementing the MCP standard. -Try it out: [MCP Inspector](https://inspector.use-mcp.dev) | [Cloudflare Workers AI Playground](https://playground.ai.cloudflare.com/) +Try it out: [Chat Demo](https://chat.use-mcp.dev) | [MCP Inspector](https://inspector.use-mcp.dev) | [Cloudflare Workers AI Playground](https://playground.ai.cloudflare.com/) ## Installation @@ -20,11 +20,39 @@ pnpm add use-mcp yarn add use-mcp ``` +## Development + +To run the development environment with all examples and servers: + +```bash +pnpm dev +``` + +This starts: +- **Inspector**: http://localhost:5001 - MCP server debugging tool +- **Chat UI**: http://localhost:5002 - Example chat interface +- **Hono MCP Server**: http://localhost:5101 - Example MCP server +- **CF Agents MCP Server**: http://localhost:5102 - Cloudflare Workers AI MCP server + +### Testing + +Integration tests are located in the `test/` directory and run headlessly by default: + +```bash +cd test && pnpm test # Run tests headlessly (default) +cd test && pnpm test:headed # Run tests with visible browser +cd test && pnpm test:watch # Run tests in watch mode +cd test && pnpm test:ui # Run tests with interactive UI +``` + ## Features - ๐ Automatic connection management with reconnection and retries - ๐ OAuth authentication flow handling with popup and fallback support - ๐ฆ Simple React hook interface for MCP integration +- ๐งฐ Full support for MCP tools, resources, and prompts +- ๐ Access server resources and read their contents +- ๐ฌ Use server-provided prompt templates - ๐งฐ TypeScript types for editor assistance and type checking - ๐ Comprehensive logging for debugging - ๐ Works with both HTTP and SSE (Server-Sent Events) transports @@ -36,10 +64,14 @@ import { useMcp } from 'use-mcp/react' function MyAIComponent() { const { - state, // Connection state: 'discovering' | 'authenticating' | 'connecting' | 'loading' | 'ready' | 'failed' + state, // Connection state: 'discovering' | 'pending_auth' | 'authenticating' | 'connecting' | 'loading' | 'ready' | 'failed' tools, // Available tools from MCP server + resources, // Available resources from MCP server + prompts, // Available prompts from MCP server error, // Error message if connection failed callTool, // Function to call tools on the MCP server + readResource, // Function to read resource contents + getPrompt, // Function to get prompt messages retry, // Retry connection manually authenticate, // Manually trigger authentication clearStorage, // Clear stored tokens and credentials @@ -83,6 +115,32 @@ function MyAIComponent() { ))} + + {/* Example: Display and read resources */} + {resources.length > 0 && ( +
+ Enter your {provider.name} API key to use this model. Your key will be stored locally in your browser. +
+ + ++ {state === 'pending_auth' + ? 'Authentication is required to connect to this server.' + : 'Authentication popup was blocked. You can open the authentication page manually:'} +
+No MCP servers configured yet.
+Add your first server below.
++ Connect to Model Context Protocol (MCP) servers to access additional AI capabilities. +
+ ++ {state === 'pending_auth' + ? 'Authentication is required to connect to this server.' + : 'Authentication popup was blocked. You can open the authentication page manually:'} +
+{tool.description}
} ++ {provider.authType === 'oauth' ? 'OAuth Authentication' : 'API Key Authentication'} +
+No starred models yet
+Click on a provider above to explore and star models
+Select models to add to your favorites
+ + {/* Search Bar */} +No models found matching "{searchTerm}"
+Please wait while we complete your authentication.
+This window should close automatically.
+ +Connecting to {provider}...
+ > + )} + + {status === 'success' && ( + <> +Successfully connected to {provider}.
+{error || 'An error occurred during authentication'}
+ + > + )} +Select models to add to your favorites
+
+ {JSON.stringify(message.toolArgs, null, 2)}
+
+ ) : (
+
+ {JSON.stringify(message.toolResult, null, 2)}
+
+ ) : (
+ - Minimal demo showcasing the{' '} - - use-mcp - {' '} - React hook -
++ Minimal demo showcasing the{' '} + + use-mcp + {' '} + React hook +
+- Connect to Model Context Protocol (MCP) servers to access additional AI - capabilities. + Connect to Model Context Protocol (MCP) servers to access additional AI capabilities.