GitHub MCP Server

Building a GitHub MCP Server

Let's build a practical MCP server that lets Claude interact with GitHub — list repos, create issues, and manage pull requests.
typescript
server.tool("list_repos", "List GitHub repositories", {
  username: z.string().describe("GitHub username"),
}, async ({ username }) => {
  const res = await fetch(`https://api.github.com/users/${username}/repos`);
  const repos = await res.json();
  const list = repos.map((r: any) => `- ${r.name}: ${r.description || "No description"}`);
  return { content: [{ type: "text", text: list.join("\n") }] };
});

server.tool("create_issue", "Create a GitHub issue", {
  owner: z.string(), repo: z.string(),
  title: z.string(), body: z.string().optional(),
}, async ({ owner, repo, title, body }) => {
  const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/issues`, {
    method: "POST",
    headers: { Authorization: `token ${process.env.GITHUB_TOKEN}`, "Content-Type": "application/json" },
    body: JSON.stringify({ title, body }),
  });
  const issue = await res.json();
  return { content: [{ type: "text", text: `Created issue #${issue.number}: ${issue.html_url}` }] };
});

Tip:Store API tokens in environment variables, never hardcode them. Pass them via the MCP server config in Claude Desktop.

PreviewTypeScriptRead Only
Copy this code and run it locally with npx tsx server.ts

💬 Got questions? Ask me anything!