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,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tools API Route
|
|
3
|
+
*
|
|
4
|
+
* GET /api/playground/v2/tools - List all tools
|
|
5
|
+
* POST /api/playground/v2/tools - Execute a tool
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
9
|
+
import {
|
|
10
|
+
handleApiError,
|
|
11
|
+
createSuccessResponse,
|
|
12
|
+
SessionExpiredError,
|
|
13
|
+
McpExecutionError,
|
|
14
|
+
NotFoundError,
|
|
15
|
+
validateToolCall,
|
|
16
|
+
validateSessionIdFromQuery,
|
|
17
|
+
applyMiddleware,
|
|
18
|
+
corsPreflightResponse,
|
|
19
|
+
createLogContext,
|
|
20
|
+
SessionManager,
|
|
21
|
+
withRequestId,
|
|
22
|
+
RELAXED_RATE_LIMIT,
|
|
23
|
+
} from '@/lib/api';
|
|
24
|
+
import type { ToolsListResponseData, ToolCallResponseData } from '@/lib/api';
|
|
25
|
+
|
|
26
|
+
const PATH = '/api/playground/v2/tools';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Handle CORS preflight request
|
|
30
|
+
*/
|
|
31
|
+
export async function OPTIONS(): Promise<NextResponse> {
|
|
32
|
+
return corsPreflightResponse({ methods: ['GET', 'POST', 'OPTIONS'] });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* GET /api/playground/v2/tools
|
|
37
|
+
*
|
|
38
|
+
* Lists all available tools for a session.
|
|
39
|
+
*
|
|
40
|
+
* Query parameters:
|
|
41
|
+
* - sessionId: string (required) - The session ID
|
|
42
|
+
*
|
|
43
|
+
* Response:
|
|
44
|
+
* - success: boolean
|
|
45
|
+
* - data: { tools: McpTool[] }
|
|
46
|
+
*/
|
|
47
|
+
export async function GET(request: NextRequest): Promise<NextResponse> {
|
|
48
|
+
const middleware = await applyMiddleware(request, { rateLimit: RELAXED_RATE_LIMIT });
|
|
49
|
+
if ('response' in middleware) {
|
|
50
|
+
return middleware.response;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const { context } = middleware;
|
|
54
|
+
const log = createLogContext('GET', PATH, context.requestId, context.clientId);
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const { searchParams } = new URL(request.url);
|
|
58
|
+
const sessionId = validateSessionIdFromQuery(searchParams);
|
|
59
|
+
|
|
60
|
+
const sessionManager = SessionManager.getInstance();
|
|
61
|
+
|
|
62
|
+
const session = await sessionManager.getSession(sessionId);
|
|
63
|
+
if (!session) {
|
|
64
|
+
throw new SessionExpiredError(
|
|
65
|
+
`Session not found or expired: ${sessionId}`,
|
|
66
|
+
sessionId
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const tools = await sessionManager.listTools(sessionId);
|
|
71
|
+
|
|
72
|
+
const responseData: ToolsListResponseData = { tools };
|
|
73
|
+
|
|
74
|
+
log.log(200, sessionId);
|
|
75
|
+
|
|
76
|
+
return createSuccessResponse(responseData, 200, {
|
|
77
|
+
...context.rateLimitHeaders,
|
|
78
|
+
...withRequestId({}, context.requestId),
|
|
79
|
+
'Access-Control-Allow-Origin': '*',
|
|
80
|
+
});
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const status = error instanceof Error && 'statusCode' in error
|
|
83
|
+
? (error as { statusCode: number }).statusCode
|
|
84
|
+
: 500;
|
|
85
|
+
log.log(status, undefined, error instanceof Error ? error.message : 'Unknown error');
|
|
86
|
+
return handleApiError(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* POST /api/playground/v2/tools
|
|
92
|
+
*
|
|
93
|
+
* Executes a tool.
|
|
94
|
+
*
|
|
95
|
+
* Request body:
|
|
96
|
+
* - sessionId: string (required) - The session ID
|
|
97
|
+
* - toolName: string (required) - Name of the tool to execute
|
|
98
|
+
* - params: object (optional) - Tool parameters
|
|
99
|
+
*
|
|
100
|
+
* Response:
|
|
101
|
+
* - success: boolean
|
|
102
|
+
* - data: { result: McpToolResult, executionTime: number, logs: string[] }
|
|
103
|
+
*/
|
|
104
|
+
export async function POST(request: NextRequest): Promise<NextResponse> {
|
|
105
|
+
const middleware = await applyMiddleware(request, { rateLimit: RELAXED_RATE_LIMIT });
|
|
106
|
+
if ('response' in middleware) {
|
|
107
|
+
return middleware.response;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const { context } = middleware;
|
|
111
|
+
const log = createLogContext('POST', PATH, context.requestId, context.clientId);
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
const body = await request.json();
|
|
115
|
+
const { sessionId, toolName, params } = validateToolCall(body);
|
|
116
|
+
|
|
117
|
+
const sessionManager = SessionManager.getInstance();
|
|
118
|
+
|
|
119
|
+
const session = await sessionManager.getSession(sessionId);
|
|
120
|
+
if (!session) {
|
|
121
|
+
throw new SessionExpiredError(
|
|
122
|
+
`Session not found or expired: ${sessionId}`,
|
|
123
|
+
sessionId
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const executionStart = Date.now();
|
|
128
|
+
let result;
|
|
129
|
+
let logs: string[];
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const execution = await sessionManager.executeTool(sessionId, toolName, params);
|
|
133
|
+
result = execution.result;
|
|
134
|
+
logs = execution.logs;
|
|
135
|
+
} catch (error) {
|
|
136
|
+
if (error instanceof Error && error.message.includes('not found')) {
|
|
137
|
+
throw new NotFoundError(`Tool not found: ${toolName}`, 'tool');
|
|
138
|
+
}
|
|
139
|
+
throw new McpExecutionError(
|
|
140
|
+
`Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
141
|
+
{ executionType: 'tool', name: toolName }
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const executionTime = Date.now() - executionStart;
|
|
146
|
+
|
|
147
|
+
const responseData: ToolCallResponseData = {
|
|
148
|
+
result,
|
|
149
|
+
executionTime,
|
|
150
|
+
logs,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
log.log(200, sessionId, undefined, { toolName, executionTime });
|
|
154
|
+
|
|
155
|
+
return createSuccessResponse(responseData, 200, {
|
|
156
|
+
...context.rateLimitHeaders,
|
|
157
|
+
...withRequestId({}, context.requestId),
|
|
158
|
+
'Access-Control-Allow-Origin': '*',
|
|
159
|
+
});
|
|
160
|
+
} catch (error) {
|
|
161
|
+
const status = error instanceof Error && 'statusCode' in error
|
|
162
|
+
? (error as { statusCode: number }).statusCode
|
|
163
|
+
: 500;
|
|
164
|
+
log.log(status, undefined, error instanceof Error ? error.message : 'Unknown error');
|
|
165
|
+
return handleApiError(error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SSE endpoint for streaming generation progress
|
|
3
|
+
* GET /api/stream - Server-Sent Events endpoint
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { NextRequest } from 'next/server';
|
|
7
|
+
import { generateFromGithub } from '@nirholas/github-to-mcp';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Progress event structure
|
|
11
|
+
*/
|
|
12
|
+
interface ProgressEvent {
|
|
13
|
+
type: 'start' | 'analyzing' | 'extracting' | 'generating' | 'validating' | 'complete' | 'error';
|
|
14
|
+
message: string;
|
|
15
|
+
progress: number;
|
|
16
|
+
details?: {
|
|
17
|
+
step?: string;
|
|
18
|
+
filesProcessed?: number;
|
|
19
|
+
totalFiles?: number;
|
|
20
|
+
toolsFound?: number;
|
|
21
|
+
currentSource?: string;
|
|
22
|
+
};
|
|
23
|
+
timestamp: number;
|
|
24
|
+
data?: unknown;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Create a Server-Sent Events response
|
|
29
|
+
*/
|
|
30
|
+
function createSSEResponse(stream: ReadableStream): Response {
|
|
31
|
+
return new Response(stream, {
|
|
32
|
+
headers: {
|
|
33
|
+
'Content-Type': 'text/event-stream',
|
|
34
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
35
|
+
'Connection': 'keep-alive',
|
|
36
|
+
'X-Accel-Buffering': 'no',
|
|
37
|
+
'Access-Control-Allow-Origin': '*',
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Send an SSE event
|
|
44
|
+
*/
|
|
45
|
+
function formatSSEEvent(event: ProgressEvent): string {
|
|
46
|
+
return `data: ${JSON.stringify(event)}\n\n`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function GET(request: NextRequest): Promise<Response> {
|
|
50
|
+
const searchParams = request.nextUrl.searchParams;
|
|
51
|
+
const url = searchParams.get('url');
|
|
52
|
+
const language = (searchParams.get('language') || 'typescript') as 'typescript' | 'python';
|
|
53
|
+
const sourcesParam = searchParams.get('sources');
|
|
54
|
+
const sources = sourcesParam ? sourcesParam.split(',') : ['readme', 'openapi', 'code'];
|
|
55
|
+
|
|
56
|
+
if (!url) {
|
|
57
|
+
const errorStream = new ReadableStream({
|
|
58
|
+
start(controller) {
|
|
59
|
+
const encoder = new TextEncoder();
|
|
60
|
+
const event: ProgressEvent = {
|
|
61
|
+
type: 'error',
|
|
62
|
+
message: 'GitHub URL is required',
|
|
63
|
+
progress: 0,
|
|
64
|
+
timestamp: Date.now(),
|
|
65
|
+
};
|
|
66
|
+
controller.enqueue(encoder.encode(formatSSEEvent(event)));
|
|
67
|
+
controller.close();
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
return createSSEResponse(errorStream);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Validate GitHub URL
|
|
74
|
+
const githubPattern = /^https?:\/\/(www\.)?github\.com\/[\w-]+\/[\w.-]+/;
|
|
75
|
+
if (!githubPattern.test(url)) {
|
|
76
|
+
const errorStream = new ReadableStream({
|
|
77
|
+
start(controller) {
|
|
78
|
+
const encoder = new TextEncoder();
|
|
79
|
+
const event: ProgressEvent = {
|
|
80
|
+
type: 'error',
|
|
81
|
+
message: 'Invalid GitHub URL format',
|
|
82
|
+
progress: 0,
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
};
|
|
85
|
+
controller.enqueue(encoder.encode(formatSSEEvent(event)));
|
|
86
|
+
controller.close();
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
return createSSEResponse(errorStream);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const encoder = new TextEncoder();
|
|
93
|
+
|
|
94
|
+
const stream = new ReadableStream({
|
|
95
|
+
async start(controller) {
|
|
96
|
+
const emit = (event: ProgressEvent) => {
|
|
97
|
+
try {
|
|
98
|
+
controller.enqueue(encoder.encode(formatSSEEvent(event)));
|
|
99
|
+
} catch {
|
|
100
|
+
// Stream may be closed
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
// Start event
|
|
106
|
+
emit({
|
|
107
|
+
type: 'start',
|
|
108
|
+
message: 'Starting conversion...',
|
|
109
|
+
progress: 0,
|
|
110
|
+
timestamp: Date.now(),
|
|
111
|
+
details: { step: 'initialization' },
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Analyzing event
|
|
115
|
+
emit({
|
|
116
|
+
type: 'analyzing',
|
|
117
|
+
message: 'Analyzing repository structure...',
|
|
118
|
+
progress: 10,
|
|
119
|
+
timestamp: Date.now(),
|
|
120
|
+
details: { step: 'analysis' },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Generate MCP tools
|
|
124
|
+
const result = await generateFromGithub(url, {
|
|
125
|
+
sources: sources as ('readme' | 'openapi' | 'code' | 'graphql')[],
|
|
126
|
+
githubToken: process.env.GITHUB_TOKEN,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Extracting event
|
|
130
|
+
emit({
|
|
131
|
+
type: 'extracting',
|
|
132
|
+
message: `Extracting tools from ${result.sources.length} sources...`,
|
|
133
|
+
progress: 40,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
details: {
|
|
136
|
+
step: 'extraction',
|
|
137
|
+
toolsFound: result.tools.length,
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Generating event
|
|
142
|
+
emit({
|
|
143
|
+
type: 'generating',
|
|
144
|
+
message: 'Generating MCP server code...',
|
|
145
|
+
progress: 70,
|
|
146
|
+
timestamp: Date.now(),
|
|
147
|
+
details: {
|
|
148
|
+
step: 'generation',
|
|
149
|
+
toolsFound: result.tools.length,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Generate code
|
|
154
|
+
const code = language === 'python' ? result.generatePython() : result.generate();
|
|
155
|
+
|
|
156
|
+
// Generate config snippets
|
|
157
|
+
const repoName = result.name;
|
|
158
|
+
|
|
159
|
+
const claudeConfig = {
|
|
160
|
+
mcpServers: {
|
|
161
|
+
[repoName]: {
|
|
162
|
+
command: language === 'python' ? 'python' : 'npx',
|
|
163
|
+
args: language === 'python'
|
|
164
|
+
? ['-m', `${repoName.replace(/-/g, '_')}_mcp`]
|
|
165
|
+
: ['tsx', `${repoName}-mcp/index.ts`],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Validating event
|
|
171
|
+
emit({
|
|
172
|
+
type: 'validating',
|
|
173
|
+
message: 'Validating generated code...',
|
|
174
|
+
progress: 90,
|
|
175
|
+
timestamp: Date.now(),
|
|
176
|
+
details: { step: 'validation' },
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Complete event with data
|
|
180
|
+
emit({
|
|
181
|
+
type: 'complete',
|
|
182
|
+
message: 'Conversion complete!',
|
|
183
|
+
progress: 100,
|
|
184
|
+
timestamp: Date.now(),
|
|
185
|
+
details: {
|
|
186
|
+
toolsFound: result.tools.length,
|
|
187
|
+
},
|
|
188
|
+
data: {
|
|
189
|
+
name: result.name,
|
|
190
|
+
tools: result.tools.map(t => ({
|
|
191
|
+
name: t.name,
|
|
192
|
+
description: t.description,
|
|
193
|
+
inputSchema: t.inputSchema,
|
|
194
|
+
source: t.source,
|
|
195
|
+
})),
|
|
196
|
+
sources: result.sources,
|
|
197
|
+
classification: result.classification,
|
|
198
|
+
code,
|
|
199
|
+
claudeConfig: JSON.stringify(claudeConfig, null, 2),
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
controller.close();
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const message = error instanceof Error ? error.message : 'Conversion failed';
|
|
206
|
+
|
|
207
|
+
emit({
|
|
208
|
+
type: 'error',
|
|
209
|
+
message,
|
|
210
|
+
progress: 0,
|
|
211
|
+
timestamp: Date.now(),
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
controller.close();
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
return createSSEResponse(stream);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Support OPTIONS for CORS preflight
|
|
223
|
+
export async function OPTIONS(): Promise<Response> {
|
|
224
|
+
return new Response(null, {
|
|
225
|
+
status: 204,
|
|
226
|
+
headers: {
|
|
227
|
+
'Access-Control-Allow-Origin': '*',
|
|
228
|
+
'Access-Control-Allow-Methods': 'GET, OPTIONS',
|
|
229
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch Convert Client Component
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { useState, useCallback } from 'react';
|
|
10
|
+
import Link from 'next/link';
|
|
11
|
+
import { motion } from 'framer-motion';
|
|
12
|
+
import {
|
|
13
|
+
ArrowLeft,
|
|
14
|
+
Archive,
|
|
15
|
+
Download,
|
|
16
|
+
Settings,
|
|
17
|
+
Info,
|
|
18
|
+
Zap,
|
|
19
|
+
} from 'lucide-react';
|
|
20
|
+
import { BatchConvert } from '@/components/batch';
|
|
21
|
+
import type { ConversionResult } from '@/types';
|
|
22
|
+
|
|
23
|
+
export default function BatchConvertClient() {
|
|
24
|
+
const [completedResults, setCompletedResults] = useState<Array<{
|
|
25
|
+
url: string;
|
|
26
|
+
result?: ConversionResult;
|
|
27
|
+
error?: string;
|
|
28
|
+
}>>([]);
|
|
29
|
+
const [showSettings, setShowSettings] = useState(false);
|
|
30
|
+
const [maxConcurrent, setMaxConcurrent] = useState(3);
|
|
31
|
+
|
|
32
|
+
const handleBatchComplete = useCallback((results: typeof completedResults) => {
|
|
33
|
+
setCompletedResults(results);
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<main className="min-h-screen bg-black text-white">
|
|
38
|
+
{/* Background gradient */}
|
|
39
|
+
<div className="fixed inset-0 bg-gradient-to-br from-purple-500/5 via-black to-blue-500/5 pointer-events-none" />
|
|
40
|
+
|
|
41
|
+
{/* Content */}
|
|
42
|
+
<div className="relative z-10 max-w-5xl mx-auto px-4 py-8">
|
|
43
|
+
{/* Navigation */}
|
|
44
|
+
<motion.div
|
|
45
|
+
initial={{ opacity: 0, y: -20 }}
|
|
46
|
+
animate={{ opacity: 1, y: 0 }}
|
|
47
|
+
className="flex items-center justify-between mb-8"
|
|
48
|
+
>
|
|
49
|
+
<Link
|
|
50
|
+
href="/"
|
|
51
|
+
className="flex items-center gap-2 text-neutral-400 hover:text-white transition-colors"
|
|
52
|
+
>
|
|
53
|
+
<ArrowLeft className="w-5 h-5" />
|
|
54
|
+
Back to home
|
|
55
|
+
</Link>
|
|
56
|
+
|
|
57
|
+
<div className="flex items-center gap-2">
|
|
58
|
+
<button
|
|
59
|
+
onClick={() => setShowSettings(!showSettings)}
|
|
60
|
+
className={`p-2 rounded-lg transition-colors ${
|
|
61
|
+
showSettings ? 'bg-white text-black' : 'bg-white/10 text-white hover:bg-white/20'
|
|
62
|
+
}`}
|
|
63
|
+
title="Settings"
|
|
64
|
+
>
|
|
65
|
+
<Settings className="w-5 h-5" />
|
|
66
|
+
</button>
|
|
67
|
+
</div>
|
|
68
|
+
</motion.div>
|
|
69
|
+
|
|
70
|
+
{/* Page header */}
|
|
71
|
+
<motion.div
|
|
72
|
+
initial={{ opacity: 0, y: 20 }}
|
|
73
|
+
animate={{ opacity: 1, y: 0 }}
|
|
74
|
+
transition={{ delay: 0.1 }}
|
|
75
|
+
className="text-center mb-8"
|
|
76
|
+
>
|
|
77
|
+
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-purple-500/10 border border-purple-500/20 text-purple-400 text-sm mb-4">
|
|
78
|
+
<Zap className="w-4 h-4" />
|
|
79
|
+
Parallel Processing
|
|
80
|
+
</div>
|
|
81
|
+
<h1 className="text-4xl md:text-5xl font-bold mb-4">
|
|
82
|
+
Batch Convert
|
|
83
|
+
</h1>
|
|
84
|
+
<p className="text-xl text-neutral-400 max-w-2xl mx-auto">
|
|
85
|
+
Convert multiple GitHub repositories to MCP servers simultaneously.
|
|
86
|
+
Perfect for setting up tool suites or migrating multiple projects.
|
|
87
|
+
</p>
|
|
88
|
+
</motion.div>
|
|
89
|
+
|
|
90
|
+
{/* Settings panel */}
|
|
91
|
+
{showSettings && (
|
|
92
|
+
<motion.div
|
|
93
|
+
initial={{ opacity: 0, height: 0 }}
|
|
94
|
+
animate={{ opacity: 1, height: 'auto' }}
|
|
95
|
+
exit={{ opacity: 0, height: 0 }}
|
|
96
|
+
className="mb-6 rounded-xl border border-neutral-800 bg-neutral-900/50 p-4"
|
|
97
|
+
>
|
|
98
|
+
<h3 className="text-sm font-medium text-white mb-3 flex items-center gap-2">
|
|
99
|
+
<Settings className="w-4 h-4" />
|
|
100
|
+
Conversion Settings
|
|
101
|
+
</h3>
|
|
102
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
103
|
+
<div>
|
|
104
|
+
<label className="block text-sm text-neutral-400 mb-2">
|
|
105
|
+
Max Concurrent Conversions
|
|
106
|
+
</label>
|
|
107
|
+
<select
|
|
108
|
+
value={maxConcurrent}
|
|
109
|
+
onChange={(e) => setMaxConcurrent(Number(e.target.value))}
|
|
110
|
+
className="w-full p-2 bg-black border border-neutral-700 rounded-lg text-white focus:outline-none focus:border-white/50"
|
|
111
|
+
>
|
|
112
|
+
<option value={1}>1 (Sequential)</option>
|
|
113
|
+
<option value={2}>2</option>
|
|
114
|
+
<option value={3}>3 (Recommended)</option>
|
|
115
|
+
<option value={5}>5</option>
|
|
116
|
+
<option value={10}>10 (High Load)</option>
|
|
117
|
+
</select>
|
|
118
|
+
</div>
|
|
119
|
+
<div className="flex items-end">
|
|
120
|
+
<div className="flex items-start gap-2 p-3 rounded-lg bg-blue-500/10 border border-blue-500/20 text-sm">
|
|
121
|
+
<Info className="w-4 h-4 text-blue-400 flex-shrink-0 mt-0.5" />
|
|
122
|
+
<p className="text-blue-200">
|
|
123
|
+
Higher concurrency is faster but may hit rate limits
|
|
124
|
+
</p>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</motion.div>
|
|
129
|
+
)}
|
|
130
|
+
|
|
131
|
+
{/* Main batch convert component */}
|
|
132
|
+
<BatchConvert
|
|
133
|
+
onBatchComplete={handleBatchComplete}
|
|
134
|
+
maxConcurrent={maxConcurrent}
|
|
135
|
+
/>
|
|
136
|
+
|
|
137
|
+
{/* Features */}
|
|
138
|
+
<motion.div
|
|
139
|
+
initial={{ opacity: 0, y: 20 }}
|
|
140
|
+
animate={{ opacity: 1, y: 0 }}
|
|
141
|
+
transition={{ delay: 0.4 }}
|
|
142
|
+
className="mt-12 grid grid-cols-1 md:grid-cols-3 gap-6"
|
|
143
|
+
>
|
|
144
|
+
{[
|
|
145
|
+
{
|
|
146
|
+
icon: Archive,
|
|
147
|
+
title: 'Bulk Import',
|
|
148
|
+
description: 'Import URLs from file, paste multiple, or drag and drop',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
icon: Zap,
|
|
152
|
+
title: 'Parallel Processing',
|
|
153
|
+
description: 'Convert multiple repos simultaneously for speed',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
icon: Download,
|
|
157
|
+
title: 'Combined Export',
|
|
158
|
+
description: 'Download all results as a single JSON file',
|
|
159
|
+
},
|
|
160
|
+
].map((feature, index) => (
|
|
161
|
+
<div
|
|
162
|
+
key={index}
|
|
163
|
+
className="p-4 rounded-xl border border-neutral-800 bg-neutral-900/30"
|
|
164
|
+
>
|
|
165
|
+
<feature.icon className="w-8 h-8 text-white/80 mb-3" />
|
|
166
|
+
<h3 className="font-medium text-white mb-1">{feature.title}</h3>
|
|
167
|
+
<p className="text-sm text-neutral-500">{feature.description}</p>
|
|
168
|
+
</div>
|
|
169
|
+
))}
|
|
170
|
+
</motion.div>
|
|
171
|
+
|
|
172
|
+
{/* Tips */}
|
|
173
|
+
<motion.div
|
|
174
|
+
initial={{ opacity: 0 }}
|
|
175
|
+
animate={{ opacity: 1 }}
|
|
176
|
+
transition={{ delay: 0.5 }}
|
|
177
|
+
className="mt-8 p-4 rounded-xl border border-neutral-800 bg-neutral-900/30"
|
|
178
|
+
>
|
|
179
|
+
<h3 className="text-sm font-medium text-white mb-2">Pro Tips</h3>
|
|
180
|
+
<ul className="text-sm text-neutral-500 space-y-1">
|
|
181
|
+
<li>• Drag to reorder URLs - they'll be processed in order</li>
|
|
182
|
+
<li>• Use Import URLs to paste a list from a text file</li>
|
|
183
|
+
<li>• Failed conversions can be retried without re-adding URLs</li>
|
|
184
|
+
<li>• Results are preserved even if you navigate away</li>
|
|
185
|
+
</ul>
|
|
186
|
+
</motion.div>
|
|
187
|
+
</div>
|
|
188
|
+
</main>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch Convert Page - Convert multiple repositories to MCP servers
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Suspense } from 'react';
|
|
8
|
+
import { Metadata } from 'next';
|
|
9
|
+
import BatchConvertClient from './BatchConvertClient';
|
|
10
|
+
|
|
11
|
+
export const metadata: Metadata = {
|
|
12
|
+
title: 'Batch Convert | GitHub to MCP',
|
|
13
|
+
description: 'Convert multiple GitHub repositories to MCP servers simultaneously',
|
|
14
|
+
openGraph: {
|
|
15
|
+
title: 'Batch Convert | GitHub to MCP',
|
|
16
|
+
description: 'Convert multiple GitHub repositories to MCP servers simultaneously',
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default function BatchConvertPage() {
|
|
21
|
+
return (
|
|
22
|
+
<Suspense fallback={<BatchConvertLoading />}>
|
|
23
|
+
<BatchConvertClient />
|
|
24
|
+
</Suspense>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function BatchConvertLoading() {
|
|
29
|
+
return (
|
|
30
|
+
<div className="min-h-screen bg-black flex items-center justify-center">
|
|
31
|
+
<div className="text-center">
|
|
32
|
+
<div className="w-16 h-16 border-4 border-white/20 border-t-white rounded-full animate-spin mx-auto mb-4" />
|
|
33
|
+
<p className="text-neutral-400">Loading batch converter...</p>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|