github-directory-mcp
Provides tools for listing GitHub repositories and directories, enabling AI agents to query GitHub user/organization repos and repo directory structures.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@github-directory-mcplist repositories for the user 'octocat'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
github-directory-mcp
An MCP (Model Context Protocol) server, written in TypeScript, that gives an AI assistant two tools for querying GitHub: listing a user/org's repositories, and listing the directories inside a repo.
This README covers MCP from first principles through to this project's internals, running it, and extending it.
Table of contents
Related MCP server: HTTP MCP Server
Quick command reference
Every command actually needed to build, run, register, and debug this server, in one place. Run
these from a normal terminal (VS Code integrated terminal or system PowerShell) in the project
folder, C:\Users\banda\OneDrive\Desktop\Mcp — not a sandboxed/CI shell.
These are wired up as real npm run scripts in package.json — not just copy-paste text:
# One-time setup
npm install
cp .env.example .env # then paste your GITHUB_TOKEN into .env
# Build (re-run after any src/index.ts edit)
npm run build
# Register with Claude Code (one-time; restart the session afterwards)
npm run register
# Manual visual testing via MCP Inspector
npm run inspector
# Same, but skip the session-token requirement (fixes stale-tab proxy errors)
npm run inspector:noauth
# Raw run (server just listens on stdio; used for scripted JSON-RPC testing)
npm start
# Verify GITHUB_TOKEN is valid
npm run check-token
# Find + stop whatever is holding the Inspector's ports (6274 UI / 6277 proxy)
netstat -ano | findstr "6274 6277"
Stop-Process -Id <PID> -ForceScript | What it runs |
|
|
|
|
| build then start, in one step |
| Launches MCP Inspector against the built server |
| Same, with |
|
|
| Hits |
1. What is MCP
Model Context Protocol is an open standard (created by Anthropic, now used across the industry) that defines a common way for an AI application — a chat client, an IDE assistant, an agent — to discover and call external capabilities, without every AI vendor and every tool vendor needing a custom integration for each other.
Before MCP: if you wanted Claude to talk to GitHub, Slack, a database, and a filesystem, someone had to write four bespoke integrations inside the AI application, each with its own auth handling, its own API shape, its own way of describing what it can do.
With MCP: each of those four things (GitHub, Slack, DB, filesystem) is wrapped in a small standalone program called an MCP server. Any MCP-compatible client (Claude Code, Claude Desktop, other agent frameworks) can talk to any MCP server using the same protocol. The server describes its own capabilities at connection time — the client doesn't need prior knowledge of what a "GitHub server" looks like.
The analogy people reach for is USB-C for AI: one physical/logical connector, many devices behind it, no per-device custom cable.
The three primitives MCP servers expose
Primitive | What it is | Example in this project |
Tools | Functions the model can call, with typed inputs/outputs. The model decides when to call them. |
|
Resources | Read-only data the client can attach to context (files, query results). Not used in this project. | — |
Prompts | Reusable prompt templates the server offers. Not used in this project. | — |
This project only implements tools, which is the most common case — "let the model call a function and get a result back."
2. How the protocol actually works
Under the hood, MCP is JSON-RPC 2.0 — a simple, transport-agnostic RPC format where every
message is a JSON object with a method, optional params, and an id to match requests to
responses.
A session looks like this:
Client Server (this project)
|--- initialize ------------------------->| client says "here's my protocol version/capabilities"
|<-- initialize result -------------------| server replies with its name/version/capabilities
|--- notifications/initialized ---------->| client confirms handshake is done
|
|--- tools/list -------------------------->| client asks "what tools do you have?"
|<-- tools/list result -------------------| server returns tool names + JSON Schema for each input
|
|--- tools/call (list_github_repositories)->| client invokes a tool with arguments
|<-- tools/call result --------------------| server runs it, returns text/structured contentEvery tool advertises an input schema (we use Zod to define it, which the SDK
converts to JSON Schema automatically). This is what lets the calling model know it must supply
owner and repo as strings for list_github_directories, for instance — the schema is enforced
before your tool code even runs (see src/index.ts's .min(1) validators, which reject empty
strings with a clear error instead of letting a malformed request reach the GitHub API).
3. Transports: stdio vs HTTP
MCP defines the message format (JSON-RPC) separately from the transport (how bytes physically move between client and server). Two transports matter in practice:
stdio (what this project uses): the client spawns your server as a child process and talks to it over its stdin/stdout. Zero networking, zero ports, zero auth needed — the client owns the process. This is the right choice for a local tool a single user runs on their own machine, which is what
claude mcp add ... -- node dist/index.jsdoes.Streamable HTTP: the server runs independently (its own process, possibly remote), and clients connect to it over HTTP. Needed when the server is shared, long-running, or not co-located with the client. Requires you to think about auth, since now it's a network-reachable service.
This project only implements stdio (see StdioServerTransport in src/index.ts). If you ever need
to expose it to multiple remote clients, that's the piece you'd swap out — the tool logic itself
wouldn't change.
4. What this project does
Two tools, both backed directly by the GitHub REST API (no
GitHub SDK dependency — just fetch):
list_github_repositories— callsGET /users/{owner}/repos(falling back toGET /orgs/{owner}/reposif that 404s), orGET /user/reposwhenowneris omitted and a token is set. Returnsfull_name, description, privacy/fork flags, and URL for each repo.list_github_directories— callsGET /repos/{owner}/{repo}/contents/{path}for a shallow listing, orGET /repos/{owner}/{repo}/git/trees/{ref}?recursive=1(filtered totype: "tree") for a full recursive directory walk.
Both accept an optional GITHUB_TOKEN (read from .env via dotenv) which is sent as a
Bearer token — required for your own private repos / own-account listing, and generally useful to
avoid GitHub's 60 req/hour unauthenticated rate limit (jumps to 5000 req/hour authenticated).
5. Project layout
Mcp/
├── src/index.ts Server source: tool definitions, GitHub API calls, stdio bootstrap
├── dist/index.js Compiled output — this is what actually gets executed
├── .env Your real GITHUB_TOKEN (git-ignored, never commit)
├── .env.example Template for .env (safe to commit)
├── .gitignore Excludes node_modules/, dist/, .env, Repository_token.txt
├── repositories.txt A saved snapshot of a list_github_repositories run
├── package.json Scripts: build (tsc), start, dev
└── tsconfig.json TypeScript compiler config (NodeNext modules, ES2022 target)6. Setup from scratch
Requirements: Node.js 18+ (this was built and tested on Node 25).
cd "C:\Users\banda\OneDrive\Desktop\Mcp"
npm install
cp .env.example .envEdit .env and paste in a GitHub token:
GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxxxxxxxx(Generate one at github.com → Settings → Developer settings → Personal access tokens. Fine-grained, read-only "Contents" + "Metadata" repo permissions are enough for these two tools.)
Build:
npm run buildThis compiles src/index.ts → dist/index.js via tsc. Re-run this any time you edit src/index.ts.
7. Tool reference
list_github_repositories
Param | Type | Required | Notes |
| string | no | Username or org. Omit to list the authenticated user's own repos (needs |
| number 1-100 | no | Default 30. |
| number | no | Default 1. |
list_github_directories
Param | Type | Required | Notes |
| string | yes | e.g. |
| string | yes | e.g. |
| string | no | Default: repo root. |
| string | no | Branch/tag/SHA. Default: repo's default branch. |
| boolean | no | Default false. |
Note: both owner and repo must actually be provided — if you ask something vague like "list
my repo's directories" without naming a repo, the calling model may send empty strings, which now
fails fast with a validation error instead of silently hitting a malformed GitHub URL.
8. Accessing the server
There are two ways to actually use this server, depending on your goal.
A. Through Claude Code (the real use case)
Register it once, from a normal terminal (not a sandboxed/CI one):
claude mcp add github-directory -- node "C:\Users\banda\OneDrive\Desktop\Mcp\dist\index.js"Restart your Claude Code session (MCP servers load at session start), then just ask, naming the repo explicitly:
"List directories in Productdeveloper5192/MCP" "List my github repositories"
Claude reads the tool schemas via tools/list, decides when a request warrants calling one, and
calls it via tools/call — all of that JSON-RPC exchange happens invisibly.
B. MCP Inspector (manual/visual testing, no client needed)
npx @modelcontextprotocol/inspector node dist/index.jsThis starts two things: a proxy on port 6277 (bridges the browser to your stdio process) and a UI on port 6274. It prints a URL with a session token baked in — open that exact URL.
Click Connect.
Tools tab → List Tools.
Pick a tool, fill the form, Run Tool.
If you keep hitting "Error Connecting to MCP Inspector Proxy" from stale browser tabs/tokens, skip the token entirely for local testing:
$env:DANGEROUSLY_OMIT_AUTH="true"
npx @modelcontextprotocol/inspector node dist/index.jsC. Raw JSON-RPC over stdio (for scripting/debugging)
node dist/index.jsFeed it JSON-RPC lines on stdin, one per line — this is what's used internally to smoke-test the
server. Example sequence: initialize → notifications/initialized → tools/call.
9. Troubleshooting
GitHub API 404 for /repos//
owner/repo were empty when the tool was called — usually because the prompt to Claude didn't
name a specific repo. Now blocked at the schema level with a clear validation error instead (see
.min(1) in src/index.ts). Name the repo explicitly in your prompt.
"Error Connecting to MCP Inspector Proxy" The Inspector mints a new session token every time it starts. This almost always means an old browser tab is using a stale token from a previous run. Close all old Inspector tabs and open the exact URL (with token) printed by the current run.
MCP Inspector PORT IS IN USE at http://localhost:6274
A leftover node process from a prior Inspector run is still holding the port. Find and stop it:
netstat -ano | findstr 6274
Stop-Process -Id <PID> -Forceclaude: command not found
You're not in a terminal where Claude Code's CLI is on PATH — use VS Code's integrated terminal or
your normal system terminal, not a restricted/sandboxed shell.
Rate limited / can't see private repos / owner omitted fails
Check GITHUB_TOKEN is actually set in .env and non-empty. Verify it directly:
curl -H "Authorization: Bearer $env:GITHUB_TOKEN" https://api.github.com/userA 200 with your account info confirms the token is valid.
10. Advanced: extending this server
To add a new tool, follow the pattern already in src/index.ts:
server.registerTool(
"your_tool_name",
{
title: "Human-readable title",
description: "What it does — this is what the model reads to decide when to call it.",
inputSchema: {
someParam: z.string().min(1).describe("Shown to the model as field docs"),
},
},
async ({ someParam }) => {
// ... do work, call APIs, etc.
return { content: [{ type: "text", text: "result" }] };
}
);Ideas in scope for this GitHub-focused server: list branches, list commits on a path, search code,
read a single file's content, list pull requests. Each is one more githubFetch call plus one more
registerTool block — no architectural changes needed.
If you ever need this reachable by more than one local client (e.g. a shared team server), swap
StdioServerTransport for the SDK's Streamable HTTP transport — at that point also add real auth in
front of it, since it stops being "only reachable by whoever can spawn the process" and becomes a
network service.
11. Security notes
.envholds a live GitHub token — it is git-ignored. Never commit it, never paste its contents into chat, issues, or logs.Repository_token.txtis also git-ignored as a safety net, but the token has already been moved into.env— that plaintext file is redundant and can be deleted.Fine-grained PATs scoped to only the repos/permissions you need are safer than classic PATs with broad scopes — regenerate and re-scope if the current token was created broadly.
This server only ever reads from GitHub (no write/delete endpoints are implemented), so the blast radius of a leaked token is limited to whatever that token itself can do on your account — treat it with the same care as a password.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Productdeveloper5192/MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server