import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import express, { Request, Response } from "express";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
const server = new McpServer({
name: "git-scrapper",
version: "1.0.0",
});
// Build MCP server with tools
async function buildMcpServer() {
server.registerTool(
"get_repos",
{
title: "get github repository",
description: "get github repositories from a given username",
inputSchema: { username: z.string() },
},
async ({ username }:{username:string}) => {
const safeUsername = encodeURIComponent(username.trim());
const res = await fetch(
`https://api.github.com/users/${safeUsername}/repos`,
{ headers: { "User-Agent": "MCP-Server" } }
);
if (!res.ok) throw new Error(`Failed to fetch repositories: ${res.statusText}`);
const repos = await res.json();
const repoList = repos
.map((repo: any, i: number) => `${i + 1}. ${repo.name}`)
.join("\n\n");
return {
content: [
{
type: "text",
text: `github repos for ${username}: ${repos.length} repos:\n\n${repoList}`,
},
],
};
}
);
return server;
}
// Start HTTP MCP server
async function startHttp() {
const app = express();
app.use(express.json());
// Build MCP server once
const server = await buildMcpServer();
const transport = new StreamableHTTPServerTransport({ enableJsonResponse: true });
await server.connect(transport);
// Reuse transport for all requests
app.post("/mcp", async (req: Request, res: Response) => {
try {
await transport.handleRequest(req, res, req.body);
} catch (error) {
console.error("Error handling MCP request:", error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: "2.0",
error: { code: -32603, message: "Internal server error" },
id: null,
});
}
}
});
const port = Number(process.env.PORT || 3000);
app.listen(port, () => {
console.log(`HTTP MCP server listening on http://localhost:${port}/mcp`);
});
}
// Entry point
(async () => {
const mode = process.argv[2]; // "stdio" or "http"
if (mode === "stdio") {
const server = await buildMcpServer();
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP server (stdio) ready.");
} else {
await startHttp();
}
})();