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,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides validation functions for playground API routes.
|
|
5
|
+
* All validators throw ValidationError with descriptive messages.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ValidationError } from './errors';
|
|
9
|
+
|
|
10
|
+
// Transport configuration types
|
|
11
|
+
export type TransportType = 'stdio' | 'sse' | 'http';
|
|
12
|
+
|
|
13
|
+
export interface StdioTransportConfig {
|
|
14
|
+
type: 'stdio';
|
|
15
|
+
command: string;
|
|
16
|
+
args?: string[];
|
|
17
|
+
env?: Record<string, string>;
|
|
18
|
+
cwd?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SseTransportConfig {
|
|
22
|
+
type: 'sse';
|
|
23
|
+
url: string;
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface HttpTransportConfig {
|
|
28
|
+
type: 'http';
|
|
29
|
+
url: string;
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type TransportConfig =
|
|
34
|
+
| StdioTransportConfig
|
|
35
|
+
| SseTransportConfig
|
|
36
|
+
| HttpTransportConfig;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Validates and returns a typed transport configuration
|
|
40
|
+
*/
|
|
41
|
+
export function validateTransportConfig(body: unknown): TransportConfig {
|
|
42
|
+
if (!body || typeof body !== 'object') {
|
|
43
|
+
throw new ValidationError('Request body must be an object');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const data = body as Record<string, unknown>;
|
|
47
|
+
|
|
48
|
+
if (!data.transport || typeof data.transport !== 'object') {
|
|
49
|
+
throw new ValidationError('Missing or invalid transport configuration');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const transport = data.transport as Record<string, unknown>;
|
|
53
|
+
|
|
54
|
+
if (!transport.type || typeof transport.type !== 'string') {
|
|
55
|
+
throw new ValidationError('Transport type is required');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const transportType = transport.type as string;
|
|
59
|
+
|
|
60
|
+
if (!['stdio', 'sse', 'http'].includes(transportType)) {
|
|
61
|
+
throw new ValidationError(
|
|
62
|
+
`Invalid transport type: ${transportType}. Must be one of: stdio, sse, http`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
switch (transportType) {
|
|
67
|
+
case 'stdio':
|
|
68
|
+
return validateStdioTransport(transport);
|
|
69
|
+
case 'sse':
|
|
70
|
+
return validateSseTransport(transport);
|
|
71
|
+
case 'http':
|
|
72
|
+
return validateHttpTransport(transport);
|
|
73
|
+
default:
|
|
74
|
+
throw new ValidationError(`Unknown transport type: ${transportType}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function validateStdioTransport(
|
|
79
|
+
transport: Record<string, unknown>
|
|
80
|
+
): StdioTransportConfig {
|
|
81
|
+
if (!transport.command || typeof transport.command !== 'string') {
|
|
82
|
+
throw new ValidationError(
|
|
83
|
+
'stdio transport requires a command string'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const config: StdioTransportConfig = {
|
|
88
|
+
type: 'stdio',
|
|
89
|
+
command: transport.command,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (transport.args !== undefined) {
|
|
93
|
+
if (
|
|
94
|
+
!Array.isArray(transport.args) ||
|
|
95
|
+
!transport.args.every((a) => typeof a === 'string')
|
|
96
|
+
) {
|
|
97
|
+
throw new ValidationError('args must be an array of strings');
|
|
98
|
+
}
|
|
99
|
+
config.args = transport.args;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (transport.env !== undefined) {
|
|
103
|
+
if (
|
|
104
|
+
typeof transport.env !== 'object' ||
|
|
105
|
+
transport.env === null ||
|
|
106
|
+
Array.isArray(transport.env)
|
|
107
|
+
) {
|
|
108
|
+
throw new ValidationError('env must be an object');
|
|
109
|
+
}
|
|
110
|
+
const env = transport.env as Record<string, unknown>;
|
|
111
|
+
for (const [key, value] of Object.entries(env)) {
|
|
112
|
+
if (typeof value !== 'string') {
|
|
113
|
+
throw new ValidationError(`env.${key} must be a string`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
config.env = env as Record<string, string>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (transport.cwd !== undefined) {
|
|
120
|
+
if (typeof transport.cwd !== 'string') {
|
|
121
|
+
throw new ValidationError('cwd must be a string');
|
|
122
|
+
}
|
|
123
|
+
config.cwd = transport.cwd;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return config;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function validateSseTransport(
|
|
130
|
+
transport: Record<string, unknown>
|
|
131
|
+
): SseTransportConfig {
|
|
132
|
+
if (!transport.url || typeof transport.url !== 'string') {
|
|
133
|
+
throw new ValidationError('sse transport requires a url string');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!isValidUrl(transport.url)) {
|
|
137
|
+
throw new ValidationError('sse transport url must be a valid URL');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const config: SseTransportConfig = {
|
|
141
|
+
type: 'sse',
|
|
142
|
+
url: transport.url,
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
if (transport.headers !== undefined) {
|
|
146
|
+
config.headers = validateHeaders(transport.headers);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return config;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function validateHttpTransport(
|
|
153
|
+
transport: Record<string, unknown>
|
|
154
|
+
): HttpTransportConfig {
|
|
155
|
+
if (!transport.url || typeof transport.url !== 'string') {
|
|
156
|
+
throw new ValidationError('http transport requires a url string');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!isValidUrl(transport.url)) {
|
|
160
|
+
throw new ValidationError('http transport url must be a valid URL');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const config: HttpTransportConfig = {
|
|
164
|
+
type: 'http',
|
|
165
|
+
url: transport.url,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (transport.headers !== undefined) {
|
|
169
|
+
config.headers = validateHeaders(transport.headers);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return config;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function validateHeaders(headers: unknown): Record<string, string> {
|
|
176
|
+
if (
|
|
177
|
+
typeof headers !== 'object' ||
|
|
178
|
+
headers === null ||
|
|
179
|
+
Array.isArray(headers)
|
|
180
|
+
) {
|
|
181
|
+
throw new ValidationError('headers must be an object');
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const headersObj = headers as Record<string, unknown>;
|
|
185
|
+
const result: Record<string, string> = {};
|
|
186
|
+
|
|
187
|
+
for (const [key, value] of Object.entries(headersObj)) {
|
|
188
|
+
if (typeof value !== 'string') {
|
|
189
|
+
throw new ValidationError(`header "${key}" must be a string`);
|
|
190
|
+
}
|
|
191
|
+
result[key] = value;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function isValidUrl(url: string): boolean {
|
|
198
|
+
try {
|
|
199
|
+
const parsed = new URL(url);
|
|
200
|
+
return ['http:', 'https:'].includes(parsed.protocol);
|
|
201
|
+
} catch {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Validates a tool call request
|
|
208
|
+
*/
|
|
209
|
+
export function validateToolCall(body: unknown): {
|
|
210
|
+
toolName: string;
|
|
211
|
+
params: Record<string, unknown>;
|
|
212
|
+
sessionId: string;
|
|
213
|
+
} {
|
|
214
|
+
if (!body || typeof body !== 'object') {
|
|
215
|
+
throw new ValidationError('Request body must be an object');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const data = body as Record<string, unknown>;
|
|
219
|
+
|
|
220
|
+
if (!data.sessionId || typeof data.sessionId !== 'string') {
|
|
221
|
+
throw new ValidationError('sessionId is required and must be a string');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!data.toolName || typeof data.toolName !== 'string') {
|
|
225
|
+
throw new ValidationError('toolName is required and must be a string');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (data.toolName.length === 0) {
|
|
229
|
+
throw new ValidationError('toolName cannot be empty');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Validate tool name format (alphanumeric, underscores, hyphens)
|
|
233
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(data.toolName)) {
|
|
234
|
+
throw new ValidationError(
|
|
235
|
+
'toolName must start with a letter and contain only alphanumeric characters, underscores, and hyphens'
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let params: Record<string, unknown> = {};
|
|
240
|
+
if (data.params !== undefined) {
|
|
241
|
+
if (
|
|
242
|
+
typeof data.params !== 'object' ||
|
|
243
|
+
data.params === null ||
|
|
244
|
+
Array.isArray(data.params)
|
|
245
|
+
) {
|
|
246
|
+
throw new ValidationError('params must be an object');
|
|
247
|
+
}
|
|
248
|
+
params = data.params as Record<string, unknown>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
sessionId: data.sessionId,
|
|
253
|
+
toolName: data.toolName,
|
|
254
|
+
params,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Validates a resource read request
|
|
260
|
+
*/
|
|
261
|
+
export function validateResourceRead(body: unknown): {
|
|
262
|
+
uri: string;
|
|
263
|
+
sessionId: string;
|
|
264
|
+
} {
|
|
265
|
+
if (!body || typeof body !== 'object') {
|
|
266
|
+
throw new ValidationError('Request body must be an object');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const data = body as Record<string, unknown>;
|
|
270
|
+
|
|
271
|
+
if (!data.sessionId || typeof data.sessionId !== 'string') {
|
|
272
|
+
throw new ValidationError('sessionId is required and must be a string');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!data.uri || typeof data.uri !== 'string') {
|
|
276
|
+
throw new ValidationError('uri is required and must be a string');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (data.uri.length === 0) {
|
|
280
|
+
throw new ValidationError('uri cannot be empty');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Basic URI validation - should have a scheme
|
|
284
|
+
if (!data.uri.includes(':')) {
|
|
285
|
+
throw new ValidationError('uri must be a valid URI with a scheme');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
sessionId: data.sessionId,
|
|
290
|
+
uri: data.uri,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Validates a prompt get request
|
|
296
|
+
*/
|
|
297
|
+
export function validatePromptGet(body: unknown): {
|
|
298
|
+
name: string;
|
|
299
|
+
args?: Record<string, string>;
|
|
300
|
+
sessionId: string;
|
|
301
|
+
} {
|
|
302
|
+
if (!body || typeof body !== 'object') {
|
|
303
|
+
throw new ValidationError('Request body must be an object');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const data = body as Record<string, unknown>;
|
|
307
|
+
|
|
308
|
+
if (!data.sessionId || typeof data.sessionId !== 'string') {
|
|
309
|
+
throw new ValidationError('sessionId is required and must be a string');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (!data.name || typeof data.name !== 'string') {
|
|
313
|
+
throw new ValidationError('name is required and must be a string');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (data.name.length === 0) {
|
|
317
|
+
throw new ValidationError('name cannot be empty');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Validate prompt name format
|
|
321
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(data.name)) {
|
|
322
|
+
throw new ValidationError(
|
|
323
|
+
'name must start with a letter and contain only alphanumeric characters, underscores, and hyphens'
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const result: {
|
|
328
|
+
name: string;
|
|
329
|
+
args?: Record<string, string>;
|
|
330
|
+
sessionId: string;
|
|
331
|
+
} = {
|
|
332
|
+
sessionId: data.sessionId,
|
|
333
|
+
name: data.name,
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
if (data.args !== undefined) {
|
|
337
|
+
if (
|
|
338
|
+
typeof data.args !== 'object' ||
|
|
339
|
+
data.args === null ||
|
|
340
|
+
Array.isArray(data.args)
|
|
341
|
+
) {
|
|
342
|
+
throw new ValidationError('args must be an object');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const args = data.args as Record<string, unknown>;
|
|
346
|
+
const validatedArgs: Record<string, string> = {};
|
|
347
|
+
|
|
348
|
+
for (const [key, value] of Object.entries(args)) {
|
|
349
|
+
if (typeof value !== 'string') {
|
|
350
|
+
throw new ValidationError(`args.${key} must be a string`);
|
|
351
|
+
}
|
|
352
|
+
validatedArgs[key] = value;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
result.args = validatedArgs;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Validates and extracts session ID from request
|
|
363
|
+
*/
|
|
364
|
+
export function validateSessionId(body: unknown): string {
|
|
365
|
+
if (!body || typeof body !== 'object') {
|
|
366
|
+
throw new ValidationError('Request body must be an object');
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const data = body as Record<string, unknown>;
|
|
370
|
+
|
|
371
|
+
if (!data.sessionId || typeof data.sessionId !== 'string') {
|
|
372
|
+
throw new ValidationError('sessionId is required and must be a string');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (data.sessionId.length === 0) {
|
|
376
|
+
throw new ValidationError('sessionId cannot be empty');
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return data.sessionId;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Validates session ID from query parameters
|
|
384
|
+
*/
|
|
385
|
+
export function validateSessionIdFromQuery(
|
|
386
|
+
searchParams: URLSearchParams
|
|
387
|
+
): string {
|
|
388
|
+
const sessionId = searchParams.get('sessionId');
|
|
389
|
+
|
|
390
|
+
if (!sessionId) {
|
|
391
|
+
throw new ValidationError('sessionId query parameter is required');
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (sessionId.length === 0) {
|
|
395
|
+
throw new ValidationError('sessionId cannot be empty');
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return sessionId;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Dangerous patterns to detect in code
|
|
402
|
+
const DANGEROUS_PATTERNS = [
|
|
403
|
+
// Shell injection
|
|
404
|
+
/\$\(.*\)/,
|
|
405
|
+
/`[^`]*`/,
|
|
406
|
+
/;\s*(rm|mv|cp|chmod|chown|kill|pkill|shutdown|reboot)\b/i,
|
|
407
|
+
// File system access outside sandbox
|
|
408
|
+
/\.\.\//,
|
|
409
|
+
/\/etc\//,
|
|
410
|
+
/\/root\//,
|
|
411
|
+
/\/home\/(?!sandbox)/,
|
|
412
|
+
// Network attacks
|
|
413
|
+
/\beval\s*\(/,
|
|
414
|
+
/\bexec\s*\(/,
|
|
415
|
+
/\bspawn\s*\(/,
|
|
416
|
+
/child_process/,
|
|
417
|
+
// Process manipulation
|
|
418
|
+
/process\.exit/,
|
|
419
|
+
/process\.kill/,
|
|
420
|
+
// Dangerous imports (for TypeScript/JavaScript)
|
|
421
|
+
/require\s*\(\s*['"]fs['"]\s*\)/,
|
|
422
|
+
/from\s+['"]fs['"]/,
|
|
423
|
+
/import\s+.*\s+from\s+['"]child_process['"]/,
|
|
424
|
+
// Environment variable access
|
|
425
|
+
/process\.env\./,
|
|
426
|
+
// Infinite loops (basic detection)
|
|
427
|
+
/while\s*\(\s*true\s*\)/,
|
|
428
|
+
/for\s*\(\s*;\s*;\s*\)/,
|
|
429
|
+
];
|
|
430
|
+
|
|
431
|
+
// Allowed patterns that might look dangerous but are safe
|
|
432
|
+
const ALLOWED_PATTERNS = [
|
|
433
|
+
// Common safe patterns
|
|
434
|
+
/console\.log/,
|
|
435
|
+
/JSON\.parse/,
|
|
436
|
+
/JSON\.stringify/,
|
|
437
|
+
];
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Sanitizes code by removing dangerous patterns
|
|
441
|
+
* Throws ValidationError if code contains unsafe constructs that cannot be sanitized
|
|
442
|
+
*/
|
|
443
|
+
export function sanitizeCode(code: string): string {
|
|
444
|
+
if (typeof code !== 'string') {
|
|
445
|
+
throw new ValidationError('Code must be a string');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Check for truly dangerous patterns that cannot be sanitized
|
|
449
|
+
for (const pattern of DANGEROUS_PATTERNS) {
|
|
450
|
+
if (pattern.test(code)) {
|
|
451
|
+
// Check if it's actually an allowed pattern
|
|
452
|
+
let isAllowed = false;
|
|
453
|
+
for (const allowedPattern of ALLOWED_PATTERNS) {
|
|
454
|
+
if (allowedPattern.test(code)) {
|
|
455
|
+
// More specific check - the dangerous pattern might be a false positive
|
|
456
|
+
const match = code.match(pattern);
|
|
457
|
+
if (match) {
|
|
458
|
+
const matchStr = match[0];
|
|
459
|
+
// If the match is part of an allowed pattern, skip
|
|
460
|
+
for (const ap of ALLOWED_PATTERNS) {
|
|
461
|
+
if (ap.test(matchStr)) {
|
|
462
|
+
isAllowed = true;
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (!isAllowed) {
|
|
471
|
+
throw new ValidationError(
|
|
472
|
+
`Code contains potentially dangerous pattern: ${pattern.toString()}. ` +
|
|
473
|
+
'This operation is not allowed for security reasons.'
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Remove any null bytes
|
|
480
|
+
let sanitized = code.replace(/\0/g, '');
|
|
481
|
+
|
|
482
|
+
// Normalize line endings
|
|
483
|
+
sanitized = sanitized.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
484
|
+
|
|
485
|
+
// Limit code length
|
|
486
|
+
const MAX_CODE_LENGTH = 100000; // 100KB
|
|
487
|
+
if (sanitized.length > MAX_CODE_LENGTH) {
|
|
488
|
+
throw new ValidationError(
|
|
489
|
+
`Code exceeds maximum length of ${MAX_CODE_LENGTH} characters`
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return sanitized;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Validates connect request body
|
|
498
|
+
*/
|
|
499
|
+
export function validateConnectRequest(body: unknown): {
|
|
500
|
+
transport: TransportConfig;
|
|
501
|
+
generatedCode?: string;
|
|
502
|
+
} {
|
|
503
|
+
if (!body || typeof body !== 'object') {
|
|
504
|
+
throw new ValidationError('Request body must be an object');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const data = body as Record<string, unknown>;
|
|
508
|
+
const transport = validateTransportConfig(body);
|
|
509
|
+
|
|
510
|
+
const result: {
|
|
511
|
+
transport: TransportConfig;
|
|
512
|
+
generatedCode?: string;
|
|
513
|
+
} = { transport };
|
|
514
|
+
|
|
515
|
+
if (data.generatedCode !== undefined) {
|
|
516
|
+
if (typeof data.generatedCode !== 'string') {
|
|
517
|
+
throw new ValidationError('generatedCode must be a string');
|
|
518
|
+
}
|
|
519
|
+
result.generatedCode = sanitizeCode(data.generatedCode);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application Constants
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const APP_NAME = 'GitHub to MCP';
|
|
8
|
+
export const APP_VERSION = '1.0.0';
|
|
9
|
+
export const APP_DESCRIPTION = 'Convert any GitHub repository into an MCP server for AI assistants';
|
|
10
|
+
|
|
11
|
+
export const GITHUB_URL = 'https://github.com/nirholas/github-to-mcp';
|
|
12
|
+
export const DOCS_URL = 'https://github.com/nirholas/github-to-mcp#readme';
|
|
13
|
+
|
|
14
|
+
export const EXAMPLE_REPOS = [
|
|
15
|
+
{
|
|
16
|
+
name: 'Stripe Node.js SDK',
|
|
17
|
+
url: 'https://github.com/stripe/stripe-node',
|
|
18
|
+
description: 'Popular payment API SDK',
|
|
19
|
+
category: 'API SDK',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'OpenAI Node.js SDK',
|
|
23
|
+
url: 'https://github.com/openai/openai-node',
|
|
24
|
+
description: 'Official OpenAI API library',
|
|
25
|
+
category: 'API SDK',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Octokit.js',
|
|
29
|
+
url: 'https://github.com/octokit/octokit.js',
|
|
30
|
+
description: 'GitHub REST API client',
|
|
31
|
+
category: 'API SDK',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'Axios',
|
|
35
|
+
url: 'https://github.com/axios/axios',
|
|
36
|
+
description: 'Promise-based HTTP client',
|
|
37
|
+
category: 'Library',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'Prisma',
|
|
41
|
+
url: 'https://github.com/prisma/prisma',
|
|
42
|
+
description: 'Next-generation ORM',
|
|
43
|
+
category: 'Database',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'OpenAI MCP Server',
|
|
47
|
+
url: 'https://github.com/arthurcolle/openai-mcp',
|
|
48
|
+
description: 'Python MCP server for OpenAI',
|
|
49
|
+
category: 'MCP Server',
|
|
50
|
+
},
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
export const CLASSIFICATION_LABELS: Record<string, { label: string; color: string; icon: string }> = {
|
|
54
|
+
'mcp-server': { label: 'MCP Server', color: 'purple', icon: '🔮' },
|
|
55
|
+
'api-sdk': { label: 'API SDK', color: 'blue', icon: '🔌' },
|
|
56
|
+
'cli-tool': { label: 'CLI Tool', color: 'green', icon: '⌨️' },
|
|
57
|
+
'library': { label: 'Library', color: 'yellow', icon: '📚' },
|
|
58
|
+
'documentation': { label: 'Documentation', color: 'gray', icon: '📄' },
|
|
59
|
+
'data': { label: 'Data/Config', color: 'orange', icon: '📊' },
|
|
60
|
+
'unknown': { label: 'Unknown', color: 'gray', icon: '❓' },
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const SOURCE_TYPE_LABELS: Record<string, { label: string; color: string }> = {
|
|
64
|
+
'readme': { label: 'README', color: 'blue' },
|
|
65
|
+
'code': { label: 'Source Code', color: 'green' },
|
|
66
|
+
'openapi': { label: 'OpenAPI Spec', color: 'purple' },
|
|
67
|
+
'graphql': { label: 'GraphQL', color: 'pink' },
|
|
68
|
+
'mcp-introspect': { label: 'MCP Introspect', color: 'orange' },
|
|
69
|
+
'universal': { label: 'Universal', color: 'gray' },
|
|
70
|
+
'mcp-decorator': { label: 'MCP Decorator', color: 'pink' },
|
|
71
|
+
'python-mcp': { label: 'Python MCP', color: 'yellow' },
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const PLATFORMS = {
|
|
75
|
+
claude: {
|
|
76
|
+
name: 'Claude Desktop',
|
|
77
|
+
icon: '🤖',
|
|
78
|
+
configPath: '~/Library/Application Support/Claude/claude_desktop_config.json',
|
|
79
|
+
docsUrl: 'https://docs.anthropic.com/en/docs/claude-desktop',
|
|
80
|
+
},
|
|
81
|
+
cursor: {
|
|
82
|
+
name: 'Cursor',
|
|
83
|
+
icon: '⚡',
|
|
84
|
+
configPath: '.cursor/mcp.json',
|
|
85
|
+
docsUrl: 'https://www.cursor.com/docs',
|
|
86
|
+
},
|
|
87
|
+
openai: {
|
|
88
|
+
name: 'ChatGPT / OpenAI',
|
|
89
|
+
icon: '💬',
|
|
90
|
+
configPath: 'openai-mcp-config.json',
|
|
91
|
+
docsUrl: 'https://platform.openai.com/docs',
|
|
92
|
+
},
|
|
93
|
+
} as const;
|
|
94
|
+
|
|
95
|
+
export const RATE_LIMIT = {
|
|
96
|
+
requestsPerMinute: 30,
|
|
97
|
+
burstLimit: 5,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const CACHE_TTL = {
|
|
101
|
+
conversion: 3600, // 1 hour
|
|
102
|
+
repoInfo: 86400, // 24 hours
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const MAX_TOOLS_DISPLAY = 100;
|
|
106
|
+
export const MAX_HISTORY_ITEMS = 50;
|
|
107
|
+
|
|
108
|
+
export const KEYBOARD_SHORTCUTS = {
|
|
109
|
+
convert: 'Enter',
|
|
110
|
+
clearInput: 'Escape',
|
|
111
|
+
copyCode: 'mod+shift+c',
|
|
112
|
+
downloadCode: 'mod+shift+d',
|
|
113
|
+
toggleTheme: 'mod+shift+t',
|
|
114
|
+
} as const;
|