
Research
/Security News
CanisterWorm: npm Publisher Compromise Deploys Backdoor Across 29+ Packages
The worm-enabled campaign hit @emilgroup and @teale.io, then used an ICP canister to deliver follow-on payloads.
github-to-mcp-monorepo
Advanced tools
Convert any GitHub repository into an MCP server in seconds
Give Claude, ChatGPT, Cursor, Windsurf, Cline, and any AI assistant instant access to any codebase.
🌐 Web App • 🚀 Quick Start • ✨ Features • 📖 Docs
GitHub to MCP bridges the gap between code repositories and AI assistants. Instead of manually describing APIs or copying code snippets into chat windows, this tool generates a standardized interface that allows AI systems to programmatically explore, read, and interact with any GitHub repository.
The generated MCP servers provide tools that AI assistants can invoke to read files, search code, list directory structures, and call API endpoints discovered within the repository. This enables AI assistants to have deep, structured access to codebases without requiring manual context management.
┌─────────────────────────────────────────────────────────────┐
│ GitHub Repository │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 1. Fetch & Classify → Detect repo type (API/CLI/Lib) │
│ 2. Extract Tools → OpenAPI, GraphQL, Code, README │
│ 3. Generate Server → TypeScript or Python MCP server │
│ 4. Bundle Output → Complete package with dependencies │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ Ready-to-use MCP Server + Config │
└─────────────────────────────────────────────────────────────┘
The Model Context Protocol (MCP) is an open standard developed by Anthropic that defines how AI assistants communicate with external tools and data sources. MCP servers expose "tools" that AI models can invoke, along with "resources" that provide context and "prompts" that guide interactions.
When you connect an MCP server to an AI assistant like Claude Desktop, the assistant gains the ability to call the tools defined by that server. For example, a GitHub MCP server might expose tools like read_file, search_code, or list_pull_requests, which the AI can invoke to gather information needed to answer questions or complete tasks.
This project generates MCP servers from GitHub repositories, automatically creating tools based on the repository's contents, APIs, and documentation.
Visit github-to-mcp.vercel.app — Paste any GitHub URL, click Generate, download your MCP server.
npx @nirholas/github-to-mcp https://github.com/stripe/stripe-node
import { generateFromGithub } from '@nirholas/github-to-mcp';
const result = await generateFromGithub('https://github.com/stripe/stripe-node');
console.log(`Generated ${result.tools.length} tools`);
await result.save('./my-mcp-server');
🔬 Repository Analysis
|
🌍 Multi-Language SupportInput repositories:
Output MCP servers:
|
🔧 Tool Extraction
|
⚡ Code Generation
|
Clone the repository and install dependencies:
git clone https://github.com/nirholas/github-to-mcp.git
cd github-to-mcp
pnpm install
pnpm build
The web application is deployed at github-to-mcp.vercel.app. Use the browser-based interface without any local installation.
The web interface provides the simplest way to convert repositories:
https://github.com/owner/repo)The web interface also provides an interactive playground where you can test generated tools before downloading.
After building the project locally, you can use the CLI:
# Basic usage
node packages/core/dist/cli.mjs https://github.com/owner/repo
# Specify output directory
node packages/core/dist/cli.mjs https://github.com/owner/repo --output ./my-mcp-server
# Generate Python instead of TypeScript
node packages/core/dist/cli.mjs https://github.com/owner/repo --language python
# Include only specific extraction sources
node packages/core/dist/cli.mjs https://github.com/owner/repo --sources openapi,readme
# Use a GitHub token for private repos or higher rate limits
GITHUB_TOKEN=ghp_xxx node packages/core/dist/cli.mjs https://github.com/owner/repo
Import the generator in your own TypeScript or JavaScript code:
import { GithubToMcpGenerator } from '@nirholas/github-to-mcp';
const generator = new GithubToMcpGenerator({
githubToken: process.env.GITHUB_TOKEN,
sources: ['openapi', 'readme', 'code'],
outputLanguage: 'typescript'
});
const result = await generator.generate('https://github.com/owner/repo');
console.log(`Repository: ${result.name}`);
console.log(`Classification: ${result.classification.type}`);
console.log(`Generated ${result.tools.length} tools`);
// Access the generated code
console.log(result.code);
// Save to disk
await result.save('./output-directory');
interface GithubToMcpOptions {
// GitHub personal access token for API authentication
githubToken?: string;
// Which sources to extract tools from
// Default: ['openapi', 'readme', 'code', 'graphql', 'mcp']
sources?: Array<'openapi' | 'readme' | 'code' | 'graphql' | 'grpc' | 'mcp'>;
// Output language for generated server
// Default: 'typescript'
outputLanguage?: 'typescript' | 'python' | 'go';
// Include universal tools (read_file, list_files, etc.)
// Default: true
includeUniversalTools?: boolean;
// Maximum number of tools to generate
// Default: 100
maxTools?: number;
// Specific branch to analyze
// Default: repository's default branch
branch?: string;
}
The conversion process follows these stages:
The generator first analyzes the repository to determine its type and structure:
| Classification | Description |
|---|---|
mcp-server | An existing MCP server implementation |
api-sdk | A client library for an API |
cli-tool | A command-line application |
library | A general-purpose code library |
documentation | Primarily documentation content |
data | Data files or datasets |
unknown | Unclassified repository |
Classification influences which extraction strategies are prioritized and how tools are named.
Tools are extracted from multiple sources within the repository:
When an OpenAPI specification is found:
When GraphQL schemas are found:
The README is analyzed for:
Extracted examples become tools with inferred parameter schemas.
For supported languages, the source code is analyzed:
@mcp.tool, @server.tool, or similar@GetMapping, @PostMapping, etc.If the repository is already an MCP server:
server.tool() definitionsAfter tools are extracted, the generator produces:
The generated code is complete and runnable without modification.
Every generated MCP server includes these baseline tools for repository exploration:
| Tool | Description | Parameters |
|---|---|---|
get_readme | Retrieve the repository's README content | None |
list_files | List files and directories at a given path | path (optional, defaults to root) |
read_file | Read the contents of a specific file | path (required) |
search_code | Search for patterns across the repository | query (required), path (optional) |
These tools ensure that even if no APIs or functions are detected, the AI assistant can still explore and understand the repository.
Additional tools are generated based on repository contents:
Each API endpoint becomes a tool:
POST /users → create_user(name: string, email: string)
GET /users/{id} → get_user(id: string)
PUT /users/{id} → update_user(id: string, name?: string, email?: string)
DELETE /users/{id} → delete_user(id: string)
GET /users → list_users(page?: number, limit?: number)
Queries and mutations become tools:
type Query {
user(id: ID!): User → get_user(id: string)
users(first: Int): [User] → list_users(first?: number)
}
type Mutation {
createUser(input: CreateUserInput!): User → create_user(input: object)
}
@server.tool()
async def analyze_sentiment(text: str) -> str:
"""Analyze the sentiment of the given text."""
# Implementation
Becomes: analyze_sentiment(text: string) → "Analyze the sentiment of the given text."
CLI commands documented in READMEs:
# Create a new project
mycli create --name myproject --template typescript
Becomes: mycli_create(name: string, template?: string)
| Variable | Description | Required |
|---|---|---|
GITHUB_TOKEN | GitHub personal access token for API access | No (but recommended) |
GITHUB_API_URL | Custom GitHub API URL for Enterprise | No |
Without a token, GitHub API requests are limited to 60 per hour. With a token, the limit increases to 5,000 per hour. For private repositories, a token with appropriate access is required.
Create a token at: https://github.com/settings/tokens
Required scopes:
repo (for private repositories)public_repo (for public repositories only)When using the programmatic API, you can configure:
const generator = new GithubToMcpGenerator({
// Authentication
githubToken: process.env.GITHUB_TOKEN,
// Extraction sources to enable
sources: ['openapi', 'readme', 'code', 'graphql', 'grpc', 'mcp'],
// Output configuration
outputLanguage: 'typescript', // or 'python', 'go'
// Tool filtering
includeUniversalTools: true,
maxTools: 100,
// Repository options
branch: 'main', // specific branch to analyze
});
Add the generated server to your Claude Desktop configuration:
| Platform | Config Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"my-repo": {
"command": "node",
"args": ["/absolute/path/to/generated/server.mjs"],
"env": {
"GITHUB_TOKEN": "ghp_xxxx"
}
}
}
}
⚠️ Restart Claude Desktop after modifying the configuration.
Cursor supports MCP servers through its settings. Add the server path in Cursor's MCP configuration panel, or edit the configuration file directly:
{
"mcp": {
"servers": {
"my-repo": {
"command": "node",
"args": ["/path/to/server.mjs"]
}
}
}
}
If using the Continue extension for VS Code:
{
"models": [...],
"mcpServers": {
"my-repo": {
"command": "node",
"args": ["/path/to/server.mjs"]
}
}
}
Any MCP-compatible client can use the generated servers. The server communicates over stdio by default, accepting JSON-RPC messages on stdin and responding on stdout.
To run manually:
node server.mjs
The server will wait for MCP protocol messages on stdin.
The web application includes an interactive playground for testing generated tools:
The playground executes tools in a sandboxed environment and displays results in real-time.
You can share your generated tools with others:
| Parameter | Description |
|---|---|
?code=<base64> | Base64-encoded TypeScript server code |
?gist=<id> | GitHub Gist ID containing server code |
?name=<name> | Display name for the server |
Example:
https://github-to-mcp.vercel.app/playground?gist=abc123&name=My%20API
github-to-mcp/
├── 📂 apps/
│ ├── 📂 web/ # Next.js web application
│ │ ├── 📂 app/ # Next.js App Router pages
│ │ │ ├── 📂 api/ # API routes for conversion
│ │ │ ├── 📂 convert/ # Conversion page
│ │ │ ├── 📂 playground/ # Interactive playground
│ │ │ └── 📂 dashboard/ # User dashboard
│ │ ├── 📂 components/ # React components
│ │ ├── 📂 hooks/ # Custom React hooks
│ │ ├── 📂 lib/ # Utility functions
│ │ └── 📂 types/ # TypeScript type definitions
│ └── 📂 vscode/ # VS Code extension (in development)
│
├── 📂 packages/
│ ├── 📂 core/ # Main conversion engine
│ │ └── 📂 src/
│ │ ├── index.ts # GithubToMcpGenerator class
│ │ ├── github-client.ts # GitHub API client
│ │ ├── readme-extractor.ts # README parsing
│ │ ├── code-extractor.ts # Source code analysis
│ │ ├── graphql-extractor.ts # GraphQL schema parsing
│ │ ├── mcp-introspector.ts # Existing MCP server detection
│ │ ├── python-generator.ts # Python output generation
│ │ ├── go-generator.ts # Go output generation
│ │ └── types.ts # Type definitions
│ │
│ ├── 📂 openapi-parser/ # OpenAPI specification parser
│ │ └── 📂 src/
│ │ ├── parser.ts # OpenAPI parsing logic
│ │ ├── analyzer.ts # Endpoint analysis
│ │ ├── transformer.ts # Schema transformation
│ │ └── generator.ts # Tool generation
│ │
│ ├── 📂 mcp-server/ # MCP server utilities
│ │ └── 📂 src/
│ │ ├── server.ts # Base MCP server implementation
│ │ └── tools.ts # Tool registration helpers
│ │
│ └── 📂 registry/ # Tool registry management
│ └── 📂 src/
│ └── index.ts # Registry operations
│
├── 📂 mkdocs/ # Documentation site (MkDocs)
│ ├── 📂 docs/ # Markdown documentation
│ └── mkdocs.yml # MkDocs configuration
│
├── 📂 tests/ # Integration tests
│ ├── 📂 fixtures/ # Test fixture repositories
│ │ ├── 📂 express-app/ # Express.js test app
│ │ ├── 📂 fastapi-app/ # FastAPI test app
│ │ ├── 📂 graphql/ # GraphQL test schemas
│ │ └── 📂 openapi/ # OpenAPI test specs
│ └── 📂 integration/ # Integration test files
│
├── 📂 templates/ # Code generation templates
│ ├── Dockerfile.python.template
│ └── Dockerfile.typescript.template
│
├── package.json # Root package configuration
├── pnpm-workspace.yaml # pnpm workspace configuration
├── tsconfig.json # TypeScript configuration
└── vitest.config.ts # Test configuration
| Requirement | Version |
|---|---|
| Node.js | 22.x or later |
| pnpm | 10.x or later |
| Git | 2.x or later |
# Clone the repository
git clone https://github.com/nirholas/github-to-mcp.git
cd github-to-mcp
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Start the development server
pnpm dev
The web application will be available at http://localhost:3000.
# Build all packages
pnpm build
# Build specific package
pnpm --filter @nirholas/github-to-mcp build
pnpm --filter @github-to-mcp/openapi-parser build
pnpm --filter web build
# Run all tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage
# Run specific test file
pnpm test -- tests/integration/openapi-conversion.test.ts
# Run linting
pnpm lint
# Type checking
pnpm typecheck
The system follows a pipeline architecture:
Input (GitHub URL)
│
▼
┌──────────────────┐
│ GitHub Client │ Fetches repository metadata, files, and README
└──────────────────┘
│
▼
┌──────────────────┐
│ Classifier │ Determines repository type and structure
└──────────────────┘
│
▼
┌──────────────────┐
│ Extractors │ Multiple extractors run in parallel:
│ ├─ OpenAPI │ • Parse API specifications
│ ├─ GraphQL │ • Parse GraphQL schemas
│ ├─ README │ • Extract examples from documentation
│ ├─ Code │ • Analyze source code
│ └─ MCP │ • Detect existing MCP tools
└──────────────────┘
│
▼
┌──────────────────┐
│ Deduplicator │ Removes duplicate tools, merges similar ones
└──────────────────┘
│
▼
┌──────────────────┐
│ Validator │ Validates tool schemas, adds confidence scores
└──────────────────┘
│
▼
┌──────────────────┐
│ Generator │ Produces output code in target language
└──────────────────┘
│
▼
Output (MCP Server Code + Configuration)
Each extractor produces a list of ExtractedTool objects with a standardized schema. The deduplicator and validator ensure consistency before the generator produces the final output.
| Format | File Patterns | Version Support |
|---|---|---|
| OpenAPI | openapi.json, openapi.yaml, swagger.json, swagger.yaml, api.json, api.yaml | 2.0, 3.0.x, 3.1.x |
| GraphQL | schema.graphql, *.gql, schema.json | June 2018 spec |
| gRPC | *.proto | proto3 |
| AsyncAPI | asyncapi.json, asyncapi.yaml | 2.x |
| Language | Framework Detection |
|---|---|
| TypeScript/JavaScript | Express, Fastify, Hono, Next.js API routes |
| Python | FastAPI, Flask, Django REST, MCP SDK decorators |
| Go | Gin, Echo, Chi, Fiber, Gorilla Mux |
| Java | Spring Boot, JAX-RS, Micronaut |
| Kotlin | Ktor, Spring Boot |
| Rust | Actix-web, Axum, Rocket |
| Ruby | Rails, Sinatra, Grape |
The default output is a TypeScript MCP server using the official @modelcontextprotocol/sdk package:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'generated-server',
version: '1.0.0',
}, {
capabilities: {
tools: {},
},
});
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [/* generated tools */],
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
// Tool dispatch logic
});
const transport = new StdioServerTransport();
await server.connect(transport);
Python output uses the MCP Python SDK:
from mcp.server import Server
from mcp.server.stdio import stdio_server
server = Server("generated-server")
@server.tool()
async def example_tool(param: str) -> str:
"""Tool description."""
# Implementation
async def main():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Each generated server includes:
| File | Description |
|---|---|
claude_desktop_config.json | Claude Desktop configuration snippet |
cursor_config.json | Cursor editor configuration |
package.json or requirements.txt | Dependencies |
Dockerfile (optional) | Container deployment |
Provide a GITHUB_TOKEN to increase rate limits.
Provide a GitHub token:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxx
repo scope--sources openapi,readme,code,graphql,mcpnpm install in the generated directorynpx tsc --noEmitclaude_desktop_config.json is absoluteContributions are welcome! Please see CONTRIBUTING.md for detailed guidelines on:
When reporting issues, please include:
Apache 2.0. See LICENSE for details.
| Resource | URL |
|---|---|
| 📖 Documentation | docs-github-to-mcp.vercel.app |
| 🌐 Web App | github-to-mcp.vercel.app |
| 📦 npm Package | npmjs.com/package/@nirholas/github-to-mcp |
| 🔗 MCP Specification | modelcontextprotocol.io |
| 📘 MCP TypeScript SDK | github.com/modelcontextprotocol/typescript-sdk |
| 🐍 MCP Python SDK | github.com/modelcontextprotocol/python-sdk |
| 💬 Discussions | github.com/nirholas/github-to-mcp/discussions |
Built by nich
FAQs
Convert any GitHub repository into an MCP server
We found that github-to-mcp-monorepo demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
The worm-enabled campaign hit @emilgroup and @teale.io, then used an ICP canister to deliver follow-on payloads.

Research
/Security News
Attackers compromised Trivy GitHub Actions by force-updating tags to deliver malware, exposing CI/CD secrets across affected pipelines.

Security News
ENISA’s new package manager advisory outlines the dependency security practices companies will need to demonstrate as the EU’s Cyber Resilience Act begins enforcing software supply chain requirements.