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,491 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Edge-compatible subset of github-to-mcp for serverless/edge environments
|
|
3
|
+
* @copyright Copyright (c) 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*
|
|
6
|
+
* This module provides a lightweight version of the github-to-mcp generator
|
|
7
|
+
* that works in edge environments like Vercel Edge Functions, Cloudflare Workers,
|
|
8
|
+
* and Deno Deploy. It avoids Node.js-specific APIs and uses only Web APIs.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
GithubToMcpOptions,
|
|
13
|
+
ExtractedTool,
|
|
14
|
+
RepoMetadata,
|
|
15
|
+
RepoClassification,
|
|
16
|
+
RepoType,
|
|
17
|
+
SourceType
|
|
18
|
+
} from './types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Edge-compatible options (subset of full options)
|
|
22
|
+
*/
|
|
23
|
+
export interface EdgeOptions {
|
|
24
|
+
/** GitHub personal access token */
|
|
25
|
+
githubToken?: string;
|
|
26
|
+
/** Sources to extract from */
|
|
27
|
+
sources?: SourceType[];
|
|
28
|
+
/** Output language */
|
|
29
|
+
outputLanguage?: 'typescript' | 'python';
|
|
30
|
+
/** Enable verbose logging */
|
|
31
|
+
verbose?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Lightweight result for edge processing
|
|
36
|
+
*/
|
|
37
|
+
export interface EdgeResult {
|
|
38
|
+
repo: string;
|
|
39
|
+
name: string;
|
|
40
|
+
tools: ExtractedTool[];
|
|
41
|
+
classification: RepoClassification;
|
|
42
|
+
metadata: {
|
|
43
|
+
stars: number;
|
|
44
|
+
language: string;
|
|
45
|
+
license?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
};
|
|
48
|
+
/** Generated TypeScript code */
|
|
49
|
+
typescript?: string;
|
|
50
|
+
/** Generated Python code */
|
|
51
|
+
python?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Edge-compatible GitHub client using fetch API
|
|
56
|
+
*/
|
|
57
|
+
export class EdgeGitHubClient {
|
|
58
|
+
private token?: string;
|
|
59
|
+
private baseUrl = 'https://api.github.com';
|
|
60
|
+
|
|
61
|
+
constructor(token?: string) {
|
|
62
|
+
this.token = token;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private getHeaders(): Record<string, string> {
|
|
66
|
+
const headers: Record<string, string> = {
|
|
67
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
68
|
+
'User-Agent': 'github-to-mcp-edge'
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (this.token) {
|
|
72
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return headers;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Parse GitHub URL
|
|
80
|
+
*/
|
|
81
|
+
parseUrl(url: string): RepoMetadata {
|
|
82
|
+
const treeMatch = url.match(/github\.com\/([^\/]+)\/([^\/]+)\/tree\/(.+)/);
|
|
83
|
+
if (treeMatch) {
|
|
84
|
+
const owner = treeMatch[1];
|
|
85
|
+
const repo = treeMatch[2].replace('.git', '');
|
|
86
|
+
const parts = treeMatch[3].split('/');
|
|
87
|
+
return {
|
|
88
|
+
owner,
|
|
89
|
+
repo,
|
|
90
|
+
branch: parts[0],
|
|
91
|
+
path: parts.length > 1 ? parts.slice(1).join('/') : undefined
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const simpleMatch = url.match(/github\.com\/([^\/]+)\/([^\/]+)/);
|
|
96
|
+
if (simpleMatch) {
|
|
97
|
+
return {
|
|
98
|
+
owner: simpleMatch[1],
|
|
99
|
+
repo: simpleMatch[2].replace('.git', ''),
|
|
100
|
+
branch: 'main'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
throw new Error(`Invalid GitHub URL: ${url}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get repository metadata
|
|
109
|
+
*/
|
|
110
|
+
async getRepoMetadata(owner: string, repo: string) {
|
|
111
|
+
const response = await fetch(`${this.baseUrl}/repos/${owner}/${repo}`, {
|
|
112
|
+
headers: this.getHeaders()
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (!response.ok) {
|
|
116
|
+
throw new Error(`GitHub API error: ${response.status}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const data = await response.json() as {
|
|
120
|
+
stargazers_count: number;
|
|
121
|
+
language: string | null;
|
|
122
|
+
license: { spdx_id: string } | null;
|
|
123
|
+
description: string | null;
|
|
124
|
+
default_branch: string;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
stars: data.stargazers_count,
|
|
129
|
+
language: data.language || 'unknown',
|
|
130
|
+
license: data.license?.spdx_id,
|
|
131
|
+
description: data.description ?? undefined,
|
|
132
|
+
defaultBranch: data.default_branch
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Get file content
|
|
138
|
+
*/
|
|
139
|
+
async getFileContent(owner: string, repo: string, path: string, branch?: string): Promise<string | null> {
|
|
140
|
+
const url = `${this.baseUrl}/repos/${owner}/${repo}/contents/${path}${branch ? `?ref=${branch}` : ''}`;
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
const response = await fetch(url, {
|
|
144
|
+
headers: this.getHeaders()
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (!response.ok) return null;
|
|
148
|
+
|
|
149
|
+
const data = await response.json() as {
|
|
150
|
+
type: string;
|
|
151
|
+
content?: string;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
if (data.type === 'file' && data.content) {
|
|
155
|
+
// Decode base64 content
|
|
156
|
+
return atob(data.content.replace(/\n/g, ''));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return null;
|
|
160
|
+
} catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get README content
|
|
167
|
+
*/
|
|
168
|
+
async getReadme(owner: string, repo: string, branch?: string): Promise<string | null> {
|
|
169
|
+
const readmeFiles = ['README.md', 'README.MD', 'readme.md', 'Readme.md'];
|
|
170
|
+
|
|
171
|
+
for (const filename of readmeFiles) {
|
|
172
|
+
const content = await this.getFileContent(owner, repo, filename, branch);
|
|
173
|
+
if (content) return content;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Edge-compatible tool extractor
|
|
182
|
+
*/
|
|
183
|
+
export class EdgeToolExtractor {
|
|
184
|
+
/**
|
|
185
|
+
* Extract tools from README content
|
|
186
|
+
*/
|
|
187
|
+
extractFromReadme(readme: string, repoName: string): ExtractedTool[] {
|
|
188
|
+
const tools: ExtractedTool[] = [];
|
|
189
|
+
|
|
190
|
+
// Extract code blocks with function signatures
|
|
191
|
+
const codeBlockRegex = /```(?:typescript|javascript|python|js|ts)?\n([\s\S]*?)```/g;
|
|
192
|
+
let match;
|
|
193
|
+
|
|
194
|
+
while ((match = codeBlockRegex.exec(readme)) !== null) {
|
|
195
|
+
const code = match[1];
|
|
196
|
+
|
|
197
|
+
// Extract function definitions
|
|
198
|
+
const funcMatches = code.matchAll(
|
|
199
|
+
/(?:async\s+)?(?:function\s+|const\s+|let\s+|var\s+)?(\w+)\s*(?:=\s*(?:async\s*)?\(|\()/g
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
for (const funcMatch of funcMatches) {
|
|
203
|
+
const name = funcMatch[1];
|
|
204
|
+
if (this.isValidToolName(name)) {
|
|
205
|
+
tools.push({
|
|
206
|
+
name,
|
|
207
|
+
description: `Function extracted from README: ${name}`,
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {},
|
|
211
|
+
required: []
|
|
212
|
+
},
|
|
213
|
+
source: {
|
|
214
|
+
type: 'readme',
|
|
215
|
+
file: 'README.md'
|
|
216
|
+
},
|
|
217
|
+
confidence: 0.5
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Extract API endpoints from README
|
|
224
|
+
const endpointRegex = /(?:GET|POST|PUT|DELETE|PATCH)\s+[`']?([\/\w\-\{\}:]+)[`']?/gi;
|
|
225
|
+
while ((match = endpointRegex.exec(readme)) !== null) {
|
|
226
|
+
const endpoint = match[1];
|
|
227
|
+
const method = match[0].split(' ')[0].toUpperCase();
|
|
228
|
+
const name = this.endpointToToolName(endpoint, method);
|
|
229
|
+
|
|
230
|
+
tools.push({
|
|
231
|
+
name,
|
|
232
|
+
description: `${method} ${endpoint}`,
|
|
233
|
+
inputSchema: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
properties: {},
|
|
236
|
+
required: []
|
|
237
|
+
},
|
|
238
|
+
source: {
|
|
239
|
+
type: 'readme',
|
|
240
|
+
file: 'README.md'
|
|
241
|
+
},
|
|
242
|
+
confidence: 0.6
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return tools;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Check if a name is a valid tool name
|
|
251
|
+
*/
|
|
252
|
+
private isValidToolName(name: string): boolean {
|
|
253
|
+
const reserved = ['if', 'else', 'for', 'while', 'function', 'const', 'let', 'var', 'return', 'async', 'await'];
|
|
254
|
+
return name.length >= 2 && !reserved.includes(name.toLowerCase());
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Convert API endpoint to tool name
|
|
259
|
+
*/
|
|
260
|
+
private endpointToToolName(endpoint: string, method: string): string {
|
|
261
|
+
const parts = endpoint
|
|
262
|
+
.replace(/[{}]/g, '')
|
|
263
|
+
.split('/')
|
|
264
|
+
.filter(p => p && !p.startsWith(':'))
|
|
265
|
+
.map(p => p.charAt(0).toUpperCase() + p.slice(1));
|
|
266
|
+
|
|
267
|
+
const prefix = method.toLowerCase();
|
|
268
|
+
return prefix + parts.join('');
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Classify repository type (edge-compatible)
|
|
274
|
+
*/
|
|
275
|
+
export function classifyRepo(readme: string | null, language: string): RepoClassification {
|
|
276
|
+
let type: RepoType = 'unknown';
|
|
277
|
+
let confidence = 0.3;
|
|
278
|
+
const indicators: string[] = [];
|
|
279
|
+
|
|
280
|
+
const readmeLower = readme?.toLowerCase() || '';
|
|
281
|
+
|
|
282
|
+
// Check for MCP server
|
|
283
|
+
if (readmeLower.includes('mcp') || readmeLower.includes('model context protocol')) {
|
|
284
|
+
type = 'mcp-server';
|
|
285
|
+
confidence = 0.9;
|
|
286
|
+
indicators.push('Contains MCP references');
|
|
287
|
+
}
|
|
288
|
+
// Check for API/SDK
|
|
289
|
+
else if (readmeLower.includes('api') || readmeLower.includes('sdk') || readmeLower.includes('client')) {
|
|
290
|
+
type = 'api-sdk';
|
|
291
|
+
confidence = 0.7;
|
|
292
|
+
indicators.push('Contains API/SDK references');
|
|
293
|
+
}
|
|
294
|
+
// Check for CLI tool
|
|
295
|
+
else if (readmeLower.includes('cli') || readmeLower.includes('command line') || readmeLower.includes('terminal')) {
|
|
296
|
+
type = 'cli-tool';
|
|
297
|
+
confidence = 0.7;
|
|
298
|
+
indicators.push('Contains CLI references');
|
|
299
|
+
}
|
|
300
|
+
// Check for library
|
|
301
|
+
else if (readmeLower.includes('library') || readmeLower.includes('package') || readmeLower.includes('module')) {
|
|
302
|
+
type = 'library';
|
|
303
|
+
confidence = 0.6;
|
|
304
|
+
indicators.push('Contains library references');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
indicators.push(`Language: ${language}`);
|
|
308
|
+
|
|
309
|
+
return { type, confidence, indicators };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Generate TypeScript MCP server code (edge-compatible)
|
|
314
|
+
*/
|
|
315
|
+
export function generateTypeScript(tools: ExtractedTool[], repoName: string, owner: string): string {
|
|
316
|
+
const safeName = repoName.replace(/[^a-zA-Z0-9]/g, '_');
|
|
317
|
+
|
|
318
|
+
const toolDefinitions = tools.map(tool => `
|
|
319
|
+
{
|
|
320
|
+
name: "${tool.name}",
|
|
321
|
+
description: "${tool.description.replace(/"/g, '\\"')}",
|
|
322
|
+
inputSchema: ${JSON.stringify(tool.inputSchema, null, 4).replace(/\n/g, '\n ')}
|
|
323
|
+
}`).join(',');
|
|
324
|
+
|
|
325
|
+
const toolHandlers = tools.map((tool, i) =>
|
|
326
|
+
`${i === 0 ? '' : ' else '}if (name === "${tool.name}") {
|
|
327
|
+
// TODO: Implement ${tool.name}
|
|
328
|
+
return { content: [{ type: "text", text: "Not implemented: ${tool.name}" }] };
|
|
329
|
+
}`
|
|
330
|
+
).join('\n ');
|
|
331
|
+
|
|
332
|
+
return `/**
|
|
333
|
+
* Auto-generated MCP Server for ${repoName}
|
|
334
|
+
* Generated by @nirholas/github-to-mcp (Edge)
|
|
335
|
+
*
|
|
336
|
+
* Repository: https://github.com/${owner}/${repoName}
|
|
337
|
+
*/
|
|
338
|
+
|
|
339
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
340
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
341
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
342
|
+
|
|
343
|
+
const server = new Server(
|
|
344
|
+
{ name: "${safeName}-mcp", version: "1.0.0" },
|
|
345
|
+
{ capabilities: { tools: {} } }
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
// Tool definitions
|
|
349
|
+
const tools = [${toolDefinitions}
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
// List available tools
|
|
353
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
354
|
+
tools
|
|
355
|
+
}));
|
|
356
|
+
|
|
357
|
+
// Handle tool calls
|
|
358
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
359
|
+
const { name, arguments: args } = request.params;
|
|
360
|
+
|
|
361
|
+
${toolHandlers}
|
|
362
|
+
|
|
363
|
+
throw new Error(\`Unknown tool: \${name}\`);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Start server
|
|
367
|
+
const transport = new StdioServerTransport();
|
|
368
|
+
server.connect(transport);
|
|
369
|
+
`;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Generate Python MCP server code (edge-compatible)
|
|
374
|
+
*/
|
|
375
|
+
export function generatePython(tools: ExtractedTool[], repoName: string, owner: string): string {
|
|
376
|
+
const safeName = repoName.replace(/[^a-zA-Z0-9]/g, '_');
|
|
377
|
+
|
|
378
|
+
const toolDefinitions = tools.map(tool => ` Tool(
|
|
379
|
+
name="${tool.name}",
|
|
380
|
+
description="${tool.description.replace(/"/g, '\\"')}",
|
|
381
|
+
inputSchema=${JSON.stringify(tool.inputSchema)}
|
|
382
|
+
)`).join(',\n');
|
|
383
|
+
|
|
384
|
+
const toolHandlers = tools.map((tool, i) =>
|
|
385
|
+
` ${i === 0 ? '' : 'el'}if name == "${tool.name}":
|
|
386
|
+
# TODO: Implement ${tool.name}
|
|
387
|
+
return [TextContent(type="text", text="Not implemented: ${tool.name}")]`
|
|
388
|
+
).join('\n');
|
|
389
|
+
|
|
390
|
+
return `"""
|
|
391
|
+
Auto-generated MCP Server for ${repoName}
|
|
392
|
+
Generated by @nirholas/github-to-mcp (Edge)
|
|
393
|
+
|
|
394
|
+
Repository: https://github.com/${owner}/${repoName}
|
|
395
|
+
"""
|
|
396
|
+
|
|
397
|
+
import asyncio
|
|
398
|
+
from mcp.server import Server
|
|
399
|
+
from mcp.server.stdio import stdio_server
|
|
400
|
+
from mcp.types import Tool, TextContent
|
|
401
|
+
|
|
402
|
+
server = Server("${safeName}-mcp")
|
|
403
|
+
|
|
404
|
+
TOOLS = [
|
|
405
|
+
${toolDefinitions}
|
|
406
|
+
]
|
|
407
|
+
|
|
408
|
+
@server.list_tools()
|
|
409
|
+
async def list_tools() -> list[Tool]:
|
|
410
|
+
return TOOLS
|
|
411
|
+
|
|
412
|
+
@server.call_tool()
|
|
413
|
+
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
414
|
+
${toolHandlers}
|
|
415
|
+
else:
|
|
416
|
+
raise ValueError(f"Unknown tool: {name}")
|
|
417
|
+
|
|
418
|
+
async def main():
|
|
419
|
+
async with stdio_server() as (read_stream, write_stream):
|
|
420
|
+
await server.run(read_stream, write_stream, server.create_initialization_options())
|
|
421
|
+
|
|
422
|
+
if __name__ == "__main__":
|
|
423
|
+
asyncio.run(main())
|
|
424
|
+
`;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Main edge-compatible generator
|
|
429
|
+
*/
|
|
430
|
+
export class EdgeGenerator {
|
|
431
|
+
private github: EdgeGitHubClient;
|
|
432
|
+
private extractor: EdgeToolExtractor;
|
|
433
|
+
private options: EdgeOptions;
|
|
434
|
+
|
|
435
|
+
constructor(options: EdgeOptions = {}) {
|
|
436
|
+
this.options = options;
|
|
437
|
+
this.github = new EdgeGitHubClient(options.githubToken);
|
|
438
|
+
this.extractor = new EdgeToolExtractor();
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Generate MCP server from GitHub URL (edge-compatible)
|
|
443
|
+
*/
|
|
444
|
+
async generate(githubUrl: string): Promise<EdgeResult> {
|
|
445
|
+
// Parse URL
|
|
446
|
+
const repoMeta = this.github.parseUrl(githubUrl);
|
|
447
|
+
|
|
448
|
+
// Fetch metadata and README in parallel
|
|
449
|
+
const [metadata, readme] = await Promise.all([
|
|
450
|
+
this.github.getRepoMetadata(repoMeta.owner, repoMeta.repo),
|
|
451
|
+
this.github.getReadme(repoMeta.owner, repoMeta.repo, repoMeta.branch)
|
|
452
|
+
]);
|
|
453
|
+
|
|
454
|
+
// Classify repository
|
|
455
|
+
const classification = classifyRepo(readme, metadata.language);
|
|
456
|
+
|
|
457
|
+
// Extract tools from README
|
|
458
|
+
const tools = readme ? this.extractor.extractFromReadme(readme, repoMeta.repo) : [];
|
|
459
|
+
|
|
460
|
+
// Generate code
|
|
461
|
+
const result: EdgeResult = {
|
|
462
|
+
repo: `${repoMeta.owner}/${repoMeta.repo}`,
|
|
463
|
+
name: repoMeta.repo,
|
|
464
|
+
tools,
|
|
465
|
+
classification,
|
|
466
|
+
metadata
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// Generate TypeScript if requested
|
|
470
|
+
if (!this.options.outputLanguage || this.options.outputLanguage === 'typescript') {
|
|
471
|
+
result.typescript = generateTypeScript(tools, repoMeta.repo, repoMeta.owner);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Generate Python if requested
|
|
475
|
+
if (this.options.outputLanguage === 'python') {
|
|
476
|
+
result.python = generatePython(tools, repoMeta.repo, repoMeta.owner);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return result;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Quick generation function for edge use
|
|
485
|
+
*/
|
|
486
|
+
export async function generateFromUrl(githubUrl: string, options?: EdgeOptions): Promise<EdgeResult> {
|
|
487
|
+
const generator = new EdgeGenerator(options);
|
|
488
|
+
return generator.generate(githubUrl);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Export everything for edge runtime
|