Skip to main content
Glama
Productdeveloper5192

github-directory-mcp

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

  1. What is MCP

  2. How the protocol actually works

  3. Transports: stdio vs HTTP

  4. What this project does

  5. Project layout

  6. Setup from scratch

  7. Tool reference

  8. Accessing the server

  9. Troubleshooting

  10. Advanced: extending this server

  11. Security notes


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> -Force

Script

What it runs

npm run build

tsc — compiles src/index.tsdist/index.js

npm start

node dist/index.js — raw stdio server

npm run dev

build then start, in one step

npm run inspector

Launches MCP Inspector against the built server

npm run inspector:noauth

Same, with DANGEROUSLY_OMIT_AUTH=true (via cross-env, so it works on Windows too)

npm run register

claude mcp add github-directory -- node dist/index.js

npm run check-token

Hits GET /user with your GITHUB_TOKEN and prints the resolved account or the raw error


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.

list_github_repositories, list_github_directories

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 content

Every 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.js does.

  • 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 — calls GET /users/{owner}/repos (falling back to GET /orgs/{owner}/repos if that 404s), or GET /user/repos when owner is omitted and a token is set. Returns full_name, description, privacy/fork flags, and URL for each repo.

  • list_github_directories — calls GET /repos/{owner}/{repo}/contents/{path} for a shallow listing, or GET /repos/{owner}/{repo}/git/trees/{ref}?recursive=1 (filtered to type: "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 .env

Edit .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 build

This compiles src/index.tsdist/index.js via tsc. Re-run this any time you edit src/index.ts.


7. Tool reference

list_github_repositories

Param

Type

Required

Notes

owner

string

no

Username or org. Omit to list the authenticated user's own repos (needs GITHUB_TOKEN).

perPage

number 1-100

no

Default 30.

page

number

no

Default 1.

list_github_directories

Param

Type

Required

Notes

owner

string

yes

e.g. "anthropics". Must be non-empty (validated).

repo

string

yes

e.g. "claude-code". Must be non-empty (validated).

path

string

no

Default: repo root.

ref

string

no

Branch/tag/SHA. Default: repo's default branch.

recursive

boolean

no

Default false. true walks the entire tree via the Git Trees API.

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.js

This 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.

  1. Click Connect.

  2. Tools tab → List Tools.

  3. 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.js

C. Raw JSON-RPC over stdio (for scripting/debugging)

node dist/index.js

Feed it JSON-RPC lines on stdin, one per line — this is what's used internally to smoke-test the server. Example sequence: initializenotifications/initializedtools/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> -Force

claude: 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/user

A 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

  • .env holds a live GitHub token — it is git-ignored. Never commit it, never paste its contents into chat, issues, or logs.

  • Repository_token.txt is 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.

Install Server
F
license - not found
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

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