From 6d2d974bc91cb61b74fdca78a176c7f6e49600c5 Mon Sep 17 00:00:00 2001 From: gudnuf Date: Fri, 16 Jan 2026 22:43:38 -0800 Subject: [PATCH] add mcp-integration skill, add playwright mcp --- .claude/skills/mcp-integration/SKILL.md | 571 ++++++++++++++++++ .../mcp-integration/examples/http-server.json | 20 + .../mcp-integration/examples/sse-server.json | 19 + .../examples/stdio-server.json | 30 + .../references/authentication.md | 549 +++++++++++++++++ .../references/server-types.md | 550 +++++++++++++++++ .../mcp-integration/references/tool-usage.md | 538 +++++++++++++++++ .../playwright-agicash-navigation/SKILL.md | 263 ++++++++ .claude/skills/skill-creator/SKILL.md | 34 +- .gitignore | 3 + .mcp.json | 8 + CLAUDE.md | 2 + package.json | 4 +- 13 files changed, 2558 insertions(+), 33 deletions(-) create mode 100644 .claude/skills/mcp-integration/SKILL.md create mode 100644 .claude/skills/mcp-integration/examples/http-server.json create mode 100644 .claude/skills/mcp-integration/examples/sse-server.json create mode 100644 .claude/skills/mcp-integration/examples/stdio-server.json create mode 100644 .claude/skills/mcp-integration/references/authentication.md create mode 100644 .claude/skills/mcp-integration/references/server-types.md create mode 100644 .claude/skills/mcp-integration/references/tool-usage.md create mode 100644 .claude/skills/playwright-agicash-navigation/SKILL.md create mode 100644 .mcp.json diff --git a/.claude/skills/mcp-integration/SKILL.md b/.claude/skills/mcp-integration/SKILL.md new file mode 100644 index 00000000..c9281f1b --- /dev/null +++ b/.claude/skills/mcp-integration/SKILL.md @@ -0,0 +1,571 @@ +--- +name: MCP Integration +description: This skill should be used when the user asks to "add MCP server", "integrate MCP", "configure MCP in plugin", "use .mcp.json", "set up Model Context Protocol", "connect external service", mentions "${CLAUDE_PLUGIN_ROOT} with MCP", or discusses MCP server types (SSE, stdio, HTTP, WebSocket). Provides comprehensive guidance for integrating Model Context Protocol servers into Claude Code plugins for external tool and service integration. +version: 0.1.0 +source: https://github.com/anthropics/claude-code/tree/main/plugins/plugin-dev/skills/mcp-integration +--- + +# MCP Integration for Claude Code Plugins + +## Overview + +Model Context Protocol (MCP) enables Claude Code plugins to integrate with external services and APIs by providing structured tool access. Use MCP integration to expose external service capabilities as tools within Claude Code. + +**Key capabilities:** +- Connect to external services (databases, APIs, file systems) +- Provide 10+ related tools from a single service +- Handle OAuth and complex authentication flows +- Bundle MCP servers with plugins for automatic setup + +## MCP Server Configuration Methods + +Plugins can bundle MCP servers in two ways: + +### Method 1: Dedicated .mcp.json (Recommended) + +Create `.mcp.json` at plugin root: + +```json +{ + "database-tools": { + "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server", + "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"], + "env": { + "DB_URL": "${DB_URL}" + } + } +} +``` + +**Benefits:** +- Clear separation of concerns +- Easier to maintain +- Better for multiple servers + +### Method 2: Inline in plugin.json + +Add `mcpServers` field to plugin.json: + +```json +{ + "name": "my-plugin", + "version": "1.0.0", + "mcpServers": { + "plugin-api": { + "command": "${CLAUDE_PLUGIN_ROOT}/servers/api-server", + "args": ["--port", "8080"] + } + } +} +``` + +**Benefits:** +- Single configuration file +- Good for simple single-server plugins + +## MCP Server Types + +### stdio (Local Process) + +Execute local MCP servers as child processes. Best for local tools and custom servers. + +**Configuration (Node.js projects):** +```json +{ + "filesystem": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"], + "env": { + "LOG_LEVEL": "debug" + } + } +} +``` + +**Configuration (Bun projects - preferred):** +```json +{ + "filesystem": { + "command": "bunx", + "args": ["@modelcontextprotocol/server-filesystem", "/allowed/path"], + "env": { + "LOG_LEVEL": "debug" + } + } +} +``` + +**Note:** Use `bunx` instead of `npx` in Bun projects. It's faster and auto-downloads packages (no `-y` flag needed). + +**Use cases:** +- File system access +- Local database connections +- Custom MCP servers +- NPM-packaged MCP servers + +**Process management:** +- Claude Code spawns and manages the process +- Communicates via stdin/stdout +- Terminates when Claude Code exits + +### SSE (Server-Sent Events) + +Connect to hosted MCP servers with OAuth support. Best for cloud services. + +**Configuration:** +```json +{ + "asana": { + "type": "sse", + "url": "https://mcp.asana.com/sse" + } +} +``` + +**Use cases:** +- Official hosted MCP servers (Asana, GitHub, etc.) +- Cloud services with MCP endpoints +- OAuth-based authentication +- No local installation needed + +**Authentication:** +- OAuth flows handled automatically +- User prompted on first use +- Tokens managed by Claude Code + +### HTTP (REST API) + +Connect to RESTful MCP servers with token authentication. + +**Configuration:** +```json +{ + "api-service": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { + "Authorization": "Bearer ${API_TOKEN}", + "X-Custom-Header": "value" + } + } +} +``` + +**Use cases:** +- REST API-based MCP servers +- Token-based authentication +- Custom API backends +- Stateless interactions + +### WebSocket (Real-time) + +Connect to WebSocket MCP servers for real-time bidirectional communication. + +**Configuration:** +```json +{ + "realtime-service": { + "type": "ws", + "url": "wss://mcp.example.com/ws", + "headers": { + "Authorization": "Bearer ${TOKEN}" + } + } +} +``` + +**Use cases:** +- Real-time data streaming +- Persistent connections +- Push notifications from server +- Low-latency requirements + +## Environment Variable Expansion + +All MCP configurations support environment variable substitution: + +**${CLAUDE_PLUGIN_ROOT}** - Plugin directory (always use for portability): +```json +{ + "command": "${CLAUDE_PLUGIN_ROOT}/servers/my-server" +} +``` + +**User environment variables** - From user's shell: +```json +{ + "env": { + "API_KEY": "${MY_API_KEY}", + "DATABASE_URL": "${DB_URL}" + } +} +``` + +**Best practice:** Document all required environment variables in plugin README. + +## MCP Tool Naming + +When MCP servers provide tools, they're automatically prefixed: + +**Format:** `mcp__plugin____` + +**Example:** +- Plugin: `asana` +- Server: `asana` +- Tool: `create_task` +- **Full name:** `mcp__plugin_asana_asana__asana_create_task` + +### Using MCP Tools in Commands + +Pre-allow specific MCP tools in command frontmatter: + +```markdown +--- +allowed-tools: [ + "mcp__plugin_asana_asana__asana_create_task", + "mcp__plugin_asana_asana__asana_search_tasks" +] +--- +``` + +**Wildcard (use sparingly):** +```markdown +--- +allowed-tools: ["mcp__plugin_asana_asana__*"] +--- +``` + +**Best practice:** Pre-allow specific tools, not wildcards, for security. + +## Lifecycle Management + +**Automatic startup:** +- MCP servers start when plugin enables +- Connection established before first tool use +- Restart required for configuration changes + +**Lifecycle:** +1. Plugin loads +2. MCP configuration parsed +3. Server process started (stdio) or connection established (SSE/HTTP/WS) +4. Tools discovered and registered +5. Tools available as `mcp__plugin_...__...` + +**Viewing servers:** +Use `/mcp` command to see all servers including plugin-provided ones. + +## Authentication Patterns + +### OAuth (SSE/HTTP) + +OAuth handled automatically by Claude Code: + +```json +{ + "type": "sse", + "url": "https://mcp.example.com/sse" +} +``` + +User authenticates in browser on first use. No additional configuration needed. + +### Token-Based (Headers) + +Static or environment variable tokens: + +```json +{ + "type": "http", + "url": "https://api.example.com", + "headers": { + "Authorization": "Bearer ${API_TOKEN}" + } +} +``` + +Document required environment variables in README. + +### Environment Variables (stdio) + +Pass configuration to MCP server: + +```json +{ + "command": "python", + "args": ["-m", "my_mcp_server"], + "env": { + "DATABASE_URL": "${DB_URL}", + "API_KEY": "${API_KEY}", + "LOG_LEVEL": "info" + } +} +``` + +## Integration Patterns + +### Pattern 1: Simple Tool Wrapper + +Commands use MCP tools with user interaction: + +```markdown +# Command: create-item.md +--- +allowed-tools: ["mcp__plugin_name_server__create_item"] +--- + +Steps: +1. Gather item details from user +2. Use mcp__plugin_name_server__create_item +3. Confirm creation +``` + +**Use for:** Adding validation or preprocessing before MCP calls. + +### Pattern 2: Autonomous Agent + +Agents use MCP tools autonomously: + +```markdown +# Agent: data-analyzer.md + +Analysis Process: +1. Query data via mcp__plugin_db_server__query +2. Process and analyze results +3. Generate insights report +``` + +**Use for:** Multi-step MCP workflows without user interaction. + +### Pattern 3: Multi-Server Plugin + +Integrate multiple MCP servers: + +```json +{ + "github": { + "type": "sse", + "url": "https://mcp.github.com/sse" + }, + "jira": { + "type": "sse", + "url": "https://mcp.jira.com/sse" + } +} +``` + +**Use for:** Workflows spanning multiple services. + +## Security Best Practices + +### Use HTTPS/WSS + +Always use secure connections: + +```json +✅ "url": "https://mcp.example.com/sse" +❌ "url": "http://mcp.example.com/sse" +``` + +### Token Management + +**DO:** +- ✅ Use environment variables for tokens +- ✅ Document required env vars in README +- ✅ Let OAuth flow handle authentication + +**DON'T:** +- ❌ Hardcode tokens in configuration +- ❌ Commit tokens to git +- ❌ Share tokens in documentation + +### Permission Scoping + +Pre-allow only necessary MCP tools: + +```markdown +✅ allowed-tools: [ + "mcp__plugin_api_server__read_data", + "mcp__plugin_api_server__create_item" +] + +❌ allowed-tools: ["mcp__plugin_api_server__*"] +``` + +## Error Handling + +### Connection Failures + +Handle MCP server unavailability: +- Provide fallback behavior in commands +- Inform user of connection issues +- Check server URL and configuration + +### Tool Call Errors + +Handle failed MCP operations: +- Validate inputs before calling MCP tools +- Provide clear error messages +- Check rate limiting and quotas + +### Configuration Errors + +Validate MCP configuration: +- Test server connectivity during development +- Validate JSON syntax +- Check required environment variables + +## Performance Considerations + +### Lazy Loading + +MCP servers connect on-demand: +- Not all servers connect at startup +- First tool use triggers connection +- Connection pooling managed automatically + +### Batching + +Batch similar requests when possible: + +``` +# Good: Single query with filters +tasks = search_tasks(project="X", assignee="me", limit=50) + +# Avoid: Many individual queries +for id in task_ids: + task = get_task(id) +``` + +## Testing MCP Integration + +### Local Testing + +1. Configure MCP server in `.mcp.json` +2. Install plugin locally (`.claude-plugin/`) +3. Run `/mcp` to verify server appears +4. Test tool calls in commands +5. Check `claude --debug` logs for connection issues + +### Validation Checklist + +- [ ] MCP configuration is valid JSON +- [ ] Server URL is correct and accessible +- [ ] Required environment variables documented +- [ ] Tools appear in `/mcp` output +- [ ] Authentication works (OAuth or tokens) +- [ ] Tool calls succeed from commands +- [ ] Error cases handled gracefully + +## Debugging + +### Enable Debug Logging + +```bash +claude --debug +``` + +Look for: +- MCP server connection attempts +- Tool discovery logs +- Authentication flows +- Tool call errors + +### Common Issues + +**Server not connecting:** +- Check URL is correct +- Verify server is running (stdio) +- Check network connectivity +- Review authentication configuration + +**Tools not available:** +- Verify server connected successfully +- Check tool names match exactly +- Run `/mcp` to see available tools +- Restart Claude Code after config changes + +**Authentication failing:** +- Clear cached auth tokens +- Re-authenticate +- Check token scopes and permissions +- Verify environment variables set + +## Quick Reference + +### MCP Server Types + +| Type | Transport | Best For | Auth | +|------|-----------|----------|------| +| stdio | Process | Local tools, custom servers | Env vars | +| SSE | HTTP | Hosted services, cloud APIs | OAuth | +| HTTP | REST | API backends, token auth | Tokens | +| ws | WebSocket | Real-time, streaming | Tokens | + +### Configuration Checklist + +- [ ] Server type specified (stdio/SSE/HTTP/ws) +- [ ] Type-specific fields complete (command or url) +- [ ] Authentication configured +- [ ] Environment variables documented +- [ ] HTTPS/WSS used (not HTTP/WS) +- [ ] ${CLAUDE_PLUGIN_ROOT} used for paths + +### Best Practices + +**DO:** +- ✅ Use ${CLAUDE_PLUGIN_ROOT} for portable paths +- ✅ Prefer `bunx` over `npx` in Bun projects (faster, no `-y` flag) +- ✅ Document required environment variables +- ✅ Use secure connections (HTTPS/WSS) +- ✅ Pre-allow specific MCP tools in commands +- ✅ Test MCP integration before publishing +- ✅ Handle connection and tool errors gracefully + +**DON'T:** +- ❌ Hardcode absolute paths +- ❌ Commit credentials to git +- ❌ Use HTTP instead of HTTPS +- ❌ Pre-allow all tools with wildcards +- ❌ Skip error handling +- ❌ Forget to document setup + +## Additional Resources + +### Reference Files + +For detailed information, consult: + +- **`references/server-types.md`** - Deep dive on each server type +- **`references/authentication.md`** - Authentication patterns and OAuth +- **`references/tool-usage.md`** - Using MCP tools in commands and agents + +### Example Configurations + +Working examples in `examples/`: + +- **`stdio-server.json`** - Local stdio MCP server +- **`sse-server.json`** - Hosted SSE server with OAuth +- **`http-server.json`** - REST API with token auth + +### External Resources + +- **Official MCP Docs**: https://modelcontextprotocol.io/ +- **Claude Code MCP Docs**: https://docs.claude.com/en/docs/claude-code/mcp +- **MCP SDK**: @modelcontextprotocol/sdk +- **Testing**: Use `claude --debug` and `/mcp` command + +## Implementation Workflow + +To add MCP integration to a plugin: + +1. Choose MCP server type (stdio, SSE, HTTP, ws) +2. Create `.mcp.json` at plugin root with configuration +3. Use ${CLAUDE_PLUGIN_ROOT} for all file references +4. Document required environment variables in README +5. Test locally with `/mcp` command +6. Pre-allow MCP tools in relevant commands +7. Handle authentication (OAuth or tokens) +8. Test error cases (connection failures, auth errors) +9. Document MCP integration in plugin README + +Focus on stdio for custom/local servers, SSE for hosted services with OAuth. diff --git a/.claude/skills/mcp-integration/examples/http-server.json b/.claude/skills/mcp-integration/examples/http-server.json new file mode 100644 index 00000000..e96448fe --- /dev/null +++ b/.claude/skills/mcp-integration/examples/http-server.json @@ -0,0 +1,20 @@ +{ + "_comment": "Example HTTP MCP server configuration for REST APIs", + "rest-api": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { + "Authorization": "Bearer ${API_TOKEN}", + "Content-Type": "application/json", + "X-API-Version": "2024-01-01" + } + }, + "internal-service": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { + "Authorization": "Bearer ${API_TOKEN}", + "X-Service-Name": "claude-plugin" + } + } +} diff --git a/.claude/skills/mcp-integration/examples/sse-server.json b/.claude/skills/mcp-integration/examples/sse-server.json new file mode 100644 index 00000000..e6ec71c6 --- /dev/null +++ b/.claude/skills/mcp-integration/examples/sse-server.json @@ -0,0 +1,19 @@ +{ + "_comment": "Example SSE MCP server configuration for hosted cloud services", + "asana": { + "type": "sse", + "url": "https://mcp.asana.com/sse" + }, + "github": { + "type": "sse", + "url": "https://mcp.github.com/sse" + }, + "custom-service": { + "type": "sse", + "url": "https://mcp.example.com/sse", + "headers": { + "X-API-Version": "v1", + "X-Client-ID": "${CLIENT_ID}" + } + } +} diff --git a/.claude/skills/mcp-integration/examples/stdio-server.json b/.claude/skills/mcp-integration/examples/stdio-server.json new file mode 100644 index 00000000..55adeaa4 --- /dev/null +++ b/.claude/skills/mcp-integration/examples/stdio-server.json @@ -0,0 +1,30 @@ +{ + "_comment": "Example stdio MCP server configuration for local file system access. Use 'bunx' instead of 'npx -y' for Bun projects (faster and auto-downloads).", + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "${CLAUDE_PROJECT_DIR}" + ], + "env": { + "LOG_LEVEL": "info" + } + }, + "database": { + "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server.js", + "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config/db.json"], + "env": { + "DATABASE_URL": "${DATABASE_URL}", + "DB_POOL_SIZE": "10" + } + }, + "custom-tools": { + "command": "python", + "args": ["-m", "my_mcp_server", "--port", "8080"], + "env": { + "API_KEY": "${CUSTOM_API_KEY}", + "DEBUG": "false" + } + } +} diff --git a/.claude/skills/mcp-integration/references/authentication.md b/.claude/skills/mcp-integration/references/authentication.md new file mode 100644 index 00000000..1d4ff384 --- /dev/null +++ b/.claude/skills/mcp-integration/references/authentication.md @@ -0,0 +1,549 @@ +# MCP Authentication Patterns + +Complete guide to authentication methods for MCP servers in Claude Code plugins. + +## Overview + +MCP servers support multiple authentication methods depending on the server type and service requirements. Choose the method that best matches your use case and security requirements. + +## OAuth (Automatic) + +### How It Works + +Claude Code automatically handles the complete OAuth 2.0 flow for SSE and HTTP servers: + +1. User attempts to use MCP tool +2. Claude Code detects authentication needed +3. Opens browser for OAuth consent +4. User authorizes in browser +5. Tokens stored securely by Claude Code +6. Automatic token refresh + +### Configuration + +```json +{ + "service": { + "type": "sse", + "url": "https://mcp.example.com/sse" + } +} +``` + +No additional auth configuration needed! Claude Code handles everything. + +### Supported Services + +**Known OAuth-enabled MCP servers:** +- Asana: `https://mcp.asana.com/sse` +- GitHub (when available) +- Google services (when available) +- Custom OAuth servers + +### OAuth Scopes + +OAuth scopes are determined by the MCP server. Users see required scopes during the consent flow. + +**Document required scopes in your README:** +```markdown +## Authentication + +This plugin requires the following Asana permissions: +- Read tasks and projects +- Create and update tasks +- Access workspace data +``` + +### Token Storage + +Tokens are stored securely by Claude Code: +- Not accessible to plugins +- Encrypted at rest +- Automatic refresh +- Cleared on sign-out + +### Troubleshooting OAuth + +**Authentication loop:** +- Clear cached tokens (sign out and sign in) +- Check OAuth redirect URLs +- Verify server OAuth configuration + +**Scope issues:** +- User may need to re-authorize for new scopes +- Check server documentation for required scopes + +**Token expiration:** +- Claude Code auto-refreshes +- If refresh fails, prompts re-authentication + +## Token-Based Authentication + +### Bearer Tokens + +Most common for HTTP and WebSocket servers. + +**Configuration:** +```json +{ + "api": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { + "Authorization": "Bearer ${API_TOKEN}" + } + } +} +``` + +**Environment variable:** +```bash +export API_TOKEN="your-secret-token-here" +``` + +### API Keys + +Alternative to Bearer tokens, often in custom headers. + +**Configuration:** +```json +{ + "api": { + "type": "http", + "url": "https://api.example.com/mcp", + "headers": { + "X-API-Key": "${API_KEY}", + "X-API-Secret": "${API_SECRET}" + } + } +} +``` + +### Custom Headers + +Services may use custom authentication headers. + +**Configuration:** +```json +{ + "service": { + "type": "sse", + "url": "https://mcp.example.com/sse", + "headers": { + "X-Auth-Token": "${AUTH_TOKEN}", + "X-User-ID": "${USER_ID}", + "X-Tenant-ID": "${TENANT_ID}" + } + } +} +``` + +### Documenting Token Requirements + +Always document in your README: + +```markdown +## Setup + +### Required Environment Variables + +Set these environment variables before using the plugin: + +\`\`\`bash +export API_TOKEN="your-token-here" +export API_SECRET="your-secret-here" +\`\`\` + +### Obtaining Tokens + +1. Visit https://api.example.com/tokens +2. Create a new API token +3. Copy the token and secret +4. Set environment variables as shown above + +### Token Permissions + +The API token needs the following permissions: +- Read access to resources +- Write access for creating items +- Delete access (optional, for cleanup operations) +\`\`\` +``` + +## Environment Variable Authentication (stdio) + +### Passing Credentials to Server + +For stdio servers, pass credentials via environment variables: + +```json +{ + "database": { + "command": "python", + "args": ["-m", "mcp_server_db"], + "env": { + "DATABASE_URL": "${DATABASE_URL}", + "DB_USER": "${DB_USER}", + "DB_PASSWORD": "${DB_PASSWORD}" + } + } +} +``` + +### User Environment Variables + +```bash +# User sets these in their shell +export DATABASE_URL="postgresql://localhost/mydb" +export DB_USER="myuser" +export DB_PASSWORD="mypassword" +``` + +### Documentation Template + +```markdown +## Database Configuration + +Set these environment variables: + +\`\`\`bash +export DATABASE_URL="postgresql://host:port/database" +export DB_USER="username" +export DB_PASSWORD="password" +\`\`\` + +Or create a `.env` file (add to `.gitignore`): + +\`\`\` +DATABASE_URL=postgresql://localhost:5432/mydb +DB_USER=myuser +DB_PASSWORD=mypassword +\`\`\` + +Load with: \`source .env\` or \`export $(cat .env | xargs)\` +\`\`\` +``` + +## Dynamic Headers + +### Headers Helper Script + +For tokens that change or expire, use a helper script: + +```json +{ + "api": { + "type": "sse", + "url": "https://api.example.com", + "headersHelper": "${CLAUDE_PLUGIN_ROOT}/scripts/get-headers.sh" + } +} +``` + +**Script (get-headers.sh):** +```bash +#!/bin/bash +# Generate dynamic authentication headers + +# Fetch fresh token +TOKEN=$(get-fresh-token-from-somewhere) + +# Output JSON headers +cat <___`. Use these tools in commands and agents just like built-in Claude Code tools. + +## Tool Naming Convention + +### Format + +``` +mcp__plugin____ +``` + +### Examples + +**Asana plugin with asana server:** +- `mcp__plugin_asana_asana__asana_create_task` +- `mcp__plugin_asana_asana__asana_search_tasks` +- `mcp__plugin_asana_asana__asana_get_project` + +**Custom plugin with database server:** +- `mcp__plugin_myplug_database__query` +- `mcp__plugin_myplug_database__execute` +- `mcp__plugin_myplug_database__list_tables` + +### Discovering Tool Names + +**Use `/mcp` command:** +```bash +/mcp +``` + +This shows: +- All available MCP servers +- Tools provided by each server +- Tool schemas and descriptions +- Full tool names for use in configuration + +## Using Tools in Commands + +### Pre-Allowing Tools + +Specify MCP tools in command frontmatter: + +```markdown +--- +description: Create a new Asana task +allowed-tools: [ + "mcp__plugin_asana_asana__asana_create_task" +] +--- + +# Create Task Command + +To create a task: +1. Gather task details from user +2. Use mcp__plugin_asana_asana__asana_create_task with the details +3. Confirm creation to user +``` + +### Multiple Tools + +```markdown +--- +allowed-tools: [ + "mcp__plugin_asana_asana__asana_create_task", + "mcp__plugin_asana_asana__asana_search_tasks", + "mcp__plugin_asana_asana__asana_get_project" +] +--- +``` + +### Wildcard (Use Sparingly) + +```markdown +--- +allowed-tools: ["mcp__plugin_asana_asana__*"] +--- +``` + +**Caution:** Only use wildcards if the command truly needs access to all tools from a server. + +### Tool Usage in Command Instructions + +**Example command:** +```markdown +--- +description: Search and create Asana tasks +allowed-tools: [ + "mcp__plugin_asana_asana__asana_search_tasks", + "mcp__plugin_asana_asana__asana_create_task" +] +--- + +# Asana Task Management + +## Searching Tasks + +To search for tasks: +1. Use mcp__plugin_asana_asana__asana_search_tasks +2. Provide search filters (assignee, project, etc.) +3. Display results to user + +## Creating Tasks + +To create a task: +1. Gather task details: + - Title (required) + - Description + - Project + - Assignee + - Due date +2. Use mcp__plugin_asana_asana__asana_create_task +3. Show confirmation with task link +``` + +## Using Tools in Agents + +### Agent Configuration + +Agents can use MCP tools autonomously without pre-allowing them: + +```markdown +--- +name: asana-status-updater +description: This agent should be used when the user asks to "update Asana status", "generate project report", or "sync Asana tasks" +model: inherit +color: blue +--- + +## Role + +Autonomous agent for generating Asana project status reports. + +## Process + +1. **Query tasks**: Use mcp__plugin_asana_asana__asana_search_tasks to get all tasks +2. **Analyze progress**: Calculate completion rates and identify blockers +3. **Generate report**: Create formatted status update +4. **Update Asana**: Use mcp__plugin_asana_asana__asana_create_comment to post report + +## Available Tools + +The agent has access to all Asana MCP tools without pre-approval. +``` + +### Agent Tool Access + +Agents have broader tool access than commands: +- Can use any tool Claude determines is necessary +- Don't need pre-allowed lists +- Should document which tools they typically use + +## Tool Call Patterns + +### Pattern 1: Simple Tool Call + +Single tool call with validation: + +```markdown +Steps: +1. Validate user provided required fields +2. Call mcp__plugin_api_server__create_item with validated data +3. Check for errors +4. Display confirmation +``` + +### Pattern 2: Sequential Tools + +Chain multiple tool calls: + +```markdown +Steps: +1. Search for existing items: mcp__plugin_api_server__search +2. If not found, create new: mcp__plugin_api_server__create +3. Add metadata: mcp__plugin_api_server__update_metadata +4. Return final item ID +``` + +### Pattern 3: Batch Operations + +Multiple calls with same tool: + +```markdown +Steps: +1. Get list of items to process +2. For each item: + - Call mcp__plugin_api_server__update_item + - Track success/failure +3. Report results summary +``` + +### Pattern 4: Error Handling + +Graceful error handling: + +```markdown +Steps: +1. Try to call mcp__plugin_api_server__get_data +2. If error (rate limit, network, etc.): + - Wait and retry (max 3 attempts) + - If still failing, inform user + - Suggest checking configuration +3. On success, process data +``` + +## Tool Parameters + +### Understanding Tool Schemas + +Each MCP tool has a schema defining its parameters. View with `/mcp`. + +**Example schema:** +```json +{ + "name": "asana_create_task", + "description": "Create a new Asana task", + "inputSchema": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Task title" + }, + "notes": { + "type": "string", + "description": "Task description" + }, + "workspace": { + "type": "string", + "description": "Workspace GID" + } + }, + "required": ["name", "workspace"] + } +} +``` + +### Calling Tools with Parameters + +Claude automatically structures tool calls based on schema: + +```typescript +// Claude generates this internally +{ + toolName: "mcp__plugin_asana_asana__asana_create_task", + input: { + name: "Review PR #123", + notes: "Code review for new feature", + workspace: "12345", + assignee: "67890", + due_on: "2025-01-15" + } +} +``` + +### Parameter Validation + +**In commands, validate before calling:** + +```markdown +Steps: +1. Check required parameters: + - Title is not empty + - Workspace ID is provided + - Due date is valid format (YYYY-MM-DD) +2. If validation fails, ask user to provide missing data +3. If validation passes, call MCP tool +4. Handle tool errors gracefully +``` + +## Response Handling + +### Success Responses + +```markdown +Steps: +1. Call MCP tool +2. On success: + - Extract relevant data from response + - Format for user display + - Provide confirmation message + - Include relevant links or IDs +``` + +### Error Responses + +```markdown +Steps: +1. Call MCP tool +2. On error: + - Check error type (auth, rate limit, validation, etc.) + - Provide helpful error message + - Suggest remediation steps + - Don't expose internal error details to user +``` + +### Partial Success + +```markdown +Steps: +1. Batch operation with multiple MCP calls +2. Track successes and failures separately +3. Report summary: + - "Successfully processed 8 of 10 items" + - "Failed items: [item1, item2] due to [reason]" + - Suggest retry or manual intervention +``` + +## Performance Optimization + +### Batching Requests + +**Good: Single query with filters** +```markdown +Steps: +1. Call mcp__plugin_api_server__search with filters: + - project_id: "123" + - status: "active" + - limit: 100 +2. Process all results +``` + +**Avoid: Many individual queries** +```markdown +Steps: +1. For each item ID: + - Call mcp__plugin_api_server__get_item + - Process item +``` + +### Caching Results + +```markdown +Steps: +1. Call expensive MCP operation: mcp__plugin_api_server__analyze +2. Store results in variable for reuse +3. Use cached results for subsequent operations +4. Only re-fetch if data changes +``` + +### Parallel Tool Calls + +When tools don't depend on each other, call in parallel: + +```markdown +Steps: +1. Make parallel calls (Claude handles this automatically): + - mcp__plugin_api_server__get_project + - mcp__plugin_api_server__get_users + - mcp__plugin_api_server__get_tags +2. Wait for all to complete +3. Combine results +``` + +## Integration Best Practices + +### User Experience + +**Provide feedback:** +```markdown +Steps: +1. Inform user: "Searching Asana tasks..." +2. Call mcp__plugin_asana_asana__asana_search_tasks +3. Show progress: "Found 15 tasks, analyzing..." +4. Present results +``` + +**Handle long operations:** +```markdown +Steps: +1. Warn user: "This may take a minute..." +2. Break into smaller steps with updates +3. Show incremental progress +4. Final summary when complete +``` + +### Error Messages + +**Good error messages:** +``` +❌ "Could not create task. Please check: + 1. You're logged into Asana + 2. You have access to workspace 'Engineering' + 3. The project 'Q1 Goals' exists" +``` + +**Poor error messages:** +``` +❌ "Error: MCP tool returned 403" +``` + +### Documentation + +**Document MCP tool usage in command:** +```markdown +## MCP Tools Used + +This command uses the following Asana MCP tools: +- **asana_search_tasks**: Search for tasks matching criteria +- **asana_create_task**: Create new task with details +- **asana_update_task**: Update existing task properties + +Ensure you're authenticated to Asana before running this command. +``` + +## Testing Tool Usage + +### Local Testing + +1. **Configure MCP server** in `.mcp.json` +2. **Install plugin locally** in `.claude-plugin/` +3. **Verify tools available** with `/mcp` +4. **Test command** that uses tools +5. **Check debug output**: `claude --debug` + +### Test Scenarios + +**Test successful calls:** +```markdown +Steps: +1. Create test data in external service +2. Run command that queries this data +3. Verify correct results returned +``` + +**Test error cases:** +```markdown +Steps: +1. Test with missing authentication +2. Test with invalid parameters +3. Test with non-existent resources +4. Verify graceful error handling +``` + +**Test edge cases:** +```markdown +Steps: +1. Test with empty results +2. Test with maximum results +3. Test with special characters +4. Test with concurrent access +``` + +## Common Patterns + +### Pattern: CRUD Operations + +```markdown +--- +allowed-tools: [ + "mcp__plugin_api_server__create_item", + "mcp__plugin_api_server__read_item", + "mcp__plugin_api_server__update_item", + "mcp__plugin_api_server__delete_item" +] +--- + +# Item Management + +## Create +Use create_item with required fields... + +## Read +Use read_item with item ID... + +## Update +Use update_item with item ID and changes... + +## Delete +Use delete_item with item ID (ask for confirmation first)... +``` + +### Pattern: Search and Process + +```markdown +Steps: +1. **Search**: mcp__plugin_api_server__search with filters +2. **Filter**: Apply additional local filtering if needed +3. **Transform**: Process each result +4. **Present**: Format and display to user +``` + +### Pattern: Multi-Step Workflow + +```markdown +Steps: +1. **Setup**: Gather all required information +2. **Validate**: Check data completeness +3. **Execute**: Chain of MCP tool calls: + - Create parent resource + - Create child resources + - Link resources together + - Add metadata +4. **Verify**: Confirm all steps succeeded +5. **Report**: Provide summary to user +``` + +## Troubleshooting + +### Tools Not Available + +**Check:** +- MCP server configured correctly +- Server connected (check `/mcp`) +- Tool names match exactly (case-sensitive) +- Restart Claude Code after config changes + +### Tool Calls Failing + +**Check:** +- Authentication is valid +- Parameters match tool schema +- Required parameters provided +- Check `claude --debug` logs + +### Performance Issues + +**Check:** +- Batching queries instead of individual calls +- Caching results when appropriate +- Not making unnecessary tool calls +- Parallel calls when possible + +## Conclusion + +Effective MCP tool usage requires: +1. **Understanding tool schemas** via `/mcp` +2. **Pre-allowing tools** in commands appropriately +3. **Handling errors gracefully** +4. **Optimizing performance** with batching and caching +5. **Providing good UX** with feedback and clear errors +6. **Testing thoroughly** before deployment + +Follow these patterns for robust MCP tool integration in your plugin commands and agents. diff --git a/.claude/skills/playwright-agicash-navigation/SKILL.md b/.claude/skills/playwright-agicash-navigation/SKILL.md new file mode 100644 index 00000000..3290e3c9 --- /dev/null +++ b/.claude/skills/playwright-agicash-navigation/SKILL.md @@ -0,0 +1,263 @@ +--- +name: playwright-agicash-navigation +description: Navigate the Agicash Bitcoin wallet app efficiently using Playwright. Use when testing, automating, or navigating the Agicash web application, especially for authentication flows, wallet operations (send/receive), account management, and transaction history. Critical for handling OAuth redirects, Terms of Service modals, and understanding the app's route structure. +--- + +# Playwright Agicash Navigation + +Navigate the Agicash Bitcoin wallet app efficiently with Playwright, understanding its authentication flow, protected routes, and common interaction patterns. + +## Development Server + +Assume the app is already running and try the default server first: +- **Default URL**: `https://localhost:3000` + +If the default URL is unavailable, tell the user to start the server and ask where it is running (URL and protocol). Provide the default start command as a suggestion: +- **Start command**: `bun run dev --https` + +## Authentication Flow (CRITICAL) + +### Unauthenticated Access + +When not logged in, the app redirects to `/home` which shows a "Coming Soon" page with minimal content. This is NOT the main app. + +**To access the actual wallet app, you MUST authenticate first.** + +### Creating an Account + +**Always navigate directly to `/signup`** when you need to create an account. Do not try to access protected routes first. + +``` +Navigate to: https://localhost:3000/signup +``` + +The signup page offers three options: +1. **Email** - "Create wallet with Email" +2. **Google** - "Create wallet with Google" +3. **Guest** - "Create wallet as Guest" (RECOMMENDED for testing) + +### Guest Account Creation (Recommended) + +For automated testing, use guest accounts: + +1. Navigate to `https://localhost:3000/signup` +2. Click "Create wallet as Guest" button +3. **Accept Terms of Service modal**: + - Check the ToS checkbox + - Click "Continue" button +4. **Wait for authentication** (5 seconds recommended): + - The app performs cryptographic operations (attestation verification, key generation) + - Console shows logs about certificates and signature verification + - Redirects to `/` (main dashboard) when complete + +**Important**: The Continue button becomes enabled only after checking the ToS checkbox. The button will show a loading spinner during authentication. + +### Post-Authentication + +After successful authentication, the app redirects to the main wallet dashboard at `/`. + +## Main Routes + +### Dashboard (`/`) + +The main wallet screen showing: +- **Balance display**: Shows BTC and USD balance (initially ₿0 / $0.00) +- **Currency selector**: "BTC" button with dropdown icon +- **Primary actions**: + - "Receive" button → `/receive` + - "Send" button → `/send` +- **Top navigation**: + - Transactions icon → `/transactions` + - Settings icon → `/settings` + +### Receive (`/receive`) + +Receive bitcoin screen with: +- **Amount input**: Editable balance display with USD toggle button +- **Account selector**: Shows current account (e.g., "Spark Icon Bitcoin ₿0 (~$0.00)") +- **Action buttons**: + - Paste button (clipboard icon) + - Scan QR code link → `/receive/scan` +- **Continue button**: Disabled until valid input provided +- **Back button**: Returns to `/` + +### Send (`/send`) + +Send bitcoin screen with similar structure to Receive: +- **Amount input**: Editable balance display with USD toggle button +- **Account selector**: Shows current account +- **Action buttons**: + - Paste button (clipboard icon) + - Scan QR code link → `/send/scan` + - Additional action button +- **Continue button**: Disabled until valid input provided +- **Back button**: Returns to `/` + +### Transactions (`/transactions`) + +Transaction history page: +- **Header**: "Transactions" title with back button → `/` +- **Content**: Shows "No transactions found" for new accounts +- Eventually displays transaction list with details + +### Settings (`/settings`) + +Main settings page with: +- **User identifier**: Shows username (e.g., "user-cfc15ee8aed5@localhost:3000") with dropdown +- **Edit profile**: Link to `/settings/profile/edit` +- **Account selector**: Shows active account (e.g., "Spark Icon Bitcoin") → `/settings/accounts` +- **Contacts**: Link to `/settings/contacts` +- **Footer**: + - "Sign Out" button + - Theme toggle (system/dark/light) + - Links: Terms, Privacy + - Social links: X, Nostr, GitHub, Discord +- **Back button**: Returns to `/` + +### Accounts (`/settings/accounts`) + +Account management page with: +- **Header**: "Accounts" title with back button → `/settings` +- **Tabs**: "Bitcoin" and "USD" currency tabs +- **Account list**: Shows all accounts for selected currency + - Each account shows name, balance, and "Default" badge if applicable + - Accounts are clickable → `/settings/accounts/{account-id}` + - Example accounts: "Bitcoin ₿0 (~$0.00) Default", "Testnut BTC ₿0 (~$0.00)" +- **Add Account button**: Floating action → `/settings/accounts/create/cashu` + +## Common Navigation Patterns + +### Back Navigation + +Most pages have a back button in the top-left corner of the banner: +- Usually an arrow icon that links to the parent route +- From `/transactions`, `/send`, `/receive` → back to `/` +- From `/settings/accounts` → back to `/settings` +- From sub-settings pages → back to `/settings` + +### Link vs Button Navigation + +The app uses both links and buttons for navigation: +- **Links** (`` tags with `/url:`): Use `browser_click` on the link +- **Buttons** that navigate: Use `browser_click` on the button, which triggers programmatic navigation + +### Loading States + +After clicking buttons that trigger navigation or actions: +- Buttons may show loading spinners (disabled state with spinner icon) +- Wait 2-5 seconds for operations to complete +- Use `browser_wait_for` with time parameter for cryptographic operations +- Check for URL changes or new page content to confirm navigation + +### Modal Dialogs + +The app uses modal dialogs for: +- **Terms of Service**: Appears during signup, requires checkbox + Continue +- **Account selection**: Dropdown modals for choosing accounts +- **Amount input**: USD/BTC toggle modals + +When a modal appears, interact with its elements before attempting to navigate away. + +### Amount Input on Send/Receive + +On `/send` and `/receive` routes, there is **no visible input field** for the amount. The page captures keyboard input directly: + +1. Navigate to `/send` or `/receive` +2. Use `browser_press_key` to type digits (e.g., `1`, `0`, `0` for 100 sats) +3. The display updates in real-time (e.g., `₿0` → `₿1` → `₿10` → `₿100`) +4. The Continue button enables once a valid amount is entered + +```javascript +// Example: Enter 100 sats +await browser_press_key({ key: '1' }); +await browser_press_key({ key: '0' }); +await browser_press_key({ key: '0' }); +// Display now shows ₿100, Continue button is enabled +``` + +**Note**: Clicking on the amount display area does nothing - just start typing immediately after the page loads. + +## Expected Behaviors + +### Initial Load + +- Navigate to `https://localhost:3000` +- May show loading logo briefly +- Redirects to `/home` if not authenticated, or `/` if authenticated +- Console shows React DevTools and Vercel Analytics messages + +### Authentication Redirects + +- Accessing protected routes when not logged in redirects to `/home` +- After authentication, redirects to `/` (main dashboard) +- Some auth routes may redirect through `/signup` or `/login` + +### Page Transitions + +- URL changes trigger page view analytics logs: `[Vercel Web Analytics] [pageview] https://localhost:3000/{path}` +- New pages may show loading states before content appears +- Images and icons may trigger preload warnings in console + +### Console Messages + +Normal console output includes: +- React DevTools download prompt (INFO) +- Vercel Web Analytics debug messages (LOG) +- Resource preload warnings for icons (WARNING) +- Buffer module externalization warnings (WARNING) +- During authentication: Certificate verification and attestation logs (LOG) + +## Tips for Efficient Navigation + +1. **Always start with authentication** - Navigate to `/signup` first if testing from scratch +2. **Use guest accounts** - Fastest way to get authenticated for testing +3. **Wait for crypto operations** - Authentication and key operations take 3-5 seconds +4. **Check URL changes** - Confirm navigation by checking `page.url` +5. **Use browser_snapshot** - Get full page state and element references efficiently +6. **Handle modals immediately** - Don't try to navigate past unclosed modals +7. **Reference elements by ref** - Use the `ref` values from snapshots for reliable interactions +8. **Expect redirects** - Protected routes redirect when not authenticated + +## Troubleshooting + +### "No transactions found" / Empty balances + +This is expected for new accounts. The app starts with ₿0 and no transaction history. + +### Stuck on "Coming Soon" page + +You're on `/home` (unauthenticated). Navigate to `/signup` to create an account. + +### Continue button disabled + +Check that all required inputs are filled and checkboxes (like ToS) are checked. + +### Authentication hangs + +Wait 5-10 seconds for cryptographic operations. Check console for attestation verification logs. + +### Unexpected redirects + +Protected routes redirect to `/home` when not authenticated. Always authenticate first. + +### Authentication Fails / Invalid Credentials + +If authentication fails with errors like "Invalid email, password, or login method" or the console shows `Failed to create guest account`: + +**Tell the user:** +> "Authentication failed. This usually happens when existing localStorage credentials are invalid (e.g., after a database reset or environment change)." + +**Suggested fixes:** +1. **Clear localStorage and retry**: Use `browser_evaluate` to clear auth-related keys: + ```javascript + () => { + localStorage.removeItem('guestAccount'); + localStorage.removeItem('access_token'); + localStorage.removeItem('refresh_token'); + } + ``` +2. **Navigate to `/signup` and create a fresh guest account** - go through the full signup flow +3. **Check if the dev server is running** - ensure `bun run dev --https` is active +4. **Verify the backend/database is accessible** - the app may be unable to reach authentication services + +**Do NOT** attempt to store or reuse guest credentials across sessions - they are tied to the specific environment and database state. diff --git a/.claude/skills/skill-creator/SKILL.md b/.claude/skills/skill-creator/SKILL.md index b5cd4ff3..35285956 100644 --- a/.claude/skills/skill-creator/SKILL.md +++ b/.claude/skills/skill-creator/SKILL.md @@ -208,8 +208,7 @@ Skill creation involves these steps: 2. Plan reusable skill contents (scripts, references, assets) 3. Initialize the skill (run init_skill.py) 4. Edit the skill (implement resources and write SKILL.md) -5. Package the skill (run package_skill.py) -6. Iterate based on real usage +5. Iterate based on real usage Follow these steps in order, skipping only if there is a clear reason why they are not applicable. @@ -258,7 +257,7 @@ To establish the skill's contents, analyze each concrete example to create a lis At this point, it is time to actually create the skill. -Skip this step only if the skill being developed already exists, and iteration or packaging is needed. In this case, continue to the next step. +Skip this step only if the skill being developed already exists, and iteration is needed. In this case, continue to the next step. When creating a new skill from scratch, always run the `init_skill.py` script. The script conveniently generates a new template skill directory that automatically includes everything a skill requires, making the skill creation process much more efficient and reliable. @@ -318,34 +317,7 @@ Do not include any other fields in YAML frontmatter. Write instructions for using the skill and its bundled resources. -### Step 5: Packaging a Skill - -Once development of the skill is complete, it must be packaged into a distributable .skill file that gets shared with the user. The packaging process automatically validates the skill first to ensure it meets all requirements: - -```bash -scripts/package_skill.py -``` - -Optional output directory specification: - -```bash -scripts/package_skill.py ./dist -``` - -The packaging script will: - -1. **Validate** the skill automatically, checking: - - - YAML frontmatter format and required fields - - Skill naming conventions and directory structure - - Description completeness and quality - - File organization and resource references - -2. **Package** the skill if validation passes, creating a .skill file named after the skill (e.g., `my-skill.skill`) that includes all files and maintains the proper directory structure for distribution. The .skill file is a zip file with a .skill extension. - -If validation fails, the script will report the errors and exit without creating a package. Fix any validation errors and run the packaging command again. - -### Step 6: Iterate +### Step 5: Iterate After testing the skill, users may request improvements. Often this happens right after using the skill, with fresh context of how the skill performed. diff --git a/.gitignore b/.gitignore index 6e3cb5d7..e324ca36 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,6 @@ node_modules /certs/* !/certs/ci-localhost-cert.pem !/certs/ci-localhost-key.pem + +# Playwright MCP artifacts +.playwright-mcp/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 00000000..26402c16 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "playwright": { + "command": "bunx", + "args": ["@playwright/mcp@latest", "--browser", "firefox"] + } + } +} diff --git a/CLAUDE.md b/CLAUDE.md index b9c52a8f..4f30707a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -117,6 +117,8 @@ Use these for specialized guidance: - `/react-router-v7-expert` - Routes, loaders, layouts, middleware - `/design-motion-principles` - Animation and motion design - `/tailwind-design-system` - Component styling patterns +- `/skill-creator` - Create new skils for claude code +- `/mcp-integration` - How to integrate mcp servers with claude code ## Commands diff --git a/package.json b/package.json index 8f924ed8..f04ebe52 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "build": "run-p build:client build:server", "build:client": "react-router build", "build:server": "cross-env NODE_ENV=production bun build ./app/server.ts --target=node --format=esm --outdir=./build --external=build/server/index.js", - "dev": "cross-env NODE_OPTIONS='--max-old-space-size=8192 --use-system-ca' tsx watch ./app/server.ts", + "dev": "cross-env NODE_OPTIONS='--max-old-space-size=8192' tsx watch ./app/server.ts", "start": "cross-env NODE_ENV=production node -r dotenv/config ./build/server.js", "typecheck": "react-router typegen && tsc", "lint": "biome lint --write", @@ -22,7 +22,7 @@ "db:generate-types": "supabase gen types typescript --local --schema wallet > supabase/database.types.ts" }, "scripts:comments": { - "dev": "We use tsx instead of bun (bun hangs with 'ELOOP: too many symbolic links'). --use-system-ca enables Node.js to trust system CA certificates for Supabase TLS connections. Use --https flag for HTTPS mode.", + "dev": "We use tsx instead of bun (bun hangs with 'ELOOP: too many symbolic links'). Use NODE_EXTRA_CA_CERTS for Supabase TLS connections when needed. Use --https flag for HTTPS mode.", "build:server": "We are building for node for now. We will see what we will be using in the runtime once we implement the deployment. Depending on that we might change this to target bun. 'cross-env NODE_ENV=production' is needed because bun build otherwise seems to be setting it to 'development'.", "start": "We are running the build in node because atm we are using node as the build target." },