From e129b683a8e8f0cfa602f9c202bd213b320672dd Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Mon, 9 Jun 2025 12:41:37 -0700 Subject: [PATCH] Add marketplace endpoints (#89) --- src/app/api/marketplace/mcps/route.ts | 56 ++++++++++++++++++++++++++ src/app/api/marketplace/modes/route.ts | 56 ++++++++++++++++++++++++++ src/data/marketplace/mcps.yml | 41 +++++++++++++++++++ src/data/marketplace/modes.yml | 51 +++++++++++++++++++++++ src/middleware.ts | 1 + 5 files changed, 205 insertions(+) create mode 100644 src/app/api/marketplace/mcps/route.ts create mode 100644 src/app/api/marketplace/modes/route.ts create mode 100644 src/data/marketplace/mcps.yml create mode 100644 src/data/marketplace/modes.yml diff --git a/src/app/api/marketplace/mcps/route.ts b/src/app/api/marketplace/mcps/route.ts new file mode 100644 index 0000000000..b14e1269dd --- /dev/null +++ b/src/app/api/marketplace/mcps/route.ts @@ -0,0 +1,56 @@ +import { NextResponse } from 'next/server'; +import { readFile } from 'fs/promises'; +import path from 'path'; + +export async function GET() { + try { + // Construct the path to the YAML file + const filePath = path.join( + process.cwd(), + 'src', + 'data', + 'marketplace', + 'mcps.yml', + ); + + // Read the file content + const content = await readFile(filePath, 'utf-8'); + + // Return the content with appropriate headers + return new NextResponse(content, { + status: 200, + headers: { + 'Content-Type': 'application/x-yaml', + 'Access-Control-Allow-Origin': '*', // Allow CORS for extension access + 'Access-Control-Allow-Methods': 'GET', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }); + } catch (error) { + console.error('Error reading mcps.yml:', error); + + if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { + return NextResponse.json( + { error: 'MCPS configuration file not found' }, + { status: 404 }, + ); + } + + return NextResponse.json( + { error: 'Failed to load MCPS configuration' }, + { status: 500 }, + ); + } +} + +// Handle OPTIONS requests for CORS preflight +export async function OPTIONS() { + return new NextResponse(null, { + status: 200, + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }); +} diff --git a/src/app/api/marketplace/modes/route.ts b/src/app/api/marketplace/modes/route.ts new file mode 100644 index 0000000000..22097a186d --- /dev/null +++ b/src/app/api/marketplace/modes/route.ts @@ -0,0 +1,56 @@ +import { NextResponse } from 'next/server'; +import { readFile } from 'fs/promises'; +import path from 'path'; + +export async function GET() { + try { + // Construct the path to the YAML file + const filePath = path.join( + process.cwd(), + 'src', + 'data', + 'marketplace', + 'modes.yml', + ); + + // Read the file content + const content = await readFile(filePath, 'utf-8'); + + // Return the content with appropriate headers + return new NextResponse(content, { + status: 200, + headers: { + 'Content-Type': 'application/x-yaml', + 'Access-Control-Allow-Origin': '*', // Allow CORS for extension access + 'Access-Control-Allow-Methods': 'GET', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }); + } catch (error) { + console.error('Error reading modes.yml:', error); + + if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { + return NextResponse.json( + { error: 'Modes configuration file not found' }, + { status: 404 }, + ); + } + + return NextResponse.json( + { error: 'Failed to load modes configuration' }, + { status: 500 }, + ); + } +} + +// Handle OPTIONS requests for CORS preflight +export async function OPTIONS() { + return new NextResponse(null, { + status: 200, + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'GET', + 'Access-Control-Allow-Headers': 'Content-Type', + }, + }); +} diff --git a/src/data/marketplace/mcps.yml b/src/data/marketplace/mcps.yml new file mode 100644 index 0000000000..8d1fd64971 --- /dev/null +++ b/src/data/marketplace/mcps.yml @@ -0,0 +1,41 @@ +items: + - id: "filesystem" + name: "File System" + description: "Provides comprehensive filesystem operations including reading, writing, moving files, directory management, and advanced file editing with pattern matching and formatting capabilities." + author: "modelcontextprotocol" + url: "https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem" + tags: ["filesystem", "file-management", "directory-operations", "file-search", "file-editing"] + content: + - name: "NPX (Node.js)" + content: | + { + "filesystem": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", "{{ALLOWED_DIRECTORY}}"] + } + } + - name: "Docker" + content: | + { + "filesystem": { + "command": "docker", + "args": ["run", "-v", "{{ALLOWED_DIRECTORY}}:/workspace", "mcp/filesystem:latest"] + } + } + parameters: + - name: "Allowed Directory" + key: "ALLOWED_DIRECTORY" + placeholder: "/Users/username/Documents" + - id: "sequentialthinking" + name: "Sequential Thinking" + description: "A structured problem-solving tool that enables step-by-step analysis, thought revision, and branching logic for complex reasoning tasks." + author: "modelcontextprotocol" + url: "https://github.com/modelcontextprotocol/servers/tree/main/src/sequentialthinking" + tags: ["problem-solving", "reasoning", "analysis", "structured-thinking", "decision-making"] + content: | + { + "sequentialthinking": { + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"] + } + } \ No newline at end of file diff --git a/src/data/marketplace/modes.yml b/src/data/marketplace/modes.yml new file mode 100644 index 0000000000..dd7d89f7e7 --- /dev/null +++ b/src/data/marketplace/modes.yml @@ -0,0 +1,51 @@ +items: + - id: python-expert + name: Python Expert + description: Specialized mode for Python development with best practices + author: Roo Code + tags: [python, development, expert] + content: | + slug: python-expert + name: Python Expert + roleDefinition: | + You are a Python expert with deep knowledge of best practices, design patterns, and the Python ecosystem. + Focus on writing clean, efficient, and maintainable Python code. Use type hints, follow PEP 8, and suggest + appropriate libraries and frameworks for the task at hand. + groups: + - read + - edit + - command + + - id: react-specialist + name: React Specialist + description: Expert in React development and modern frontend practices + author: Frontend Team + tags: [react, frontend, javascript] + content: | + slug: react-specialist + name: React Specialist + roleDefinition: | + You are a React specialist with expertise in modern React patterns, hooks, and performance optimization. + Focus on component-based architecture, state management, and best practices for React applications. + Use TypeScript when appropriate and suggest modern tooling. + groups: + - read + - edit + - command + + - id: devops-engineer + name: DevOps Engineer + description: Infrastructure and deployment specialist + author: DevOps Team + tags: [devops, infrastructure, deployment] + content: | + slug: devops-engineer + name: DevOps Engineer + roleDefinition: | + You are a DevOps engineer with expertise in infrastructure as code, CI/CD pipelines, containerization, + and cloud platforms. Focus on automation, scalability, and reliability. Suggest appropriate tools + and practices for deployment and monitoring. + groups: + - read + - edit + - command \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index 8f2316f7d3..0b0dcc0ef4 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -4,6 +4,7 @@ const isUnprotectedRoute = createRouteMatcher([ '/sign-in(.*)', '/sign-up(.*)', '/extension/sign-in(.*)', + '/api/marketplace(.*)', '/', ]);