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,1206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Server for github-to-mcp
|
|
3
|
+
* Exposes the github-to-mcp conversion functionality as MCP tools
|
|
4
|
+
* @copyright Copyright (c) 2024-2026 nirholas
|
|
5
|
+
* @license MIT
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
+
import {
|
|
11
|
+
CallToolRequestSchema,
|
|
12
|
+
ListToolsRequestSchema,
|
|
13
|
+
ListResourcesRequestSchema,
|
|
14
|
+
ReadResourceRequestSchema,
|
|
15
|
+
ListPromptsRequestSchema,
|
|
16
|
+
GetPromptRequestSchema,
|
|
17
|
+
Tool,
|
|
18
|
+
TextContent,
|
|
19
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
20
|
+
import { GithubToMcpGenerator, ExtractedTool, GenerationResult } from '@nirholas/github-to-mcp';
|
|
21
|
+
import { z } from 'zod';
|
|
22
|
+
|
|
23
|
+
// Import new tools
|
|
24
|
+
import {
|
|
25
|
+
generateOpenApiTool,
|
|
26
|
+
handleGenerateOpenApi,
|
|
27
|
+
} from './tools/generate-openapi.js';
|
|
28
|
+
import {
|
|
29
|
+
exportDockerTool,
|
|
30
|
+
handleExportDocker,
|
|
31
|
+
} from './tools/export-docker.js';
|
|
32
|
+
import {
|
|
33
|
+
streamConvertTool,
|
|
34
|
+
listProvidersTool,
|
|
35
|
+
handleStreamConvert,
|
|
36
|
+
handleListProviders,
|
|
37
|
+
} from './tools/stream-convert.js';
|
|
38
|
+
import {
|
|
39
|
+
testMcpToolTool,
|
|
40
|
+
handleTestMcpTool,
|
|
41
|
+
} from './tools/test-mcp-tool.js';
|
|
42
|
+
import {
|
|
43
|
+
monitorMcpServerTool,
|
|
44
|
+
handleMonitorMcpServer,
|
|
45
|
+
} from './tools/monitor-mcp-server.js';
|
|
46
|
+
|
|
47
|
+
// Import prompts
|
|
48
|
+
import {
|
|
49
|
+
PROMPTS,
|
|
50
|
+
getPromptMessages,
|
|
51
|
+
} from './prompts/index.js';
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Tool Definitions
|
|
55
|
+
// ============================================================================
|
|
56
|
+
|
|
57
|
+
const TOOLS: Tool[] = [
|
|
58
|
+
{
|
|
59
|
+
name: 'convert_repo',
|
|
60
|
+
description: `Convert a GitHub repository into an MCP server implementation.
|
|
61
|
+
|
|
62
|
+
This tool analyzes a GitHub repository and generates a complete MCP server that exposes the repository's functionality as AI-usable tools.
|
|
63
|
+
|
|
64
|
+
Supported extraction sources:
|
|
65
|
+
- OpenAPI/Swagger specifications
|
|
66
|
+
- README documentation
|
|
67
|
+
- Source code (Python functions, TypeScript functions)
|
|
68
|
+
- GraphQL schemas
|
|
69
|
+
- Existing MCP server introspection
|
|
70
|
+
|
|
71
|
+
Returns the generated MCP server code with full type annotations and documentation.`,
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
github_url: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'The GitHub repository URL (e.g., https://github.com/owner/repo)',
|
|
78
|
+
},
|
|
79
|
+
output_language: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
enum: ['typescript', 'python'],
|
|
82
|
+
default: 'typescript',
|
|
83
|
+
description: 'The output language for the generated MCP server',
|
|
84
|
+
},
|
|
85
|
+
sources: {
|
|
86
|
+
type: 'array',
|
|
87
|
+
items: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
enum: ['readme', 'openapi', 'code', 'graphql'],
|
|
90
|
+
},
|
|
91
|
+
description: 'Which extraction sources to use (default: all)',
|
|
92
|
+
},
|
|
93
|
+
github_token: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'GitHub personal access token for private repos or higher rate limits (optional)',
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ['github_url'],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'list_extracted_tools',
|
|
103
|
+
description: `Preview the tools that would be extracted from a GitHub repository without generating the full MCP server.
|
|
104
|
+
|
|
105
|
+
Useful for understanding what capabilities will be available before committing to a full conversion.
|
|
106
|
+
|
|
107
|
+
Returns a structured list of all detected tools with their names, descriptions, parameters, and source locations.`,
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
github_url: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
description: 'The GitHub repository URL to analyze',
|
|
114
|
+
},
|
|
115
|
+
sources: {
|
|
116
|
+
type: 'array',
|
|
117
|
+
items: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
enum: ['readme', 'openapi', 'code', 'graphql'],
|
|
120
|
+
},
|
|
121
|
+
description: 'Which extraction sources to scan',
|
|
122
|
+
},
|
|
123
|
+
github_token: {
|
|
124
|
+
type: 'string',
|
|
125
|
+
description: 'GitHub personal access token (optional)',
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
required: ['github_url'],
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'validate_mcp_server',
|
|
133
|
+
description: `Validate MCP server code for correctness and best practices.
|
|
134
|
+
|
|
135
|
+
Checks:
|
|
136
|
+
- Tool definitions are well-formed
|
|
137
|
+
- Input schemas are valid JSON Schema
|
|
138
|
+
- Type annotations are consistent
|
|
139
|
+
- Required fields are present
|
|
140
|
+
- Description quality
|
|
141
|
+
|
|
142
|
+
Returns validation results with any warnings or errors found.`,
|
|
143
|
+
inputSchema: {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: {
|
|
146
|
+
code: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'The MCP server code to validate',
|
|
149
|
+
},
|
|
150
|
+
language: {
|
|
151
|
+
type: 'string',
|
|
152
|
+
enum: ['typescript', 'python'],
|
|
153
|
+
description: 'The language of the code',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
required: ['code', 'language'],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'generate_claude_config',
|
|
161
|
+
description: `Generate a Claude Desktop configuration snippet for an MCP server.
|
|
162
|
+
|
|
163
|
+
Creates the JSON configuration that can be added to Claude Desktop's config file to register the generated MCP server.`,
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
server_name: {
|
|
168
|
+
type: 'string',
|
|
169
|
+
description: 'Name for the MCP server in the config',
|
|
170
|
+
},
|
|
171
|
+
server_path: {
|
|
172
|
+
type: 'string',
|
|
173
|
+
description: 'Path to the generated MCP server file',
|
|
174
|
+
},
|
|
175
|
+
language: {
|
|
176
|
+
type: 'string',
|
|
177
|
+
enum: ['typescript', 'python'],
|
|
178
|
+
description: 'The language of the MCP server',
|
|
179
|
+
},
|
|
180
|
+
env_vars: {
|
|
181
|
+
type: 'object',
|
|
182
|
+
additionalProperties: { type: 'string' },
|
|
183
|
+
description: 'Environment variables to pass to the server',
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
required: ['server_name', 'server_path', 'language'],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: 'generate_cursor_config',
|
|
191
|
+
description: `Generate a Cursor IDE configuration for an MCP server.
|
|
192
|
+
|
|
193
|
+
Creates the configuration format used by Cursor to integrate MCP servers.`,
|
|
194
|
+
inputSchema: {
|
|
195
|
+
type: 'object',
|
|
196
|
+
properties: {
|
|
197
|
+
server_name: {
|
|
198
|
+
type: 'string',
|
|
199
|
+
description: 'Name for the MCP server',
|
|
200
|
+
},
|
|
201
|
+
server_path: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'Path to the generated MCP server file',
|
|
204
|
+
},
|
|
205
|
+
language: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
enum: ['typescript', 'python'],
|
|
208
|
+
description: 'The language of the MCP server',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
required: ['server_name', 'server_path', 'language'],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: 'analyze_repo_structure',
|
|
216
|
+
description: `Analyze a GitHub repository's structure to identify what extraction sources are available.
|
|
217
|
+
|
|
218
|
+
Scans for:
|
|
219
|
+
- OpenAPI/Swagger specs
|
|
220
|
+
- GraphQL schemas
|
|
221
|
+
- README files
|
|
222
|
+
- Python and TypeScript source files
|
|
223
|
+
- Existing MCP server implementations
|
|
224
|
+
|
|
225
|
+
Returns a detailed breakdown of the repository structure with recommendations for extraction.`,
|
|
226
|
+
inputSchema: {
|
|
227
|
+
type: 'object',
|
|
228
|
+
properties: {
|
|
229
|
+
github_url: {
|
|
230
|
+
type: 'string',
|
|
231
|
+
description: 'The GitHub repository URL to analyze',
|
|
232
|
+
},
|
|
233
|
+
github_token: {
|
|
234
|
+
type: 'string',
|
|
235
|
+
description: 'GitHub personal access token (optional)',
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
required: ['github_url'],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'convert_openapi_to_mcp',
|
|
243
|
+
description: `Convert an OpenAPI specification directly to MCP tools.
|
|
244
|
+
|
|
245
|
+
Supports OpenAPI 3.x and Swagger 2.0 specifications. Can also handle:
|
|
246
|
+
- Postman collections
|
|
247
|
+
- Insomnia exports
|
|
248
|
+
- HAR files
|
|
249
|
+
- AsyncAPI specs
|
|
250
|
+
- GraphQL schemas
|
|
251
|
+
|
|
252
|
+
Returns MCP tool definitions extracted from the API specification.`,
|
|
253
|
+
inputSchema: {
|
|
254
|
+
type: 'object',
|
|
255
|
+
properties: {
|
|
256
|
+
spec: {
|
|
257
|
+
type: 'string',
|
|
258
|
+
description: 'The OpenAPI specification content (JSON or YAML)',
|
|
259
|
+
},
|
|
260
|
+
format: {
|
|
261
|
+
type: 'string',
|
|
262
|
+
enum: ['openapi', 'swagger', 'postman', 'insomnia', 'har', 'asyncapi', 'graphql'],
|
|
263
|
+
default: 'openapi',
|
|
264
|
+
description: 'The format of the specification',
|
|
265
|
+
},
|
|
266
|
+
base_url: {
|
|
267
|
+
type: 'string',
|
|
268
|
+
description: 'Override the base URL for API calls',
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
required: ['spec'],
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: 'get_tool_template',
|
|
276
|
+
description: `Get a template for creating a new MCP tool definition.
|
|
277
|
+
|
|
278
|
+
Returns a starter template in the requested language with best practices and documentation.`,
|
|
279
|
+
inputSchema: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
tool_name: {
|
|
283
|
+
type: 'string',
|
|
284
|
+
description: 'Name for the tool',
|
|
285
|
+
},
|
|
286
|
+
description: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
description: 'Description of what the tool does',
|
|
289
|
+
},
|
|
290
|
+
parameters: {
|
|
291
|
+
type: 'array',
|
|
292
|
+
items: {
|
|
293
|
+
type: 'object',
|
|
294
|
+
properties: {
|
|
295
|
+
name: { type: 'string' },
|
|
296
|
+
type: { type: 'string' },
|
|
297
|
+
description: { type: 'string' },
|
|
298
|
+
required: { type: 'boolean' },
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
description: 'List of parameters for the tool',
|
|
302
|
+
},
|
|
303
|
+
language: {
|
|
304
|
+
type: 'string',
|
|
305
|
+
enum: ['typescript', 'python'],
|
|
306
|
+
default: 'typescript',
|
|
307
|
+
description: 'Target language for the template',
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
required: ['tool_name', 'description'],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
// New tools added
|
|
314
|
+
generateOpenApiTool,
|
|
315
|
+
exportDockerTool,
|
|
316
|
+
streamConvertTool,
|
|
317
|
+
listProvidersTool,
|
|
318
|
+
testMcpToolTool,
|
|
319
|
+
monitorMcpServerTool,
|
|
320
|
+
];
|
|
321
|
+
|
|
322
|
+
// ============================================================================
|
|
323
|
+
// Tool Implementations
|
|
324
|
+
// ============================================================================
|
|
325
|
+
|
|
326
|
+
async function convertRepo(args: {
|
|
327
|
+
github_url: string;
|
|
328
|
+
output_language?: 'typescript' | 'python';
|
|
329
|
+
sources?: string[];
|
|
330
|
+
github_token?: string;
|
|
331
|
+
}): Promise<TextContent> {
|
|
332
|
+
const generator = new GithubToMcpGenerator({
|
|
333
|
+
githubToken: args.github_token,
|
|
334
|
+
sources: args.sources as any,
|
|
335
|
+
outputLanguage: args.output_language || 'typescript',
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
try {
|
|
339
|
+
const result = await generator.generate(args.github_url);
|
|
340
|
+
|
|
341
|
+
let code: string;
|
|
342
|
+
if (args.output_language === 'python') {
|
|
343
|
+
code = result.generatePython();
|
|
344
|
+
} else {
|
|
345
|
+
code = result.generate();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const summary = formatResultSummary(result);
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
type: 'text',
|
|
352
|
+
text: `# MCP Server Generated Successfully
|
|
353
|
+
|
|
354
|
+
${summary}
|
|
355
|
+
|
|
356
|
+
## Generated Code
|
|
357
|
+
|
|
358
|
+
\`\`\`${args.output_language || 'typescript'}
|
|
359
|
+
${code}
|
|
360
|
+
\`\`\`
|
|
361
|
+
`,
|
|
362
|
+
};
|
|
363
|
+
} catch (error) {
|
|
364
|
+
return {
|
|
365
|
+
type: 'text',
|
|
366
|
+
text: `Error generating MCP server: ${error instanceof Error ? error.message : String(error)}`,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async function listExtractedTools(args: {
|
|
372
|
+
github_url: string;
|
|
373
|
+
sources?: string[];
|
|
374
|
+
github_token?: string;
|
|
375
|
+
}): Promise<TextContent> {
|
|
376
|
+
const generator = new GithubToMcpGenerator({
|
|
377
|
+
githubToken: args.github_token,
|
|
378
|
+
sources: args.sources as any,
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
const result = await generator.generate(args.github_url);
|
|
383
|
+
|
|
384
|
+
const toolsList = result.tools.map((tool: ExtractedTool, index: number) => {
|
|
385
|
+
const params = Object.entries(tool.parameters || {})
|
|
386
|
+
.map(([name, schema]) => {
|
|
387
|
+
const s = schema as any;
|
|
388
|
+
return ` - \`${name}\` (${s.type}${tool.required?.includes(name) ? ', required' : ''}): ${s.description || 'No description'}`;
|
|
389
|
+
})
|
|
390
|
+
.join('\n');
|
|
391
|
+
|
|
392
|
+
return `### ${index + 1}. ${tool.name}
|
|
393
|
+
|
|
394
|
+
**Source:** ${tool.source.type} (${tool.source.file})
|
|
395
|
+
**Description:** ${tool.description}
|
|
396
|
+
|
|
397
|
+
**Parameters:**
|
|
398
|
+
${params || ' None'}
|
|
399
|
+
`;
|
|
400
|
+
}).join('\n---\n\n');
|
|
401
|
+
|
|
402
|
+
return {
|
|
403
|
+
type: 'text',
|
|
404
|
+
text: `# Extracted Tools from ${args.github_url}
|
|
405
|
+
|
|
406
|
+
**Total Tools:** ${result.tools.length}
|
|
407
|
+
**Sources Used:** ${result.sources.map(s => `${s.type} (${s.count} tools)`).join(', ')}
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
${toolsList}`,
|
|
412
|
+
};
|
|
413
|
+
} catch (error) {
|
|
414
|
+
return {
|
|
415
|
+
type: 'text',
|
|
416
|
+
text: `Error analyzing repository: ${error instanceof Error ? error.message : String(error)}`,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function validateMcpServer(args: { code: string; language: string }): TextContent {
|
|
422
|
+
const issues: string[] = [];
|
|
423
|
+
const warnings: string[] = [];
|
|
424
|
+
const code = args.code;
|
|
425
|
+
|
|
426
|
+
// Check for tool definitions
|
|
427
|
+
if (args.language === 'typescript') {
|
|
428
|
+
if (!code.includes('ListToolsRequestSchema') && !code.includes('tools:')) {
|
|
429
|
+
issues.push('Missing tool definitions - no ListToolsRequestSchema handler or tools array found');
|
|
430
|
+
}
|
|
431
|
+
if (!code.includes('CallToolRequestSchema')) {
|
|
432
|
+
issues.push('Missing CallToolRequestSchema handler - tools cannot be executed');
|
|
433
|
+
}
|
|
434
|
+
if (!code.includes('@modelcontextprotocol/sdk')) {
|
|
435
|
+
warnings.push('Not using official MCP SDK - consider using @modelcontextprotocol/sdk');
|
|
436
|
+
}
|
|
437
|
+
if (!code.includes('inputSchema')) {
|
|
438
|
+
warnings.push('No inputSchema definitions found - tools may not have proper parameter validation');
|
|
439
|
+
}
|
|
440
|
+
if (!code.includes('description')) {
|
|
441
|
+
warnings.push('Missing tool descriptions - AI assistants need descriptions to understand tool purpose');
|
|
442
|
+
}
|
|
443
|
+
} else if (args.language === 'python') {
|
|
444
|
+
if (!code.includes('@mcp.tool') && !code.includes('list_tools')) {
|
|
445
|
+
issues.push('Missing tool definitions');
|
|
446
|
+
}
|
|
447
|
+
if (!code.includes('description=')) {
|
|
448
|
+
warnings.push('Missing tool descriptions');
|
|
449
|
+
}
|
|
450
|
+
if (!code.includes('def ') && !code.includes('async def ')) {
|
|
451
|
+
issues.push('No function definitions found');
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Check for common issues
|
|
456
|
+
if (code.length < 100) {
|
|
457
|
+
issues.push('Code appears too short to be a complete MCP server');
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const status = issues.length === 0 ? '✅ Valid' : '❌ Invalid';
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
type: 'text',
|
|
464
|
+
text: `# MCP Server Validation
|
|
465
|
+
|
|
466
|
+
**Status:** ${status}
|
|
467
|
+
|
|
468
|
+
${issues.length > 0 ? `## Errors
|
|
469
|
+
${issues.map(i => `- ❌ ${i}`).join('\n')}
|
|
470
|
+
` : ''}
|
|
471
|
+
|
|
472
|
+
${warnings.length > 0 ? `## Warnings
|
|
473
|
+
${warnings.map(w => `- ⚠️ ${w}`).join('\n')}
|
|
474
|
+
` : ''}
|
|
475
|
+
|
|
476
|
+
${issues.length === 0 && warnings.length === 0 ? '✅ No issues found!' : ''}`,
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function generateClaudeConfig(args: {
|
|
481
|
+
server_name: string;
|
|
482
|
+
server_path: string;
|
|
483
|
+
language: string;
|
|
484
|
+
env_vars?: Record<string, string>;
|
|
485
|
+
}): TextContent {
|
|
486
|
+
const command = args.language === 'python' ? 'python' : 'node';
|
|
487
|
+
const config = {
|
|
488
|
+
mcpServers: {
|
|
489
|
+
[args.server_name]: {
|
|
490
|
+
command,
|
|
491
|
+
args: [args.server_path],
|
|
492
|
+
...(args.env_vars && { env: args.env_vars }),
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
return {
|
|
498
|
+
type: 'text',
|
|
499
|
+
text: `# Claude Desktop Configuration
|
|
500
|
+
|
|
501
|
+
Add the following to your Claude Desktop config file:
|
|
502
|
+
|
|
503
|
+
**macOS:** \`~/Library/Application Support/Claude/claude_desktop_config.json\`
|
|
504
|
+
**Windows:** \`%APPDATA%\\Claude\\claude_desktop_config.json\`
|
|
505
|
+
**Linux:** \`~/.config/Claude/claude_desktop_config.json\`
|
|
506
|
+
|
|
507
|
+
\`\`\`json
|
|
508
|
+
${JSON.stringify(config, null, 2)}
|
|
509
|
+
\`\`\`
|
|
510
|
+
|
|
511
|
+
## Full Config Example
|
|
512
|
+
|
|
513
|
+
If you have multiple servers, merge them like this:
|
|
514
|
+
|
|
515
|
+
\`\`\`json
|
|
516
|
+
{
|
|
517
|
+
"mcpServers": {
|
|
518
|
+
"${args.server_name}": ${JSON.stringify(config.mcpServers[args.server_name], null, 4).split('\n').join('\n ')},
|
|
519
|
+
"other-server": {
|
|
520
|
+
"command": "...",
|
|
521
|
+
"args": ["..."]
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
\`\`\`
|
|
526
|
+
`,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function generateCursorConfig(args: {
|
|
531
|
+
server_name: string;
|
|
532
|
+
server_path: string;
|
|
533
|
+
language: string;
|
|
534
|
+
}): TextContent {
|
|
535
|
+
const command = args.language === 'python' ? 'python' : 'node';
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
type: 'text',
|
|
539
|
+
text: `# Cursor IDE Configuration
|
|
540
|
+
|
|
541
|
+
Add to your Cursor settings or \`.cursor/mcp.json\`:
|
|
542
|
+
|
|
543
|
+
\`\`\`json
|
|
544
|
+
{
|
|
545
|
+
"mcpServers": {
|
|
546
|
+
"${args.server_name}": {
|
|
547
|
+
"command": "${command}",
|
|
548
|
+
"args": ["${args.server_path}"]
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
\`\`\`
|
|
553
|
+
|
|
554
|
+
## Alternative: Using npx
|
|
555
|
+
|
|
556
|
+
If your MCP server is published to npm:
|
|
557
|
+
|
|
558
|
+
\`\`\`json
|
|
559
|
+
{
|
|
560
|
+
"mcpServers": {
|
|
561
|
+
"${args.server_name}": {
|
|
562
|
+
"command": "npx",
|
|
563
|
+
"args": ["-y", "${args.server_name}"]
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
\`\`\`
|
|
568
|
+
`,
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
async function analyzeRepoStructure(args: {
|
|
573
|
+
github_url: string;
|
|
574
|
+
github_token?: string;
|
|
575
|
+
}): Promise<TextContent> {
|
|
576
|
+
const generator = new GithubToMcpGenerator({
|
|
577
|
+
githubToken: args.github_token,
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
try {
|
|
581
|
+
const result = await generator.generate(args.github_url);
|
|
582
|
+
|
|
583
|
+
const analysis = {
|
|
584
|
+
classification: result.classification,
|
|
585
|
+
sources: result.sources,
|
|
586
|
+
metadata: {
|
|
587
|
+
name: result.metadata.name,
|
|
588
|
+
description: result.metadata.description,
|
|
589
|
+
language: result.metadata.language,
|
|
590
|
+
stars: result.metadata.stargazers_count,
|
|
591
|
+
topics: result.metadata.topics,
|
|
592
|
+
},
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
const recommendations: string[] = [];
|
|
596
|
+
|
|
597
|
+
if (result.classification.type === 'api-sdk') {
|
|
598
|
+
recommendations.push('This appears to be an API SDK - OpenAPI extraction will likely work well');
|
|
599
|
+
}
|
|
600
|
+
if (result.classification.type === 'mcp-server') {
|
|
601
|
+
recommendations.push('This is already an MCP server - introspection mode recommended');
|
|
602
|
+
}
|
|
603
|
+
if (result.sources.some(s => s.type === 'openapi')) {
|
|
604
|
+
recommendations.push('OpenAPI specs detected - these provide the most accurate tool definitions');
|
|
605
|
+
}
|
|
606
|
+
if (result.sources.some(s => s.type === 'code')) {
|
|
607
|
+
recommendations.push('Source code parsed - consider reviewing auto-generated descriptions');
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return {
|
|
611
|
+
type: 'text',
|
|
612
|
+
text: `# Repository Analysis: ${args.github_url}
|
|
613
|
+
|
|
614
|
+
## Classification
|
|
615
|
+
- **Type:** ${result.classification.type}
|
|
616
|
+
- **Confidence:** ${(result.classification.confidence * 100).toFixed(0)}%
|
|
617
|
+
- **Indicators:** ${result.classification.indicators.join(', ')}
|
|
618
|
+
|
|
619
|
+
## Repository Info
|
|
620
|
+
- **Language:** ${analysis.metadata.language || 'Unknown'}
|
|
621
|
+
- **Stars:** ${analysis.metadata.stars || 0}
|
|
622
|
+
- **Topics:** ${analysis.metadata.topics?.join(', ') || 'None'}
|
|
623
|
+
|
|
624
|
+
## Detected Sources
|
|
625
|
+
${result.sources.map(s => `- **${s.type}:** ${s.count} tools from ${s.files.length} files`).join('\n')}
|
|
626
|
+
|
|
627
|
+
## Files by Source
|
|
628
|
+
${result.sources.map(s => `### ${s.type}
|
|
629
|
+
${s.files.map(f => `- ${f}`).join('\n') || 'N/A'}`).join('\n\n')}
|
|
630
|
+
|
|
631
|
+
## Recommendations
|
|
632
|
+
${recommendations.map(r => `- ${r}`).join('\n')}
|
|
633
|
+
|
|
634
|
+
## Total Tools Available: ${result.tools.length}
|
|
635
|
+
`,
|
|
636
|
+
};
|
|
637
|
+
} catch (error) {
|
|
638
|
+
return {
|
|
639
|
+
type: 'text',
|
|
640
|
+
text: `Error analyzing repository: ${error instanceof Error ? error.message : String(error)}`,
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
async function convertOpenApiToMcpTool(args: {
|
|
646
|
+
spec: string;
|
|
647
|
+
format?: string;
|
|
648
|
+
base_url?: string;
|
|
649
|
+
}): Promise<TextContent> {
|
|
650
|
+
try {
|
|
651
|
+
const { convertOpenApiToMcp } = await import('@github-to-mcp/openapi-parser');
|
|
652
|
+
|
|
653
|
+
const result = await convertOpenApiToMcp(args.spec, {
|
|
654
|
+
format: args.format as any,
|
|
655
|
+
baseUrl: args.base_url,
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
return {
|
|
659
|
+
type: 'text',
|
|
660
|
+
text: `# OpenAPI to MCP Conversion
|
|
661
|
+
|
|
662
|
+
**Tools Extracted:** ${result.tools.length}
|
|
663
|
+
**API Title:** ${result.info?.title || 'Unknown'}
|
|
664
|
+
**Version:** ${result.info?.version || 'Unknown'}
|
|
665
|
+
|
|
666
|
+
## Tools
|
|
667
|
+
|
|
668
|
+
${result.tools.map((tool: any, i: number) => `### ${i + 1}. ${tool.name}
|
|
669
|
+
${tool.description}
|
|
670
|
+
|
|
671
|
+
**Parameters:**
|
|
672
|
+
${Object.entries(tool.inputSchema?.properties || {}).map(([name, schema]: [string, any]) =>
|
|
673
|
+
`- \`${name}\` (${schema.type}): ${schema.description || 'No description'}`
|
|
674
|
+
).join('\n') || 'None'}
|
|
675
|
+
`).join('\n---\n')}`,
|
|
676
|
+
};
|
|
677
|
+
} catch (error) {
|
|
678
|
+
return {
|
|
679
|
+
type: 'text',
|
|
680
|
+
text: `Error converting specification: ${error instanceof Error ? error.message : String(error)}`,
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
function getToolTemplate(args: {
|
|
686
|
+
tool_name: string;
|
|
687
|
+
description: string;
|
|
688
|
+
parameters?: Array<{ name: string; type: string; description?: string; required?: boolean }>;
|
|
689
|
+
language?: string;
|
|
690
|
+
}): TextContent {
|
|
691
|
+
const params = args.parameters || [];
|
|
692
|
+
|
|
693
|
+
if (args.language === 'python') {
|
|
694
|
+
const pythonParams = params.map(p => {
|
|
695
|
+
const pythonType = {
|
|
696
|
+
string: 'str',
|
|
697
|
+
number: 'float',
|
|
698
|
+
integer: 'int',
|
|
699
|
+
boolean: 'bool',
|
|
700
|
+
array: 'list',
|
|
701
|
+
object: 'dict',
|
|
702
|
+
}[p.type] || 'Any';
|
|
703
|
+
return ` ${p.name}: ${pythonType}${p.required ? '' : ' = None'}`;
|
|
704
|
+
}).join('\n');
|
|
705
|
+
|
|
706
|
+
const docParams = params.map(p =>
|
|
707
|
+
` ${p.name}: ${p.description || 'No description'}`
|
|
708
|
+
).join('\n');
|
|
709
|
+
|
|
710
|
+
return {
|
|
711
|
+
type: 'text',
|
|
712
|
+
text: `# Python MCP Tool Template
|
|
713
|
+
|
|
714
|
+
\`\`\`python
|
|
715
|
+
from mcp.server import Server
|
|
716
|
+
from mcp.types import Tool, TextContent
|
|
717
|
+
import mcp.server.stdio
|
|
718
|
+
|
|
719
|
+
server = Server("${args.tool_name}-server")
|
|
720
|
+
|
|
721
|
+
@server.list_tools()
|
|
722
|
+
async def list_tools() -> list[Tool]:
|
|
723
|
+
return [
|
|
724
|
+
Tool(
|
|
725
|
+
name="${args.tool_name}",
|
|
726
|
+
description="""${args.description}""",
|
|
727
|
+
inputSchema={
|
|
728
|
+
"type": "object",
|
|
729
|
+
"properties": {
|
|
730
|
+
${params.map(p => ` "${p.name}": {
|
|
731
|
+
"type": "${p.type}",
|
|
732
|
+
"description": "${p.description || ''}"
|
|
733
|
+
}`).join(',\n')}
|
|
734
|
+
},
|
|
735
|
+
"required": [${params.filter(p => p.required).map(p => `"${p.name}"`).join(', ')}]
|
|
736
|
+
}
|
|
737
|
+
)
|
|
738
|
+
]
|
|
739
|
+
|
|
740
|
+
@server.call_tool()
|
|
741
|
+
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
742
|
+
if name == "${args.tool_name}":
|
|
743
|
+
return await ${args.tool_name.replace(/-/g, '_')}(**arguments)
|
|
744
|
+
raise ValueError(f"Unknown tool: {name}")
|
|
745
|
+
|
|
746
|
+
async def ${args.tool_name.replace(/-/g, '_')}(
|
|
747
|
+
${pythonParams || ' # No parameters'}
|
|
748
|
+
) -> list[TextContent]:
|
|
749
|
+
"""
|
|
750
|
+
${args.description}
|
|
751
|
+
|
|
752
|
+
Args:
|
|
753
|
+
${docParams || ' None'}
|
|
754
|
+
|
|
755
|
+
Returns:
|
|
756
|
+
Tool execution result
|
|
757
|
+
"""
|
|
758
|
+
# TODO: Implement tool logic
|
|
759
|
+
result = f"Executed ${args.tool_name}"
|
|
760
|
+
|
|
761
|
+
return [TextContent(type="text", text=result)]
|
|
762
|
+
|
|
763
|
+
async def main():
|
|
764
|
+
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
|
|
765
|
+
await server.run(read_stream, write_stream)
|
|
766
|
+
|
|
767
|
+
if __name__ == "__main__":
|
|
768
|
+
import asyncio
|
|
769
|
+
asyncio.run(main())
|
|
770
|
+
\`\`\`
|
|
771
|
+
`,
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// TypeScript template (default)
|
|
776
|
+
const tsParams = params.map(p =>
|
|
777
|
+
`${p.name}${p.required ? '' : '?'}: ${p.type === 'integer' ? 'number' : p.type}`
|
|
778
|
+
).join('; ');
|
|
779
|
+
|
|
780
|
+
return {
|
|
781
|
+
type: 'text',
|
|
782
|
+
text: `# TypeScript MCP Tool Template
|
|
783
|
+
|
|
784
|
+
\`\`\`typescript
|
|
785
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
786
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
787
|
+
import {
|
|
788
|
+
CallToolRequestSchema,
|
|
789
|
+
ListToolsRequestSchema,
|
|
790
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
791
|
+
|
|
792
|
+
const server = new Server(
|
|
793
|
+
{ name: '${args.tool_name}-server', version: '1.0.0' },
|
|
794
|
+
{ capabilities: { tools: {} } }
|
|
795
|
+
);
|
|
796
|
+
|
|
797
|
+
// Tool definitions
|
|
798
|
+
const TOOLS = [
|
|
799
|
+
{
|
|
800
|
+
name: '${args.tool_name}',
|
|
801
|
+
description: \`${args.description}\`,
|
|
802
|
+
inputSchema: {
|
|
803
|
+
type: 'object',
|
|
804
|
+
properties: {
|
|
805
|
+
${params.map(p => ` ${p.name}: {
|
|
806
|
+
type: '${p.type}',
|
|
807
|
+
description: '${p.description || ''}',
|
|
808
|
+
}`).join(',\n')}
|
|
809
|
+
},
|
|
810
|
+
required: [${params.filter(p => p.required).map(p => `'${p.name}'`).join(', ')}],
|
|
811
|
+
},
|
|
812
|
+
},
|
|
813
|
+
];
|
|
814
|
+
|
|
815
|
+
// List tools handler
|
|
816
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
817
|
+
tools: TOOLS,
|
|
818
|
+
}));
|
|
819
|
+
|
|
820
|
+
// Call tool handler
|
|
821
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
822
|
+
const { name, arguments: args } = request.params;
|
|
823
|
+
|
|
824
|
+
if (name === '${args.tool_name}') {
|
|
825
|
+
const { ${params.map(p => p.name).join(', ')} } = args as { ${tsParams || 'never?: never' } };
|
|
826
|
+
|
|
827
|
+
// TODO: Implement tool logic
|
|
828
|
+
const result = \`Executed ${args.tool_name}\`;
|
|
829
|
+
|
|
830
|
+
return {
|
|
831
|
+
content: [{ type: 'text', text: result }],
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
throw new Error(\`Unknown tool: \${name}\`);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
// Start server
|
|
839
|
+
async function main() {
|
|
840
|
+
const transport = new StdioServerTransport();
|
|
841
|
+
await server.connect(transport);
|
|
842
|
+
console.error('MCP Server running on stdio');
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
main().catch(console.error);
|
|
846
|
+
\`\`\`
|
|
847
|
+
`,
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// ============================================================================
|
|
852
|
+
// Helper Functions
|
|
853
|
+
// ============================================================================
|
|
854
|
+
|
|
855
|
+
function formatResultSummary(result: GenerationResult): string {
|
|
856
|
+
return `## Conversion Summary
|
|
857
|
+
|
|
858
|
+
- **Repository:** ${result.repo}
|
|
859
|
+
- **Classification:** ${result.classification.type} (${(result.classification.confidence * 100).toFixed(0)}% confidence)
|
|
860
|
+
- **Total Tools:** ${result.tools.length}
|
|
861
|
+
|
|
862
|
+
### Sources Breakdown
|
|
863
|
+
${result.sources.map(s => `- **${s.type}:** ${s.count} tools`).join('\n')}
|
|
864
|
+
|
|
865
|
+
### Extracted Tools
|
|
866
|
+
${result.tools.slice(0, 10).map((t: ExtractedTool, i: number) => `${i + 1}. \`${t.name}\` - ${t.description?.slice(0, 60)}${(t.description?.length || 0) > 60 ? '...' : ''}`).join('\n')}
|
|
867
|
+
${result.tools.length > 10 ? `\n... and ${result.tools.length - 10} more tools` : ''}`;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// ============================================================================
|
|
871
|
+
// Server Setup
|
|
872
|
+
// ============================================================================
|
|
873
|
+
|
|
874
|
+
const server = new Server(
|
|
875
|
+
{
|
|
876
|
+
name: 'github-to-mcp',
|
|
877
|
+
version: '1.0.0',
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
capabilities: {
|
|
881
|
+
tools: {},
|
|
882
|
+
resources: {},
|
|
883
|
+
prompts: {},
|
|
884
|
+
},
|
|
885
|
+
}
|
|
886
|
+
);
|
|
887
|
+
|
|
888
|
+
// List available tools
|
|
889
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
890
|
+
return { tools: TOOLS };
|
|
891
|
+
});
|
|
892
|
+
|
|
893
|
+
// Handle tool calls
|
|
894
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
895
|
+
const { name, arguments: args } = request.params;
|
|
896
|
+
|
|
897
|
+
try {
|
|
898
|
+
let result: TextContent;
|
|
899
|
+
|
|
900
|
+
switch (name) {
|
|
901
|
+
case 'convert_repo':
|
|
902
|
+
result = await convertRepo(args as any);
|
|
903
|
+
break;
|
|
904
|
+
case 'list_extracted_tools':
|
|
905
|
+
result = await listExtractedTools(args as any);
|
|
906
|
+
break;
|
|
907
|
+
case 'validate_mcp_server':
|
|
908
|
+
result = validateMcpServer(args as any);
|
|
909
|
+
break;
|
|
910
|
+
case 'generate_claude_config':
|
|
911
|
+
result = generateClaudeConfig(args as any);
|
|
912
|
+
break;
|
|
913
|
+
case 'generate_cursor_config':
|
|
914
|
+
result = generateCursorConfig(args as any);
|
|
915
|
+
break;
|
|
916
|
+
case 'analyze_repo_structure':
|
|
917
|
+
result = await analyzeRepoStructure(args as any);
|
|
918
|
+
break;
|
|
919
|
+
case 'convert_openapi_to_mcp':
|
|
920
|
+
result = await convertOpenApiToMcpTool(args as any);
|
|
921
|
+
break;
|
|
922
|
+
case 'get_tool_template':
|
|
923
|
+
result = getToolTemplate(args as any);
|
|
924
|
+
break;
|
|
925
|
+
// New tool handlers
|
|
926
|
+
case 'generate_openapi_spec':
|
|
927
|
+
result = await handleGenerateOpenApi(args as any);
|
|
928
|
+
break;
|
|
929
|
+
case 'export_docker':
|
|
930
|
+
result = await handleExportDocker(args as any);
|
|
931
|
+
break;
|
|
932
|
+
case 'stream_convert':
|
|
933
|
+
result = await handleStreamConvert(args as any);
|
|
934
|
+
break;
|
|
935
|
+
case 'list_providers':
|
|
936
|
+
result = await handleListProviders(args as any);
|
|
937
|
+
break;
|
|
938
|
+
case 'test_mcp_tool':
|
|
939
|
+
result = await handleTestMcpTool(args as any);
|
|
940
|
+
break;
|
|
941
|
+
case 'monitor_mcp_server':
|
|
942
|
+
result = await handleMonitorMcpServer(args as any);
|
|
943
|
+
break;
|
|
944
|
+
default:
|
|
945
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
return {
|
|
949
|
+
content: [result],
|
|
950
|
+
};
|
|
951
|
+
} catch (error) {
|
|
952
|
+
return {
|
|
953
|
+
content: [
|
|
954
|
+
{
|
|
955
|
+
type: 'text',
|
|
956
|
+
text: `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
957
|
+
},
|
|
958
|
+
],
|
|
959
|
+
isError: true,
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
|
|
964
|
+
// List resources (documentation, examples)
|
|
965
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
966
|
+
return {
|
|
967
|
+
resources: [
|
|
968
|
+
{
|
|
969
|
+
uri: 'github-to-mcp://docs/quick-start',
|
|
970
|
+
name: 'Quick Start Guide',
|
|
971
|
+
description: 'Get started with github-to-mcp in 5 minutes',
|
|
972
|
+
mimeType: 'text/markdown',
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
uri: 'github-to-mcp://docs/extraction-sources',
|
|
976
|
+
name: 'Extraction Sources',
|
|
977
|
+
description: 'Learn about different extraction sources and their capabilities',
|
|
978
|
+
mimeType: 'text/markdown',
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
uri: 'github-to-mcp://examples/typescript',
|
|
982
|
+
name: 'TypeScript MCP Server Example',
|
|
983
|
+
description: 'Complete TypeScript MCP server example',
|
|
984
|
+
mimeType: 'text/markdown',
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
uri: 'github-to-mcp://examples/python',
|
|
988
|
+
name: 'Python MCP Server Example',
|
|
989
|
+
description: 'Complete Python MCP server example',
|
|
990
|
+
mimeType: 'text/markdown',
|
|
991
|
+
},
|
|
992
|
+
],
|
|
993
|
+
};
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
// Read resources
|
|
997
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
998
|
+
const { uri } = request.params;
|
|
999
|
+
|
|
1000
|
+
const resources: Record<string, string> = {
|
|
1001
|
+
'github-to-mcp://docs/quick-start': `# Quick Start Guide
|
|
1002
|
+
|
|
1003
|
+
## Installation
|
|
1004
|
+
|
|
1005
|
+
\`\`\`bash
|
|
1006
|
+
npm install -g @nirholas/github-to-mcp
|
|
1007
|
+
\`\`\`
|
|
1008
|
+
|
|
1009
|
+
## Basic Usage
|
|
1010
|
+
|
|
1011
|
+
\`\`\`bash
|
|
1012
|
+
# Convert a GitHub repository to an MCP server
|
|
1013
|
+
github-to-mcp https://github.com/owner/repo
|
|
1014
|
+
|
|
1015
|
+
# Save to a file
|
|
1016
|
+
github-to-mcp https://github.com/owner/repo --output ./mcp-server.ts
|
|
1017
|
+
|
|
1018
|
+
# Generate Python output
|
|
1019
|
+
github-to-mcp https://github.com/owner/repo --language python
|
|
1020
|
+
\`\`\`
|
|
1021
|
+
|
|
1022
|
+
## Using with Claude Desktop
|
|
1023
|
+
|
|
1024
|
+
1. Generate your MCP server
|
|
1025
|
+
2. Add to Claude Desktop config:
|
|
1026
|
+
|
|
1027
|
+
\`\`\`json
|
|
1028
|
+
{
|
|
1029
|
+
"mcpServers": {
|
|
1030
|
+
"my-server": {
|
|
1031
|
+
"command": "node",
|
|
1032
|
+
"args": ["./mcp-server.js"]
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
\`\`\`
|
|
1037
|
+
|
|
1038
|
+
3. Restart Claude Desktop
|
|
1039
|
+
`,
|
|
1040
|
+
|
|
1041
|
+
'github-to-mcp://docs/extraction-sources': `# Extraction Sources
|
|
1042
|
+
|
|
1043
|
+
github-to-mcp can extract tools from multiple sources:
|
|
1044
|
+
|
|
1045
|
+
## 1. OpenAPI Specifications
|
|
1046
|
+
- Swagger 2.0 and OpenAPI 3.x
|
|
1047
|
+
- Automatic endpoint to tool conversion
|
|
1048
|
+
- Full parameter validation
|
|
1049
|
+
|
|
1050
|
+
## 2. README Documentation
|
|
1051
|
+
- Parses code examples
|
|
1052
|
+
- Extracts API descriptions
|
|
1053
|
+
- Identifies endpoints and methods
|
|
1054
|
+
|
|
1055
|
+
## 3. Source Code
|
|
1056
|
+
- Python function analysis
|
|
1057
|
+
- TypeScript function analysis
|
|
1058
|
+
- Docstring extraction
|
|
1059
|
+
- Type annotation parsing
|
|
1060
|
+
|
|
1061
|
+
## 4. GraphQL Schemas
|
|
1062
|
+
- Query and mutation extraction
|
|
1063
|
+
- Type-safe parameter generation
|
|
1064
|
+
|
|
1065
|
+
## 5. MCP Server Introspection
|
|
1066
|
+
- Analyzes existing MCP servers
|
|
1067
|
+
- Extracts tool definitions
|
|
1068
|
+
`,
|
|
1069
|
+
|
|
1070
|
+
'github-to-mcp://examples/typescript': `# TypeScript MCP Server Example
|
|
1071
|
+
|
|
1072
|
+
\`\`\`typescript
|
|
1073
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
1074
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
1075
|
+
|
|
1076
|
+
const server = new Server(
|
|
1077
|
+
{ name: 'example-server', version: '1.0.0' },
|
|
1078
|
+
{ capabilities: { tools: {} } }
|
|
1079
|
+
);
|
|
1080
|
+
|
|
1081
|
+
// Define tools
|
|
1082
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
1083
|
+
tools: [
|
|
1084
|
+
{
|
|
1085
|
+
name: 'hello',
|
|
1086
|
+
description: 'Say hello',
|
|
1087
|
+
inputSchema: {
|
|
1088
|
+
type: 'object',
|
|
1089
|
+
properties: {
|
|
1090
|
+
name: { type: 'string', description: 'Name to greet' }
|
|
1091
|
+
},
|
|
1092
|
+
required: ['name']
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
]
|
|
1096
|
+
}));
|
|
1097
|
+
|
|
1098
|
+
// Handle calls
|
|
1099
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1100
|
+
if (request.params.name === 'hello') {
|
|
1101
|
+
return {
|
|
1102
|
+
content: [{
|
|
1103
|
+
type: 'text',
|
|
1104
|
+
text: \`Hello, \${request.params.arguments.name}!\`
|
|
1105
|
+
}]
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
// Start
|
|
1111
|
+
const transport = new StdioServerTransport();
|
|
1112
|
+
await server.connect(transport);
|
|
1113
|
+
\`\`\`
|
|
1114
|
+
`,
|
|
1115
|
+
|
|
1116
|
+
'github-to-mcp://examples/python': `# Python MCP Server Example
|
|
1117
|
+
|
|
1118
|
+
\`\`\`python
|
|
1119
|
+
from mcp.server import Server
|
|
1120
|
+
from mcp.types import Tool, TextContent
|
|
1121
|
+
import mcp.server.stdio
|
|
1122
|
+
|
|
1123
|
+
server = Server("example-server")
|
|
1124
|
+
|
|
1125
|
+
@server.list_tools()
|
|
1126
|
+
async def list_tools():
|
|
1127
|
+
return [
|
|
1128
|
+
Tool(
|
|
1129
|
+
name="hello",
|
|
1130
|
+
description="Say hello",
|
|
1131
|
+
inputSchema={
|
|
1132
|
+
"type": "object",
|
|
1133
|
+
"properties": {
|
|
1134
|
+
"name": {"type": "string", "description": "Name to greet"}
|
|
1135
|
+
},
|
|
1136
|
+
"required": ["name"]
|
|
1137
|
+
}
|
|
1138
|
+
)
|
|
1139
|
+
]
|
|
1140
|
+
|
|
1141
|
+
@server.call_tool()
|
|
1142
|
+
async def call_tool(name: str, arguments: dict):
|
|
1143
|
+
if name == "hello":
|
|
1144
|
+
return [TextContent(type="text", text=f"Hello, {arguments['name']}!")]
|
|
1145
|
+
|
|
1146
|
+
async def main():
|
|
1147
|
+
async with mcp.server.stdio.stdio_server() as (read, write):
|
|
1148
|
+
await server.run(read, write)
|
|
1149
|
+
|
|
1150
|
+
if __name__ == "__main__":
|
|
1151
|
+
import asyncio
|
|
1152
|
+
asyncio.run(main())
|
|
1153
|
+
\`\`\`
|
|
1154
|
+
`,
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
const content = resources[uri];
|
|
1158
|
+
if (!content) {
|
|
1159
|
+
throw new Error(`Resource not found: ${uri}`);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
return {
|
|
1163
|
+
contents: [
|
|
1164
|
+
{
|
|
1165
|
+
uri,
|
|
1166
|
+
mimeType: 'text/markdown',
|
|
1167
|
+
text: content,
|
|
1168
|
+
},
|
|
1169
|
+
],
|
|
1170
|
+
};
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
// List available prompts
|
|
1174
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
1175
|
+
return { prompts: PROMPTS };
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
// Get prompt messages
|
|
1179
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
1180
|
+
const { name, arguments: args } = request.params;
|
|
1181
|
+
|
|
1182
|
+
try {
|
|
1183
|
+
const messages = getPromptMessages(name, args || {});
|
|
1184
|
+
return {
|
|
1185
|
+
description: PROMPTS.find(p => p.name === name)?.description || '',
|
|
1186
|
+
messages,
|
|
1187
|
+
};
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
throw new Error(`Error getting prompt: ${error instanceof Error ? error.message : String(error)}`);
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
|
|
1193
|
+
// ============================================================================
|
|
1194
|
+
// Main Entry Point
|
|
1195
|
+
// ============================================================================
|
|
1196
|
+
|
|
1197
|
+
async function main() {
|
|
1198
|
+
const transport = new StdioServerTransport();
|
|
1199
|
+
await server.connect(transport);
|
|
1200
|
+
console.error('github-to-mcp MCP Server running on stdio');
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
main().catch((error) => {
|
|
1204
|
+
console.error('Fatal error:', error);
|
|
1205
|
+
process.exit(1);
|
|
1206
|
+
});
|