A Model Context Protocol server for GitHub that provides tools to interact with GitHub repositories, issues, pull requests, users, code security, and secret scanning
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The GitHub MCP server has 47 tools with basic name conventions and descriptions, but significant quality gaps prevent a higher score. Tool names follow verb_noun patterns (get_me, search_repositories, create_issue), which is good. However, descriptions are inconsistent, many are terse (e.g., 'Search for repositories on GitHub' is only 33 chars, below the 50-char minimum for clarity). Most critically, parameter schemas are not visible in the provided source code. The sample code shows GetMe with a 'reason' parameter, but comprehensive schema documentation for all 47 tools cannot be verified. Without seeing the full schema definitions for parameters across all tools (input types, constraints, enums, required fields), schema quality cannot be assessed reliably. The codebase uses mcp-go framework and includes tool annotations (ReadOnlyHint visible in context_tools.go), which is positive. However, error handling in the sample (GetMe) returns generic error wrapping without actionable guidance for the LLM. The dynamic toolset system (enable_toolset, list_available_toolsets, get_toolset_tools) suggests architectural sophistication but adds cognitive load, agents must discover and enable tools rather than having them immediately available. Output schemas for most tools are undocumented in the visible code.
Input schemas not visible in source code for 44 of 47 tools. Only get_me shows explicit parameter definition (reason string). Cannot verify that all tools have proper JSON Schema with types, constraints, and required field declarations.
Extract complete input and output schemas for all 47 tools into visible source code. For each tool, explicitly define all parameters with type, required flag, description, and constraints (enum values, min/max for numbers, pattern for strings).
Expand terse descriptions to 50-150 characters. Example: 'Search for repositories on GitHub' → 'Search for GitHub repositories by name, language, stars, or other criteria. Returns repo name, URL, owner, description, and language. Use this to find projects before fetching details.'
Document output schema for every tool. Include example response JSON in code comments or separate schema file. Specify: return type (object/array), field names, field types, what IDs/references are available for chaining (e.g., if search_repositories returns repo_id, ensure create_pull_request accepts that repo_id).
Implement actionable error handling. Instead of 'failed to get user: unauthorized', return 'Authentication failed. Check that GITHUB_TOKEN is set and has user:email scope. If the token is valid, the account may lack the required permissions.'
Add confirmation step for destructive tools. Modify delete_file to accept confirm=false by default; return a confirmation_id. LLM must call delete_file with confirm=true and the confirmation_id to actually delete. Prevents accidental destruction.
Score history
Overall score trend
↓ 23 points across a rubric change (v1 → v2)
0/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
F
0
<=2025-11-25
v2
2026-03-09
F
23
-
v1
destructive
auth
enable_toolsetread onlysource verified
Enable one of the sets of tools the GitHub MCP server provides, use get_toolset_tools and list_available_toolsets first to see what this will enable
fork_repositorywriteauth
get_code_scanning_alertread onlyauth
get_commitread onlyauth
get_file_contentsread onlyauth
get_issueread onlyauth
get_issue_commentsread onlyauth
get_meread onlyauthsource verified
Get details of the authenticated GitHub user. Use this when a request includes "me", "my". The output will not change unless the user changes their profile, so only call this once.
get_pull_requestread onlyauth
get_pull_request_commentsread onlyauth
get_pull_request_diffread onlyauth
get_pull_request_filesread onlyauth
get_pull_request_reviewsread onlyauth
get_pull_request_statusread onlyauth
get_secret_scanning_alertread onlyauth
get_tagread onlyauth
get_toolset_toolsread onlysource verified
Lists all the capabilities that are enabled with the specified toolset, use this to get clarity on whether enabling a toolset would help you to complete a task
list_available_toolsetsread onlysource verified
List all available toolsets this GitHub MCP server can offer, providing the enabled status of each. Use this when a task could be achieved with a GitHub tool and the currently available tools aren't enough. Call get_toolset_tools with these toolset names to discover specific tools you can call
Tool names violate single-responsibility principle. 'create_and_submit_pull_request_review' and 'add_pull_request_review_comment_to_pending_review' combine multiple actions that should be separate. This forces LLMs to choose between doing both or neither, preventing flexible composition.
Output schemas undocumented across all tools in visible source. LLMs cannot determine what fields are returned, what IDs can be chained to subsequent calls, or how to extract relevant data. Critical for tool composition.
Error handling in GetMe (context_tools.go) returns generic wrapped errors without actionable guidance. 'failed to get user: {error}' does not tell the LLM whether the error is retryable, whether to try a different approach, or how to recover.
Descriptions are terse and below recommended minimum. Examples: 'Search for repositories on GitHub' (33 chars), 'List commits in a GitHub repository' (34 chars), 'List issues in a GitHub repository' (34 chars). Rubric baseline for A+ tools is 50-200 chars. These lack context for LLM tool selection.
Dynamic toolset system (enable_toolset, list_available_toolsets) requires agents to discover and enable tools before use. This adds friction, agents must make discovery calls, parse toolset names, and enable capabilities. Standard approach is to register all tools upfront and let agents select what they need.
Destructive tools (delete_file, delete_pending_pull_request_review, merge_pull_request) lack confirmation or dry-run support documented in descriptions. LLMs can make mistakes, irreversible operations should require explicit confirmation or support a dry-run pattern.
Document parameter constraints in descriptions. E.g., for list_issues: 'state must be one of: open, closed, all. Default: open. Limit: 1-100 results per page (default 20).'
Consider flattening the toolset discovery system. Instead of enable_toolset → list_available_toolsets → get_toolset_tools, pre-register all 47 tools and document in the server README which ones are available. Agents do not benefit from lazy-loading tools.
Add parameter descriptions for all non-obvious params. E.g., search_repositories likely accepts query, language, sort, order parameters, none of these are documented in visible source.
Validate inputs before calling GitHub API. Return descriptive errors: 'Invalid state: got "pending", must be open, closed, or all.' This lets LLMs self-correct in one retry instead of guessing.