github-to-mcp-monorepo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +8 -0
- package/.github/CODEOWNERS +6 -0
- package/.husky/pre-commit +1 -0
- package/.nvmrc +1 -0
- package/.prettierignore +5 -0
- package/.prettierrc +7 -0
- package/.vscode/settings.json +4 -0
- package/ARCHITECTURE.md +1429 -0
- package/CHANGELOG.md +167 -0
- package/CONTRIBUTING.md +327 -0
- package/LICENSE +201 -0
- package/README.md +1028 -0
- package/SECURITY.md +248 -0
- package/VISUAL_GUIDE.md +437 -0
- package/apps/vscode/IMPLEMENTATION.md +480 -0
- package/apps/vscode/README.md +248 -0
- package/apps/vscode/package.json +381 -0
- package/apps/vscode/resources/icon.png +0 -0
- package/apps/vscode/resources/icon.svg +5 -0
- package/apps/vscode/src/commands/browseRegistry.ts +211 -0
- package/apps/vscode/src/commands/configureClaudeDesktop.ts +332 -0
- package/apps/vscode/src/commands/convert.ts +82 -0
- package/apps/vscode/src/commands/convertCurrentRepo.ts +109 -0
- package/apps/vscode/src/commands/convertFromUrl.ts +138 -0
- package/apps/vscode/src/commands/index.ts +121 -0
- package/apps/vscode/src/commands/validate.ts +197 -0
- package/apps/vscode/src/extension.ts +464 -0
- package/apps/vscode/src/global.d.ts +36 -0
- package/apps/vscode/src/test/extension.test.ts +73 -0
- package/apps/vscode/src/utils/file-generator.ts +529 -0
- package/apps/vscode/src/utils/github-api.ts +335 -0
- package/apps/vscode/src/utils/index.ts +29 -0
- package/apps/vscode/src/utils/mcp-config.ts +334 -0
- package/apps/vscode/src/utils/storage.ts +87 -0
- package/apps/vscode/src/views/McpServersTreeView.ts +160 -0
- package/apps/vscode/src/views/OutputChannelView.ts +195 -0
- package/apps/vscode/src/views/StatusBarItem.ts +251 -0
- package/apps/vscode/src/views/ToolsExplorerView.ts +314 -0
- package/apps/vscode/src/views/historyProvider.ts +75 -0
- package/apps/vscode/src/views/index.ts +12 -0
- package/apps/vscode/src/views/resultsPanel.ts +330 -0
- package/apps/vscode/src/webviews/ConversionPanel.ts +350 -0
- package/apps/vscode/src/webviews/ToolDetailsPanel.ts +448 -0
- package/apps/vscode/src/webviews/index.ts +9 -0
- package/apps/vscode/src/webviews/webview-ui/styles.ts +492 -0
- package/apps/vscode/tsconfig.json +20 -0
- package/apps/web/PLAYGROUND_GUIDE.md +499 -0
- package/apps/web/README.md +505 -0
- package/apps/web/app/api/convert/route.ts +100 -0
- package/apps/web/app/api/convert/stream/route.ts +198 -0
- package/apps/web/app/api/deploy/route.ts +157 -0
- package/apps/web/app/api/edge/route.ts +308 -0
- package/apps/web/app/api/export-docker/route.ts +284 -0
- package/apps/web/app/api/generate-openapi/route.ts +119 -0
- package/apps/web/app/api/mcp/[serverId]/route.ts +263 -0
- package/apps/web/app/api/playground/connect/route.ts +143 -0
- package/apps/web/app/api/playground/disconnect/route.ts +78 -0
- package/apps/web/app/api/playground/execute/route.ts +135 -0
- package/apps/web/app/api/playground/sessions/route.ts +103 -0
- package/apps/web/app/api/playground/tools/route.ts +117 -0
- package/apps/web/app/api/playground/v2/connect/route.ts +96 -0
- package/apps/web/app/api/playground/v2/disconnect/route.ts +88 -0
- package/apps/web/app/api/playground/v2/health/route.ts +80 -0
- package/apps/web/app/api/playground/v2/prompts/route.ts +160 -0
- package/apps/web/app/api/playground/v2/resources/route.ts +159 -0
- package/apps/web/app/api/playground/v2/sessions/route.ts +184 -0
- package/apps/web/app/api/playground/v2/tools/route.ts +167 -0
- package/apps/web/app/api/stream/route.ts +232 -0
- package/apps/web/app/batch/BatchConvertClient.tsx +190 -0
- package/apps/web/app/batch/page.tsx +37 -0
- package/apps/web/app/convert/page.tsx +269 -0
- package/apps/web/app/dashboard/page.tsx +380 -0
- package/apps/web/app/globals.css +622 -0
- package/apps/web/app/layout.tsx +120 -0
- package/apps/web/app/manifest.ts +31 -0
- package/apps/web/app/opengraph-image.tsx +112 -0
- package/apps/web/app/page.old.tsx +924 -0
- package/apps/web/app/page.tsx +77 -0
- package/apps/web/app/playground/page.tsx +306 -0
- package/apps/web/app/playground/v2/error.tsx +163 -0
- package/apps/web/app/playground/v2/layout.tsx +58 -0
- package/apps/web/app/playground/v2/loading.tsx +152 -0
- package/apps/web/app/playground/v2/page.tsx +644 -0
- package/apps/web/app/playground/v2/providers.tsx +214 -0
- package/apps/web/app/playground/v2/use-shortcuts.ts +209 -0
- package/apps/web/app/playground/v2/use-url-state.ts +296 -0
- package/apps/web/app/providers.tsx +22 -0
- package/apps/web/app/sitemap.ts +32 -0
- package/apps/web/app/twitter-image.tsx +112 -0
- package/apps/web/components/BranchSelector.tsx +401 -0
- package/apps/web/components/ClaudeConfigExport.tsx +226 -0
- package/apps/web/components/Features.tsx +84 -0
- package/apps/web/components/Footer.tsx +119 -0
- package/apps/web/components/GenerationProgress.tsx +248 -0
- package/apps/web/components/GithubUrlInput.tsx +483 -0
- package/apps/web/components/Header.tsx +175 -0
- package/apps/web/components/Hero.tsx +117 -0
- package/apps/web/components/HowItWorks.tsx +119 -0
- package/apps/web/components/InstallBanner.tsx +158 -0
- package/apps/web/components/Logo.tsx +116 -0
- package/apps/web/components/ParticleBackground.tsx +105 -0
- package/apps/web/components/Playground.tsx +472 -0
- package/apps/web/components/PlaygroundToolTester.tsx +410 -0
- package/apps/web/components/ProductCards.tsx +179 -0
- package/apps/web/components/SplitView.tsx +194 -0
- package/apps/web/components/ToolFilter.tsx +260 -0
- package/apps/web/components/ToolList.tsx +325 -0
- package/apps/web/components/batch/BatchConvert.tsx +785 -0
- package/apps/web/components/batch/index.ts +7 -0
- package/apps/web/components/convert/ConfigTabs.tsx +230 -0
- package/apps/web/components/convert/ConversionResult.tsx +482 -0
- package/apps/web/components/convert/InlinePlayground.tsx +259 -0
- package/apps/web/components/convert/LoadingSteps.tsx +311 -0
- package/apps/web/components/convert/OneClickInstall.tsx +224 -0
- package/apps/web/components/convert/ToolCard.tsx +189 -0
- package/apps/web/components/convert/TryInPlayground.tsx +242 -0
- package/apps/web/components/convert/index.ts +12 -0
- package/apps/web/components/deploy/DeployButton.tsx +369 -0
- package/apps/web/components/deploy/index.ts +7 -0
- package/apps/web/components/docker/DockerExport.tsx +690 -0
- package/apps/web/components/docker/index.ts +7 -0
- package/apps/web/components/install/OneClickInstall.tsx +676 -0
- package/apps/web/components/install/index.ts +7 -0
- package/apps/web/components/playground/CapabilityTabs.tsx +150 -0
- package/apps/web/components/playground/ConnectionStatusV2.tsx +322 -0
- package/apps/web/components/playground/EmptyStates.tsx +305 -0
- package/apps/web/components/playground/ExecutionLog.tsx +260 -0
- package/apps/web/components/playground/ExecutionLogV2.tsx +378 -0
- package/apps/web/components/playground/JsonViewer.tsx +388 -0
- package/apps/web/components/playground/PlaygroundLayout.tsx +244 -0
- package/apps/web/components/playground/PromptsPanel.tsx +385 -0
- package/apps/web/components/playground/ResourcesPanel.tsx +378 -0
- package/apps/web/components/playground/SchemaForm.tsx +477 -0
- package/apps/web/components/playground/ServerStatus.tsx +151 -0
- package/apps/web/components/playground/ShareButton.tsx +239 -0
- package/apps/web/components/playground/ToolsPanel.tsx +309 -0
- package/apps/web/components/playground/TransportConfigurator.tsx +563 -0
- package/apps/web/components/playground/index.ts +74 -0
- package/apps/web/components/playground/types.ts +202 -0
- package/apps/web/components/streaming/StreamingProgress.tsx +441 -0
- package/apps/web/components/streaming/index.ts +7 -0
- package/apps/web/components/ui/badge.tsx +42 -0
- package/apps/web/components/ui/button.tsx +88 -0
- package/apps/web/components/ui/card.tsx +75 -0
- package/apps/web/components/ui/code-block.tsx +122 -0
- package/apps/web/components/ui/index.ts +12 -0
- package/apps/web/components/ui/input.tsx +55 -0
- package/apps/web/components/ui/tabs.tsx +61 -0
- package/apps/web/hooks/index.ts +85 -0
- package/apps/web/hooks/types.ts +1173 -0
- package/apps/web/hooks/use-conversion.ts +133 -0
- package/apps/web/hooks/use-execution-history.ts +376 -0
- package/apps/web/hooks/use-generation-progress.ts +147 -0
- package/apps/web/hooks/use-local-storage.ts +88 -0
- package/apps/web/hooks/use-mcp-client.ts +623 -0
- package/apps/web/hooks/use-mcp-connection.ts +500 -0
- package/apps/web/hooks/use-mcp-execution.ts +282 -0
- package/apps/web/hooks/use-mcp-prompts.ts +441 -0
- package/apps/web/hooks/use-mcp-resources.ts +430 -0
- package/apps/web/hooks/use-mcp-tools.ts +540 -0
- package/apps/web/hooks/use-playground-store.ts +299 -0
- package/apps/web/hooks/use-playground.ts +184 -0
- package/apps/web/hooks/use-streaming-conversion.ts +227 -0
- package/apps/web/hooks/useBatchConversion.ts +271 -0
- package/apps/web/hooks/useDockerConfig.ts +161 -0
- package/apps/web/hooks/usePlatformDetection.ts +80 -0
- package/apps/web/hooks/useStreaming.ts +199 -0
- package/apps/web/lib/api/errors.ts +386 -0
- package/apps/web/lib/api/index.ts +137 -0
- package/apps/web/lib/api/logger.ts +187 -0
- package/apps/web/lib/api/middleware.ts +364 -0
- package/apps/web/lib/api/openapi.ts +977 -0
- package/apps/web/lib/api/session-manager.ts +594 -0
- package/apps/web/lib/api/types.ts +433 -0
- package/apps/web/lib/api/validation.ts +523 -0
- package/apps/web/lib/constants.ts +114 -0
- package/apps/web/lib/mcp/client.ts +1137 -0
- package/apps/web/lib/mcp/events.ts +651 -0
- package/apps/web/lib/mcp/index.ts +347 -0
- package/apps/web/lib/mcp/logger.ts +428 -0
- package/apps/web/lib/mcp/metrics.ts +703 -0
- package/apps/web/lib/mcp/retry.ts +616 -0
- package/apps/web/lib/mcp/session-manager.ts +779 -0
- package/apps/web/lib/mcp/transports.ts +988 -0
- package/apps/web/lib/mcp/types.ts +594 -0
- package/apps/web/lib/mcp-client-enhanced.ts +871 -0
- package/apps/web/lib/mcp-client.ts +778 -0
- package/apps/web/lib/mcp-errors.ts +489 -0
- package/apps/web/lib/mcp-sandbox.ts +593 -0
- package/apps/web/lib/mcp-testing.ts +428 -0
- package/apps/web/lib/mcp-types.ts +448 -0
- package/apps/web/lib/playground-store.tsx +1147 -0
- package/apps/web/lib/utils.ts +439 -0
- package/apps/web/next-env.d.ts +5 -0
- package/apps/web/next.config.js +23 -0
- package/apps/web/package.json +55 -0
- package/apps/web/postcss.config.js +6 -0
- package/apps/web/public/.well-known/ai-plugin.json +17 -0
- package/apps/web/public/logo.svg +6 -0
- package/apps/web/public/robots.txt +22 -0
- package/apps/web/public/schema.json +27 -0
- package/apps/web/tailwind.config.js +26 -0
- package/apps/web/tailwind.config.ts +123 -0
- package/apps/web/tsconfig.json +20 -0
- package/apps/web/types/deploy.ts +139 -0
- package/apps/web/types/index.ts +247 -0
- package/apps/web/vercel.json +39 -0
- package/eslint.config.mjs +23 -0
- package/llms.txt +102 -0
- package/mkdocs/docs/api/core.md +318 -0
- package/mkdocs/docs/api/index.md +128 -0
- package/mkdocs/docs/api/mcp-server.md +301 -0
- package/mkdocs/docs/api/openapi-parser.md +254 -0
- package/mkdocs/docs/assets/logo.svg +7 -0
- package/mkdocs/docs/changelog.md +118 -0
- package/mkdocs/docs/cli/generate.md +148 -0
- package/mkdocs/docs/cli/index.md +52 -0
- package/mkdocs/docs/cli/inspect.md +164 -0
- package/mkdocs/docs/cli/serve.md +136 -0
- package/mkdocs/docs/concepts/classification.md +254 -0
- package/mkdocs/docs/concepts/how-it-works.md +299 -0
- package/mkdocs/docs/concepts/index.md +77 -0
- package/mkdocs/docs/concepts/mcp-protocol.md +362 -0
- package/mkdocs/docs/concepts/tool-types.md +382 -0
- package/mkdocs/docs/contributing/architecture.md +262 -0
- package/mkdocs/docs/contributing/development.md +245 -0
- package/mkdocs/docs/contributing/index.md +73 -0
- package/mkdocs/docs/contributing/testing.md +320 -0
- package/mkdocs/docs/getting-started/configuration.md +235 -0
- package/mkdocs/docs/getting-started/index.md +54 -0
- package/mkdocs/docs/getting-started/installation.md +145 -0
- package/mkdocs/docs/getting-started/quickstart.md +160 -0
- package/mkdocs/docs/guides/batch.md +375 -0
- package/mkdocs/docs/guides/claude-desktop.md +227 -0
- package/mkdocs/docs/guides/cursor.md +188 -0
- package/mkdocs/docs/guides/custom-tools.md +367 -0
- package/mkdocs/docs/guides/index.md +78 -0
- package/mkdocs/docs/guides/private-repos.md +221 -0
- package/mkdocs/docs/guides/vscode.md +247 -0
- package/mkdocs/docs/index.md +175 -0
- package/mkdocs/docs/reference/config.md +223 -0
- package/mkdocs/docs/reference/env.md +192 -0
- package/mkdocs/docs/reference/index.md +102 -0
- package/mkdocs/docs/reference/tools.md +309 -0
- package/mkdocs/docs/stylesheets/extra.css +231 -0
- package/mkdocs/mkdocs.yml +204 -0
- package/mkdocs/overrides/.gitkeep +1 -0
- package/mkdocs/overrides/main.html +7 -0
- package/mkdocs/python-deps.txt +7 -0
- package/mkdocs/vercel.json +11 -0
- package/package.json +63 -0
- package/packages/core/package.json +61 -0
- package/packages/core/src/__tests__/bitbucket-client.test.ts +366 -0
- package/packages/core/src/__tests__/cli.test.ts +235 -0
- package/packages/core/src/__tests__/code-extractor.test.ts +378 -0
- package/packages/core/src/__tests__/docker-generator.test.ts +255 -0
- package/packages/core/src/__tests__/github-client.test.ts +390 -0
- package/packages/core/src/__tests__/gitlab-client.test.ts +319 -0
- package/packages/core/src/__tests__/go-extractor.test.ts +351 -0
- package/packages/core/src/__tests__/graphql-extractor.test.ts +330 -0
- package/packages/core/src/__tests__/java-extractor.test.ts +497 -0
- package/packages/core/src/__tests__/plugins.test.ts +467 -0
- package/packages/core/src/__tests__/readme-extractor.test.ts +258 -0
- package/packages/core/src/__tests__/redis-cache.test.ts +307 -0
- package/packages/core/src/__tests__/rust-extractor.test.ts +252 -0
- package/packages/core/src/__tests__/streaming.test.ts +251 -0
- package/packages/core/src/additional-extractors.ts +333 -0
- package/packages/core/src/cache/cache-interface.ts +179 -0
- package/packages/core/src/cache/index.ts +210 -0
- package/packages/core/src/cache/redis-cache.ts +291 -0
- package/packages/core/src/cache/upstash-cache.ts +379 -0
- package/packages/core/src/cache.ts +251 -0
- package/packages/core/src/cli.ts +822 -0
- package/packages/core/src/code-extractor.ts +696 -0
- package/packages/core/src/docker-generator.ts +470 -0
- package/packages/core/src/edge-compatible.ts +491 -0
- package/packages/core/src/extractors/go-extractor.ts +791 -0
- package/packages/core/src/extractors/index.ts +9 -0
- package/packages/core/src/extractors/java-extractor.ts +937 -0
- package/packages/core/src/extractors/rust-extractor.ts +744 -0
- package/packages/core/src/github-client.ts +319 -0
- package/packages/core/src/go-generator.ts +356 -0
- package/packages/core/src/graphql-extractor.ts +358 -0
- package/packages/core/src/index.ts +797 -0
- package/packages/core/src/langchain-exporter.ts +617 -0
- package/packages/core/src/language-parsers.ts +1114 -0
- package/packages/core/src/mcp-introspector.ts +279 -0
- package/packages/core/src/monorepo-detector.ts +378 -0
- package/packages/core/src/plugins/index.ts +370 -0
- package/packages/core/src/plugins/registry.ts +404 -0
- package/packages/core/src/plugins/types.ts +215 -0
- package/packages/core/src/providers/base-provider.ts +246 -0
- package/packages/core/src/providers/bitbucket-client.ts +464 -0
- package/packages/core/src/providers/gitlab-client.ts +388 -0
- package/packages/core/src/providers/index.ts +176 -0
- package/packages/core/src/python-generator.ts +260 -0
- package/packages/core/src/queue/index.ts +100 -0
- package/packages/core/src/queue/memory-queue.ts +445 -0
- package/packages/core/src/queue/redis-queue.ts +578 -0
- package/packages/core/src/queue/types.ts +251 -0
- package/packages/core/src/readme-extractor.ts +409 -0
- package/packages/core/src/schema-generator.ts +638 -0
- package/packages/core/src/streaming.ts +999 -0
- package/packages/core/src/types.ts +289 -0
- package/packages/core/tsconfig.json +9 -0
- package/packages/core/tsup.config.ts +25 -0
- package/packages/mcp-server/README.md +297 -0
- package/packages/mcp-server/package.json +55 -0
- package/packages/mcp-server/src/__tests__/mcp-server.test.ts +177 -0
- package/packages/mcp-server/src/__tests__/tools.test.ts +217 -0
- package/packages/mcp-server/src/index.ts +1206 -0
- package/packages/mcp-server/src/prompts/index.ts +601 -0
- package/packages/mcp-server/src/tools/export-docker.ts +362 -0
- package/packages/mcp-server/src/tools/generate-openapi.ts +162 -0
- package/packages/mcp-server/src/tools/monitor-mcp-server.ts +448 -0
- package/packages/mcp-server/src/tools/stream-convert.ts +398 -0
- package/packages/mcp-server/src/tools/test-mcp-tool.ts +531 -0
- package/packages/mcp-server/tsconfig.json +12 -0
- package/packages/mcp-server/tsup.config.ts +14 -0
- package/packages/openapi-parser/package-lock.json +3028 -0
- package/packages/openapi-parser/package.json +41 -0
- package/packages/openapi-parser/src/analyzer.ts +700 -0
- package/packages/openapi-parser/src/asyncapi-parser.ts +475 -0
- package/packages/openapi-parser/src/cli.ts +302 -0
- package/packages/openapi-parser/src/generator.ts +570 -0
- package/packages/openapi-parser/src/generators/express-analyzer.ts +649 -0
- package/packages/openapi-parser/src/generators/fastapi-analyzer.ts +960 -0
- package/packages/openapi-parser/src/generators/index.ts +200 -0
- package/packages/openapi-parser/src/generators/nextjs-analyzer.ts +768 -0
- package/packages/openapi-parser/src/generators/openapi-builder.ts +527 -0
- package/packages/openapi-parser/src/generators/types.ts +298 -0
- package/packages/openapi-parser/src/graphql-parser.ts +462 -0
- package/packages/openapi-parser/src/grpc-parser.ts +649 -0
- package/packages/openapi-parser/src/har-parser.ts +723 -0
- package/packages/openapi-parser/src/index.ts +635 -0
- package/packages/openapi-parser/src/insomnia-parser.ts +614 -0
- package/packages/openapi-parser/src/parser.ts +231 -0
- package/packages/openapi-parser/src/postman-parser.ts +611 -0
- package/packages/openapi-parser/src/ref-resolver.ts +313 -0
- package/packages/openapi-parser/src/transformer.ts +459 -0
- package/packages/openapi-parser/tests/generators/express.test.ts +209 -0
- package/packages/openapi-parser/tests/generators/fastapi.test.ts +236 -0
- package/packages/openapi-parser/tests/generators/nextjs.test.ts +273 -0
- package/packages/openapi-parser/tests/parsers.test.ts +847 -0
- package/packages/openapi-parser/tsconfig.json +9 -0
- package/packages/openapi-parser/tsup.config.ts +11 -0
- package/packages/registry/package.json +59 -0
- package/packages/registry/src/cli.ts +456 -0
- package/packages/registry/src/index.ts +44 -0
- package/packages/registry/src/popular/github.json +47 -0
- package/packages/registry/src/popular/index.ts +55 -0
- package/packages/registry/src/popular/linear.json +42 -0
- package/packages/registry/src/popular/notion.json +42 -0
- package/packages/registry/src/popular/openai.json +40 -0
- package/packages/registry/src/popular/resend.json +38 -0
- package/packages/registry/src/popular/slack.json +42 -0
- package/packages/registry/src/popular/stripe.json +163 -0
- package/packages/registry/src/popular/supabase.json +42 -0
- package/packages/registry/src/popular/twilio.json +40 -0
- package/packages/registry/src/popular/vercel.json +40 -0
- package/packages/registry/src/registry.ts +492 -0
- package/packages/registry/src/storage.ts +334 -0
- package/packages/registry/src/types.ts +275 -0
- package/packages/registry/src/updater.ts +208 -0
- package/packages/registry/tsconfig.json +10 -0
- package/packages/registry/tsup.config.ts +11 -0
- package/pnpm-workspace.yaml +3 -0
- package/scripts/build-docs.sh +16 -0
- package/server.json +9 -0
- package/templates/Dockerfile.python.template +60 -0
- package/templates/Dockerfile.typescript.template +60 -0
- package/templates/docker-compose.template.yml +68 -0
- package/tests/fixtures/express-app/index.js +34 -0
- package/tests/fixtures/express-app/routes/posts.js +43 -0
- package/tests/fixtures/express-app/routes/users.js +58 -0
- package/tests/fixtures/fastapi-app/main.py +125 -0
- package/tests/fixtures/fastapi-app/routes/admin.py +42 -0
- package/tests/fixtures/graphql/simple-schema.graphql +65 -0
- package/tests/fixtures/mocks/github-api-responses.json +63 -0
- package/tests/fixtures/nextjs-app/app/api/posts/route.ts +55 -0
- package/tests/fixtures/nextjs-app/app/api/users/[id]/route.ts +63 -0
- package/tests/fixtures/nextjs-app/app/api/users/route.ts +44 -0
- package/tests/fixtures/nextjs-app/pages/api/health.ts +28 -0
- package/tests/fixtures/openapi/petstore.yaml +179 -0
- package/tests/integration/langchain-export.test.ts +405 -0
- package/tests/integration/openapi-conversion.test.ts +221 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +32 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground Connect API Route - Establish MCP server connection
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { McpSandbox } from '@/lib/mcp-sandbox';
|
|
9
|
+
|
|
10
|
+
interface ConnectRequestBody {
|
|
11
|
+
generatedCode: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ConnectResponse {
|
|
15
|
+
success: boolean;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
tools: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
inputSchema?: {
|
|
21
|
+
type: string;
|
|
22
|
+
properties?: Record<string, unknown>;
|
|
23
|
+
required?: string[];
|
|
24
|
+
};
|
|
25
|
+
}>;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function validateRequest(body: unknown): body is ConnectRequestBody {
|
|
30
|
+
if (!body || typeof body !== 'object') return false;
|
|
31
|
+
const req = body as Record<string, unknown>;
|
|
32
|
+
return typeof req.generatedCode === 'string' && req.generatedCode.trim().length > 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* POST /api/playground/connect
|
|
37
|
+
* Connect to an MCP server and return available tools
|
|
38
|
+
*/
|
|
39
|
+
export async function POST(request: NextRequest): Promise<NextResponse<ConnectResponse>> {
|
|
40
|
+
try {
|
|
41
|
+
const body = await request.json().catch(() => null);
|
|
42
|
+
|
|
43
|
+
if (!validateRequest(body)) {
|
|
44
|
+
return NextResponse.json(
|
|
45
|
+
{
|
|
46
|
+
success: false,
|
|
47
|
+
sessionId: '',
|
|
48
|
+
tools: [],
|
|
49
|
+
error: 'Invalid request body. Required: generatedCode (string)',
|
|
50
|
+
},
|
|
51
|
+
{ status: 400 }
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Basic security: Check code size (max 1MB)
|
|
56
|
+
if (body.generatedCode.length > 1024 * 1024) {
|
|
57
|
+
return NextResponse.json(
|
|
58
|
+
{
|
|
59
|
+
success: false,
|
|
60
|
+
sessionId: '',
|
|
61
|
+
tools: [],
|
|
62
|
+
error: 'Generated code exceeds maximum size limit (1MB)',
|
|
63
|
+
},
|
|
64
|
+
{ status: 400 }
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Basic security: Check for dangerous patterns
|
|
69
|
+
const dangerousPatterns = [
|
|
70
|
+
/require\s*\(\s*['"`]child_process['"`]\s*\)/i,
|
|
71
|
+
/import\s+.*from\s+['"`]child_process['"`]/i,
|
|
72
|
+
/execSync|spawnSync|exec\s*\(/i,
|
|
73
|
+
/fs\.rm|fs\.unlink|fs\.rmdir/i,
|
|
74
|
+
/process\.exit/i,
|
|
75
|
+
/eval\s*\(/i,
|
|
76
|
+
/Function\s*\(/i,
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
for (const pattern of dangerousPatterns) {
|
|
80
|
+
if (pattern.test(body.generatedCode)) {
|
|
81
|
+
return NextResponse.json(
|
|
82
|
+
{
|
|
83
|
+
success: false,
|
|
84
|
+
sessionId: '',
|
|
85
|
+
tools: [],
|
|
86
|
+
error: 'Generated code contains potentially dangerous patterns',
|
|
87
|
+
},
|
|
88
|
+
{ status: 400 }
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Create sandbox and connect
|
|
94
|
+
const sandbox = new McpSandbox();
|
|
95
|
+
const result = await sandbox.connect(body.generatedCode);
|
|
96
|
+
|
|
97
|
+
if (result.success) {
|
|
98
|
+
return NextResponse.json({
|
|
99
|
+
success: true,
|
|
100
|
+
sessionId: result.sessionId,
|
|
101
|
+
tools: result.tools || [],
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
return NextResponse.json(
|
|
105
|
+
{
|
|
106
|
+
success: false,
|
|
107
|
+
sessionId: '',
|
|
108
|
+
tools: [],
|
|
109
|
+
error: result.error || 'Failed to connect',
|
|
110
|
+
},
|
|
111
|
+
{ status: 422 }
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error('[Playground Connect] Error:', error);
|
|
116
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
117
|
+
|
|
118
|
+
return NextResponse.json(
|
|
119
|
+
{
|
|
120
|
+
success: false,
|
|
121
|
+
sessionId: '',
|
|
122
|
+
tools: [],
|
|
123
|
+
error: message,
|
|
124
|
+
},
|
|
125
|
+
{ status: 500 }
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* OPTIONS /api/playground/connect
|
|
132
|
+
* Handle CORS preflight
|
|
133
|
+
*/
|
|
134
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
135
|
+
return new NextResponse(null, {
|
|
136
|
+
status: 204,
|
|
137
|
+
headers: {
|
|
138
|
+
'Access-Control-Allow-Origin': '*',
|
|
139
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
140
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground Disconnect API Route - Close MCP server session
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { McpSandbox } from '@/lib/mcp-sandbox';
|
|
9
|
+
|
|
10
|
+
interface DisconnectRequestBody {
|
|
11
|
+
sessionId: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface DisconnectResponse {
|
|
15
|
+
success: boolean;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function validateRequest(body: unknown): body is DisconnectRequestBody {
|
|
20
|
+
if (!body || typeof body !== 'object') return false;
|
|
21
|
+
const req = body as Record<string, unknown>;
|
|
22
|
+
return typeof req.sessionId === 'string' && req.sessionId.trim().length > 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* POST /api/playground/disconnect
|
|
27
|
+
* Disconnect from an MCP server session
|
|
28
|
+
*/
|
|
29
|
+
export async function POST(request: NextRequest): Promise<NextResponse<DisconnectResponse>> {
|
|
30
|
+
try {
|
|
31
|
+
const body = await request.json().catch(() => null);
|
|
32
|
+
|
|
33
|
+
if (!validateRequest(body)) {
|
|
34
|
+
return NextResponse.json(
|
|
35
|
+
{
|
|
36
|
+
success: false,
|
|
37
|
+
message: 'Invalid request body. Required: sessionId (string)',
|
|
38
|
+
},
|
|
39
|
+
{ status: 400 }
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const deleted = McpSandbox.deleteSession(body.sessionId);
|
|
44
|
+
|
|
45
|
+
return NextResponse.json({
|
|
46
|
+
success: true,
|
|
47
|
+
message: deleted
|
|
48
|
+
? `Session ${body.sessionId} disconnected successfully`
|
|
49
|
+
: `Session ${body.sessionId} not found (may have already expired)`,
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('[Playground Disconnect] Error:', error);
|
|
53
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
54
|
+
|
|
55
|
+
return NextResponse.json(
|
|
56
|
+
{
|
|
57
|
+
success: false,
|
|
58
|
+
message,
|
|
59
|
+
},
|
|
60
|
+
{ status: 500 }
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* OPTIONS /api/playground/disconnect
|
|
67
|
+
* Handle CORS preflight
|
|
68
|
+
*/
|
|
69
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
70
|
+
return new NextResponse(null, {
|
|
71
|
+
status: 204,
|
|
72
|
+
headers: {
|
|
73
|
+
'Access-Control-Allow-Origin': '*',
|
|
74
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
75
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground Execute API Route - Execute tools in MCP sandbox
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { McpSandbox, ExecuteToolRequest, ExecuteToolResponse } from '@/lib/mcp-sandbox';
|
|
9
|
+
|
|
10
|
+
// Request body schema
|
|
11
|
+
interface ExecuteRequestBody {
|
|
12
|
+
generatedCode: string;
|
|
13
|
+
toolName: string;
|
|
14
|
+
toolParams: Record<string, unknown>;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Validate request body
|
|
19
|
+
function validateRequest(body: unknown): body is ExecuteRequestBody {
|
|
20
|
+
if (!body || typeof body !== 'object') return false;
|
|
21
|
+
|
|
22
|
+
const req = body as Record<string, unknown>;
|
|
23
|
+
|
|
24
|
+
if (typeof req.generatedCode !== 'string' || !req.generatedCode.trim()) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (typeof req.toolName !== 'string' || !req.toolName.trim()) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (typeof req.toolParams !== 'object' || req.toolParams === null) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (req.sessionId !== undefined && typeof req.sessionId !== 'string') {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* POST /api/playground/execute
|
|
45
|
+
* Execute a tool in the MCP sandbox
|
|
46
|
+
*/
|
|
47
|
+
export async function POST(request: NextRequest): Promise<NextResponse<ExecuteToolResponse | { error: string }>> {
|
|
48
|
+
try {
|
|
49
|
+
// Parse request body
|
|
50
|
+
const body = await request.json().catch(() => null);
|
|
51
|
+
|
|
52
|
+
if (!validateRequest(body)) {
|
|
53
|
+
return NextResponse.json(
|
|
54
|
+
{ error: 'Invalid request body. Required fields: generatedCode (string), toolName (string), toolParams (object)' },
|
|
55
|
+
{ status: 400 }
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Basic security: Check code size (max 1MB)
|
|
60
|
+
if (body.generatedCode.length > 1024 * 1024) {
|
|
61
|
+
return NextResponse.json(
|
|
62
|
+
{ error: 'Generated code exceeds maximum size limit (1MB)' },
|
|
63
|
+
{ status: 400 }
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Basic security: Check for obviously dangerous patterns
|
|
68
|
+
const dangerousPatterns = [
|
|
69
|
+
/require\s*\(\s*['"`]child_process['"`]\s*\)/i,
|
|
70
|
+
/import\s+.*from\s+['"`]child_process['"`]/i,
|
|
71
|
+
/execSync|spawnSync|exec\s*\(/i,
|
|
72
|
+
/fs\.rm|fs\.unlink|fs\.rmdir/i,
|
|
73
|
+
/process\.exit/i,
|
|
74
|
+
/eval\s*\(/i,
|
|
75
|
+
/Function\s*\(/i,
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
for (const pattern of dangerousPatterns) {
|
|
79
|
+
if (pattern.test(body.generatedCode)) {
|
|
80
|
+
return NextResponse.json(
|
|
81
|
+
{ error: 'Generated code contains potentially dangerous patterns' },
|
|
82
|
+
{ status: 400 }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Create sandbox and execute
|
|
88
|
+
const sandbox = new McpSandbox();
|
|
89
|
+
|
|
90
|
+
const executeRequest: ExecuteToolRequest = {
|
|
91
|
+
generatedCode: body.generatedCode,
|
|
92
|
+
toolName: body.toolName,
|
|
93
|
+
toolParams: body.toolParams,
|
|
94
|
+
sessionId: body.sessionId,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const result = await sandbox.executeTool(executeRequest);
|
|
98
|
+
|
|
99
|
+
// Return appropriate status code based on success
|
|
100
|
+
if (result.success) {
|
|
101
|
+
return NextResponse.json(result);
|
|
102
|
+
} else {
|
|
103
|
+
return NextResponse.json(result, { status: 422 });
|
|
104
|
+
}
|
|
105
|
+
} catch (error) {
|
|
106
|
+
console.error('[Playground Execute] Unexpected error:', error);
|
|
107
|
+
|
|
108
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
109
|
+
|
|
110
|
+
return NextResponse.json(
|
|
111
|
+
{
|
|
112
|
+
error: message,
|
|
113
|
+
success: false,
|
|
114
|
+
sessionId: '',
|
|
115
|
+
executionTime: 0,
|
|
116
|
+
} as ExecuteToolResponse,
|
|
117
|
+
{ status: 500 }
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* OPTIONS /api/playground/execute
|
|
124
|
+
* Handle CORS preflight
|
|
125
|
+
*/
|
|
126
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
127
|
+
return new NextResponse(null, {
|
|
128
|
+
status: 204,
|
|
129
|
+
headers: {
|
|
130
|
+
'Access-Control-Allow-Origin': '*',
|
|
131
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
132
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground Sessions API Route - Manage MCP sandbox sessions
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { McpSandbox } from '@/lib/mcp-sandbox';
|
|
9
|
+
|
|
10
|
+
// Response types
|
|
11
|
+
interface SessionInfo {
|
|
12
|
+
id: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
lastUsed: string;
|
|
15
|
+
initialized: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ListSessionsResponse {
|
|
19
|
+
sessions: SessionInfo[];
|
|
20
|
+
count: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface DeleteSessionResponse {
|
|
24
|
+
success: boolean;
|
|
25
|
+
message: string;
|
|
26
|
+
deletedCount?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* GET /api/playground/sessions
|
|
31
|
+
* List all active sessions
|
|
32
|
+
*/
|
|
33
|
+
export async function GET(): Promise<NextResponse<ListSessionsResponse>> {
|
|
34
|
+
const sessions = McpSandbox.getAllSessions();
|
|
35
|
+
|
|
36
|
+
return NextResponse.json({
|
|
37
|
+
sessions: sessions.map(session => ({
|
|
38
|
+
id: session.id,
|
|
39
|
+
createdAt: session.createdAt.toISOString(),
|
|
40
|
+
lastUsed: session.lastUsed.toISOString(),
|
|
41
|
+
initialized: session.initialized,
|
|
42
|
+
})),
|
|
43
|
+
count: sessions.length,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* DELETE /api/playground/sessions
|
|
49
|
+
* Delete one or all sessions
|
|
50
|
+
*
|
|
51
|
+
* Query params:
|
|
52
|
+
* - id: Session ID to delete (optional, if not provided deletes all)
|
|
53
|
+
*/
|
|
54
|
+
export async function DELETE(request: NextRequest): Promise<NextResponse<DeleteSessionResponse>> {
|
|
55
|
+
const { searchParams } = new URL(request.url);
|
|
56
|
+
const sessionId = searchParams.get('id');
|
|
57
|
+
|
|
58
|
+
if (sessionId) {
|
|
59
|
+
// Delete specific session
|
|
60
|
+
const deleted = McpSandbox.deleteSession(sessionId);
|
|
61
|
+
|
|
62
|
+
if (deleted) {
|
|
63
|
+
return NextResponse.json({
|
|
64
|
+
success: true,
|
|
65
|
+
message: `Session ${sessionId} deleted successfully`,
|
|
66
|
+
deletedCount: 1,
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
return NextResponse.json(
|
|
70
|
+
{
|
|
71
|
+
success: false,
|
|
72
|
+
message: `Session ${sessionId} not found`,
|
|
73
|
+
deletedCount: 0,
|
|
74
|
+
},
|
|
75
|
+
{ status: 404 }
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
// Delete all sessions
|
|
80
|
+
const count = McpSandbox.deleteAllSessions();
|
|
81
|
+
|
|
82
|
+
return NextResponse.json({
|
|
83
|
+
success: true,
|
|
84
|
+
message: `All sessions deleted successfully`,
|
|
85
|
+
deletedCount: count,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* OPTIONS /api/playground/sessions
|
|
92
|
+
* Handle CORS preflight
|
|
93
|
+
*/
|
|
94
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
95
|
+
return new NextResponse(null, {
|
|
96
|
+
status: 204,
|
|
97
|
+
headers: {
|
|
98
|
+
'Access-Control-Allow-Origin': '*',
|
|
99
|
+
'Access-Control-Allow-Methods': 'GET, DELETE, OPTIONS',
|
|
100
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playground Tools API Route - List available tools from MCP server
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
8
|
+
import { McpSandbox, ListToolsResponse } from '@/lib/mcp-sandbox';
|
|
9
|
+
|
|
10
|
+
// Request body schema
|
|
11
|
+
interface ListToolsRequestBody {
|
|
12
|
+
generatedCode: string;
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Validate request body
|
|
17
|
+
function validateRequest(body: unknown): body is ListToolsRequestBody {
|
|
18
|
+
if (!body || typeof body !== 'object') return false;
|
|
19
|
+
|
|
20
|
+
const req = body as Record<string, unknown>;
|
|
21
|
+
|
|
22
|
+
if (typeof req.generatedCode !== 'string' || !req.generatedCode.trim()) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (req.sessionId !== undefined && typeof req.sessionId !== 'string') {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* POST /api/playground/tools
|
|
35
|
+
* List available tools from the MCP server
|
|
36
|
+
*/
|
|
37
|
+
export async function POST(request: NextRequest): Promise<NextResponse<ListToolsResponse | { error: string }>> {
|
|
38
|
+
try {
|
|
39
|
+
// Parse request body
|
|
40
|
+
const body = await request.json().catch(() => null);
|
|
41
|
+
|
|
42
|
+
if (!validateRequest(body)) {
|
|
43
|
+
return NextResponse.json(
|
|
44
|
+
{ error: 'Invalid request body. Required field: generatedCode (string)' },
|
|
45
|
+
{ status: 400 }
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Basic security: Check code size (max 1MB)
|
|
50
|
+
if (body.generatedCode.length > 1024 * 1024) {
|
|
51
|
+
return NextResponse.json(
|
|
52
|
+
{ error: 'Generated code exceeds maximum size limit (1MB)' },
|
|
53
|
+
{ status: 400 }
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Basic security: Check for obviously dangerous patterns
|
|
58
|
+
const dangerousPatterns = [
|
|
59
|
+
/require\s*\(\s*['"`]child_process['"`]\s*\)/i,
|
|
60
|
+
/import\s+.*from\s+['"`]child_process['"`]/i,
|
|
61
|
+
/execSync|spawnSync|exec\s*\(/i,
|
|
62
|
+
/fs\.rm|fs\.unlink|fs\.rmdir/i,
|
|
63
|
+
/process\.exit/i,
|
|
64
|
+
/eval\s*\(/i,
|
|
65
|
+
/Function\s*\(/i,
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
for (const pattern of dangerousPatterns) {
|
|
69
|
+
if (pattern.test(body.generatedCode)) {
|
|
70
|
+
return NextResponse.json(
|
|
71
|
+
{ error: 'Generated code contains potentially dangerous patterns' },
|
|
72
|
+
{ status: 400 }
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Create sandbox and list tools
|
|
78
|
+
const sandbox = new McpSandbox();
|
|
79
|
+
|
|
80
|
+
const result = await sandbox.listTools(body.generatedCode, body.sessionId);
|
|
81
|
+
|
|
82
|
+
// Return appropriate status code based on success
|
|
83
|
+
if (result.success) {
|
|
84
|
+
return NextResponse.json(result);
|
|
85
|
+
} else {
|
|
86
|
+
return NextResponse.json(result, { status: 422 });
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('[Playground Tools] Unexpected error:', error);
|
|
90
|
+
|
|
91
|
+
const message = error instanceof Error ? error.message : 'Internal server error';
|
|
92
|
+
|
|
93
|
+
return NextResponse.json(
|
|
94
|
+
{
|
|
95
|
+
error: message,
|
|
96
|
+
success: false,
|
|
97
|
+
sessionId: '',
|
|
98
|
+
} as ListToolsResponse,
|
|
99
|
+
{ status: 500 }
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* OPTIONS /api/playground/tools
|
|
106
|
+
* Handle CORS preflight
|
|
107
|
+
*/
|
|
108
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
109
|
+
return new NextResponse(null, {
|
|
110
|
+
status: 204,
|
|
111
|
+
headers: {
|
|
112
|
+
'Access-Control-Allow-Origin': '*',
|
|
113
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
114
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connect API Route
|
|
3
|
+
*
|
|
4
|
+
* POST /api/playground/v2/connect
|
|
5
|
+
* Establishes a connection to an MCP server using the specified transport.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
9
|
+
import {
|
|
10
|
+
handleApiError,
|
|
11
|
+
createSuccessResponse,
|
|
12
|
+
McpConnectionError,
|
|
13
|
+
validateConnectRequest,
|
|
14
|
+
applyMiddleware,
|
|
15
|
+
corsPreflightResponse,
|
|
16
|
+
createLogContext,
|
|
17
|
+
SessionManager,
|
|
18
|
+
withRequestId,
|
|
19
|
+
} from '@/lib/api';
|
|
20
|
+
import type { ConnectResponseData } from '@/lib/api';
|
|
21
|
+
|
|
22
|
+
const PATH = '/api/playground/v2/connect';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Handle CORS preflight request
|
|
26
|
+
*/
|
|
27
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
28
|
+
return corsPreflightResponse({ methods: ['POST', 'OPTIONS'] });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* POST /api/playground/v2/connect
|
|
33
|
+
*
|
|
34
|
+
* Establishes a connection to an MCP server.
|
|
35
|
+
*
|
|
36
|
+
* Request body:
|
|
37
|
+
* - transport: TransportConfig (required) - The transport configuration
|
|
38
|
+
* - generatedCode: string (optional) - Generated code to run as stdio server
|
|
39
|
+
*
|
|
40
|
+
* Response:
|
|
41
|
+
* - success: boolean
|
|
42
|
+
* - data: { sessionId, capabilities, serverInfo, tools }
|
|
43
|
+
*/
|
|
44
|
+
export async function POST(request: NextRequest): Promise<NextResponse> {
|
|
45
|
+
// Apply middleware (rate limiting, etc.)
|
|
46
|
+
const middleware = await applyMiddleware(request);
|
|
47
|
+
if ('response' in middleware) {
|
|
48
|
+
return middleware.response;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { context } = middleware;
|
|
52
|
+
const log = createLogContext('POST', PATH, context.requestId, context.clientId);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// Parse and validate request body
|
|
56
|
+
const body = await request.json();
|
|
57
|
+
const { transport, generatedCode } = validateConnectRequest(body);
|
|
58
|
+
|
|
59
|
+
// Create session with MCP server
|
|
60
|
+
const sessionManager = SessionManager.getInstance();
|
|
61
|
+
|
|
62
|
+
let session;
|
|
63
|
+
try {
|
|
64
|
+
session = await sessionManager.createSession(transport, generatedCode);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
throw new McpConnectionError(
|
|
67
|
+
`Failed to connect to MCP server: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
68
|
+
{
|
|
69
|
+
transportType: transport.type,
|
|
70
|
+
cause: error instanceof Error ? error.message : undefined,
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const responseData: ConnectResponseData = {
|
|
76
|
+
sessionId: session.id,
|
|
77
|
+
capabilities: session.capabilities,
|
|
78
|
+
serverInfo: session.serverInfo,
|
|
79
|
+
tools: session.tools,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
log.log(200, session.id);
|
|
83
|
+
|
|
84
|
+
return createSuccessResponse(responseData, 200, {
|
|
85
|
+
...context.rateLimitHeaders,
|
|
86
|
+
...withRequestId({}, context.requestId),
|
|
87
|
+
'Access-Control-Allow-Origin': '*',
|
|
88
|
+
});
|
|
89
|
+
} catch (error) {
|
|
90
|
+
const status = error instanceof Error && 'statusCode' in error
|
|
91
|
+
? (error as { statusCode: number }).statusCode
|
|
92
|
+
: 500;
|
|
93
|
+
log.log(status, undefined, error instanceof Error ? error.message : 'Unknown error');
|
|
94
|
+
return handleApiError(error);
|
|
95
|
+
}
|
|
96
|
+
}
|