
Read Github
Read GitHub repository documentation through gitmcp.io MCP servers via a Python CLI that normalizes owner/repo URLs.
Overview
Read GitHub is an agent skill most often used in Build (also Idea, Validate) that exposes GitHub repo documentation via gitmcp.io through a Python MCP CLI wrapper.
Install
npx skills add https://github.com/am-will/codex-skills --skill read-githubWhat is this skill?
- Converts github.com URLs and owner/repo paths to gitmcp.io endpoints
- Strips /tree, /blob, and other path segments so MCP sees owner/repo only
- Python CLI subprocess wrapper for invoking MCP-style doc reads
- Repo slug normalization (dashes to underscores) for generated tool names
- Bridges Codex-style agents to upstream GitHub README and doc content
Adoption & trust: 1.2k installs on skills.sh; 941 GitHub stars; 1/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent needs authoritative repo docs from GitHub but you do not want fragile HTML scraping or manual paste into every session.
Who is it for?
Solo builders using Codex or similar agents who rely on MCP and want quick doc ingestion from public GitHub repos.
Skip if: Private-repo access without proper MCP auth, local git operations, or teams that forbid outbound doc-fetch in security-sensitive environments.
When should I use this skill?
You need GitHub repository documentation exposed to an agent through gitmcp.io MCP rather than manual browsing.
What do I get? / Deliverables
You get normalized gitmcp.io URLs and a CLI path so agents can load upstream documentation through MCP while you integrate or evaluate repositories.
- Normalized gitmcp.io URL
- CLI invocation path for repo doc reads
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Agents most often invoke this while building or extending tooling that must pull live repo docs into context without manual copy-paste. Integrations is the canonical shelf because the skill wraps GitMCP MCP servers and URL conversion—not general Git workflows or PR automation.
Where it fits
Pull a competitor SDK README through GitMCP before deciding whether to depend on it.
Verify upstream install steps in the official repo docs while scoping an integration spike.
Wire your agent to read library docs on demand while implementing an API client.
How it compares
Doc-fetch bridge via GitMCP—not a full GitHub App, gh CLI replacement, or code-indexing MCP server.
Common Questions / FAQ
Who is read-github for?
Agent users who want programmatic access to public GitHub repository documentation through gitmcp.io from a small Python CLI in the codex-skills bundle.
When should I use read-github?
While integrating an MCP client during Build, when researching a library in Idea, or during Validate when comparing upstream README behavior before you commit to a dependency.
Is read-github safe to install?
It runs subprocess and network calls to external MCP endpoints; review the Security Audits panel on this page, vet gitmcp.io trust, and restrict use in repos with secrets on disk.
SKILL.md
READMESKILL.md - Read Github
#!/usr/bin/env python3 """ CLI wrapper for gitmcp.io MCP servers. Allows reading GitHub repository documentation via the GitMCP service. """ import argparse import json import subprocess import sys import re from typing import Optional def convert_github_to_gitmcp(url_or_path: str) -> str: """Convert a GitHub URL or owner/repo path to gitmcp.io URL.""" # Handle full GitHub URLs if "github.com" in url_or_path: url = url_or_path.replace("github.com", "gitmcp.io") # Strip /tree/..., /blob/..., /commits/..., etc. - gitmcp only needs owner/repo url = re.sub(r'/(tree|blob|commits|releases|issues|pull|actions|wiki|settings)/.*$', '', url) return url # Handle owner/repo format (possibly with extra path segments) if "/" in url_or_path and not url_or_path.startswith("http"): # Extract just owner/repo, strip any extra paths parts = url_or_path.split('/') if len(parts) >= 2: return f"https://gitmcp.io/{parts[0]}/{parts[1]}" return f"https://gitmcp.io/{url_or_path}" return url_or_path def get_repo_name_from_url(url: str) -> str: """Extract repo name from URL and convert to underscore format for tool names.""" # Extract owner/repo from URL pattern like https://gitmcp.io/owner/repo match = re.search(r'gitmcp\.io/([^/]+)/([^/]+)', url) if match: repo_name = match.group(2) # Convert dashes to underscores for tool names return repo_name.replace('-', '_') # Fallback: extract from owner/repo format match = re.search(r'^([^/]+)/([^/]+)', url) if match: repo_name = match.group(2) return repo_name.replace('-', '_') return "" def send_jsonrpc(proc: subprocess.Popen, method: str, params: dict = None, msg_id: int = 1) -> dict: """Send a JSON-RPC message and get response.""" request = { "jsonrpc": "2.0", "id": msg_id, "method": method, } if params: request["params"] = params message = json.dumps(request) + "\n" proc.stdin.write(message) proc.stdin.flush() # Read response response_line = proc.stdout.readline() if response_line: return json.loads(response_line) return {} def list_tools(mcp_url: str) -> dict: """Connect to MCP server and list available tools.""" proc = subprocess.Popen( ["npx", "-y", "mcp-remote", mcp_url], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 ) try: # Initialize init_response = send_jsonrpc(proc, "initialize", { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "gitmcp-cli", "version": "1.0.0"} }, 1) # Send initialized notification proc.stdin.write(json.dumps({"jsonrpc": "2.0", "method": "notifications/initialized"}) + "\n") proc.stdin.flush() # List tools tools_response = send_jsonrpc(proc, "tools/list", {}, 2) return tools_response finally: proc.terminate() def call_tool(mcp_url: str, tool_name: str, arguments: dict = None) -> dict: """Connect to MCP server and call a tool.""" proc = subprocess.Popen( ["npx", "-y", "mcp-remote", mcp_url], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 ) try: # Initialize send_jsonrpc(proc, "initialize", { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "gitmcp-cli", "version": "1.0.0"} }, 1) # Send initialized notification proc.stdin.write(json.dumps({"jsonrpc": "2.0", "method": "notifications/initialized"}) + "\n") proc.stdin.flush() # Call tool tool_response = send_jsonrpc(proc, "tools/call", { "name": tool_name,