Summary
The GitHub guard's tool classification (tools.rs) is comprehensive — all 102 tools currently exposed by github-mcp-server are correctly classified as write, read-write, or read. However, 34 write/mutating tools have no explicit match arm in apply_tool_labels (tool_rules.rs) and fall through to the _ => { // Default: inherit provided labels } case. This means their secrecy tags and integrity levels are inherited from caller-provided labels rather than being explicitly enforced, which can produce incorrect DIFC labeling for repo-scoped writes.
- MCP tools scanned: 102 (from
pkg/github/__toolsnaps__/ on main)
- CLI write commands scanned: ~45 (all major write groups in
pkg/cmd/)
- Guard-covered write tools (tools.rs): 60 in
WRITE_OPERATIONS + 30 in READ_WRITE_OPERATIONS
- Tools with explicit DIFC rules (tool_rules.rs): ~68 match arms (covering ~38 tool names from upstream)
- Classification gaps (tools.rs): 0 — all upstream tools are correctly classified ✅
- New DIFC labeling gaps (tool_rules.rs): 34 — write/mutating tools fall through to default
MCP Tool Classification Gaps (tools.rs)
None. All 102 upstream MCP tools are correctly classified. ✅
MCP Tool DIFC Labeling Gaps (tool_rules.rs)
These 34 write/mutating MCP tools exist in the upstream server, are correctly classified in tools.rs, but have no explicit match arm in apply_tool_labels. They fall through to _ => { // Default: inherit provided labels }, meaning secrecy and integrity are not explicitly enforced.
High-priority (repo-scoped writes, high risk)
| Tool Name |
Classification |
Data Scope |
Risk |
merge_pull_request |
READ_WRITE |
repo-scoped |
High — irreversible code merge; should enforce writer_integrity(repo_id) |
create_pull_request |
WRITE |
repo-scoped |
High — creates a PR targeting a branch; should enforce repo-scoped secrecy + writer integrity |
fork_repository |
WRITE |
user-scoped |
Medium — creates a fork under a user/org; should set user-scoped labels |
create_repository |
WRITE |
user-scoped |
Medium — creates a new repo; should set user-scoped labels |
update_pull_request_branch |
READ_WRITE |
repo-scoped |
Medium — updates PR branch (git write); should enforce repo-scoped labels |
PR review operations (PR-scoped)
| Tool Name |
Classification |
Notes |
pull_request_review_write |
READ_WRITE |
Composite review write; no label arm |
add_comment_to_pending_review |
WRITE |
Adds to pending review |
add_pull_request_review_comment |
READ_WRITE |
Posts inline review comment |
add_reply_to_pull_request_comment |
WRITE |
Replies to review thread |
create_pull_request_review |
READ_WRITE |
Creates a review |
delete_pending_pull_request_review |
READ_WRITE |
Deletes pending review |
request_pull_request_reviewers |
READ_WRITE |
Requests reviewers |
resolve_review_thread |
READ_WRITE |
Resolves a review thread |
submit_pending_pull_request_review |
READ_WRITE |
Submits the review |
unresolve_review_thread |
READ_WRITE |
Unresolves a thread |
Granular PR update tools (PR-scoped)
| Tool Name |
Classification |
Notes |
update_pull_request |
READ_WRITE |
General PR update |
update_pull_request_body |
READ_WRITE |
Updates PR description |
update_pull_request_draft_state |
READ_WRITE |
Converts to/from draft |
update_pull_request_state |
READ_WRITE |
Opens/closes PR |
update_pull_request_title |
READ_WRITE |
Updates PR title |
Sub-issue tools (issue-scoped)
| Tool Name |
Classification |
Notes |
add_sub_issue |
READ_WRITE |
Adds sub-issue link |
remove_sub_issue |
READ_WRITE |
Removes sub-issue link |
reprioritize_sub_issue |
READ_WRITE |
Reorders sub-issues |
set_issue_fields |
READ_WRITE |
Sets custom field values on an issue |
Granular issue update tools (issue-scoped)
| Tool Name |
Classification |
Notes |
update_issue_body |
READ_WRITE |
Updates issue description |
update_issue_labels |
READ_WRITE |
Updates issue labels |
update_issue_milestone |
READ_WRITE |
Updates issue milestone |
update_issue_state |
READ_WRITE |
Opens/closes issue |
update_issue_title |
READ_WRITE |
Updates issue title |
update_issue_type |
READ_WRITE |
Updates issue type |
Notification management (notification/repo-scoped)
| Tool Name |
Classification |
Notes |
dismiss_notification |
WRITE |
Dismisses a notification |
manage_notification_subscription |
WRITE |
Subscribe/unsubscribe to a thread |
manage_repository_notification_subscription |
WRITE |
Subscribe/unsubscribe to a repo |
mark_all_notifications_read |
WRITE |
Marks all notifications read |
Suggested fixes for tool_rules.rs
Add explicit match arms for each group. Follow the pattern of existing similar tools:
// === PR merge (high-risk: irreversible code write) ===
"merge_pull_request" => {
// Merging a PR writes code to the target branch.
// S = S(repo); I = writer(repo)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === PR creation / update (repo-scoped writes) ===
"create_pull_request" | "update_pull_request" | "update_pull_request_body"
| "update_pull_request_title" | "update_pull_request_state"
| "update_pull_request_draft_state" | "update_pull_request_branch" => {
// PR writes are repo-scoped.
// S = S(repo); I = writer(repo)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === PR review operations (PR-scoped writes) ===
"pull_request_review_write"
| "add_comment_to_pending_review"
| "add_pull_request_review_comment"
| "add_reply_to_pull_request_comment"
| "create_pull_request_review"
| "delete_pending_pull_request_review"
| "request_pull_request_reviewers"
| "resolve_review_thread" | "unresolve_review_thread"
| "submit_pending_pull_request_review" => {
// PR review writes are repo-scoped.
// S = S(repo); I = writer(repo)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === Repository creation / fork (user-scoped writes) ===
"create_repository" | "fork_repository" => {
// Creating or forking a repo is user-scoped.
// S = public (no private data in response); I = writer(github)
baseline_scope = "github".to_string();
integrity = writer_integrity("github", ctx);
}
// === Granular issue updates (issue-scoped writes) ===
"update_issue_body" | "update_issue_labels" | "update_issue_milestone"
| "update_issue_state" | "update_issue_title" | "update_issue_type" => {
// Issue field updates are repo-scoped writes.
// S = S(repo); I = writer(repo)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === Sub-issue management (issue-scoped writes) ===
"add_sub_issue" | "remove_sub_issue" | "reprioritize_sub_issue" | "set_issue_fields" => {
// Sub-issue writes are repo-scoped.
// S = S(repo); I = writer(repo)
secrecy = apply_repo_visibility_secrecy(&owner, &repo, repo_id, secrecy, ctx);
integrity = writer_integrity(repo_id, ctx);
}
// === Notification management (notification-scoped) ===
"dismiss_notification" | "manage_notification_subscription"
| "manage_repository_notification_subscription" | "mark_all_notifications_read" => {
// Notification management; response carries no repo-sensitive data.
// S = public (empty); I = project:github
secrecy = vec![];
baseline_scope = "github".to_string();
integrity = project_github_label(ctx);
}
GitHub CLI-Only Gaps
None found. All major GitHub CLI write operations (gh pr, gh issue, gh repo, gh gist, gh release, gh workflow, gh run, gh label, gh project, gh secret, gh variable) have corresponding entries in WRITE_OPERATIONS or READ_WRITE_OPERATIONS (including pre-emptive entries). ✅
Stale Guard Entries (bonus)
No stale entries. Pre-emptive entries in tools.rs (e.g., archive_repository, enable_workflow, set_secret) are intentional forward-looking entries, not stale — they are explicitly annotated as such. ✅
References
Generated by GitHub Guard Coverage Checker (MCP + CLI) · ● 1.3M · ◷
Summary
The GitHub guard's tool classification (
tools.rs) is comprehensive — all 102 tools currently exposed by github-mcp-server are correctly classified as write, read-write, or read. However, 34 write/mutating tools have no explicit match arm inapply_tool_labels(tool_rules.rs) and fall through to the_ => { // Default: inherit provided labels }case. This means their secrecy tags and integrity levels are inherited from caller-provided labels rather than being explicitly enforced, which can produce incorrect DIFC labeling for repo-scoped writes.pkg/github/__toolsnaps__/onmain)pkg/cmd/)WRITE_OPERATIONS+ 30 inREAD_WRITE_OPERATIONSMCP Tool Classification Gaps (tools.rs)
None. All 102 upstream MCP tools are correctly classified. ✅
MCP Tool DIFC Labeling Gaps (tool_rules.rs)
These 34 write/mutating MCP tools exist in the upstream server, are correctly classified in
tools.rs, but have no explicit match arm inapply_tool_labels. They fall through to_ => { // Default: inherit provided labels }, meaning secrecy and integrity are not explicitly enforced.High-priority (repo-scoped writes, high risk)
merge_pull_requestwriter_integrity(repo_id)create_pull_requestfork_repositorycreate_repositoryupdate_pull_request_branchPR review operations (PR-scoped)
pull_request_review_writeadd_comment_to_pending_reviewadd_pull_request_review_commentadd_reply_to_pull_request_commentcreate_pull_request_reviewdelete_pending_pull_request_reviewrequest_pull_request_reviewersresolve_review_threadsubmit_pending_pull_request_reviewunresolve_review_threadGranular PR update tools (PR-scoped)
update_pull_requestupdate_pull_request_bodyupdate_pull_request_draft_stateupdate_pull_request_stateupdate_pull_request_titleSub-issue tools (issue-scoped)
add_sub_issueremove_sub_issuereprioritize_sub_issueset_issue_fieldsGranular issue update tools (issue-scoped)
update_issue_bodyupdate_issue_labelsupdate_issue_milestoneupdate_issue_stateupdate_issue_titleupdate_issue_typeNotification management (notification/repo-scoped)
dismiss_notificationmanage_notification_subscriptionmanage_repository_notification_subscriptionmark_all_notifications_readSuggested fixes for tool_rules.rs
Add explicit match arms for each group. Follow the pattern of existing similar tools:
GitHub CLI-Only Gaps
None found. All major GitHub CLI write operations (
gh pr,gh issue,gh repo,gh gist,gh release,gh workflow,gh run,gh label,gh project,gh secret,gh variable) have corresponding entries inWRITE_OPERATIONSorREAD_WRITE_OPERATIONS(including pre-emptive entries). ✅Stale Guard Entries (bonus)
No stale entries. Pre-emptive entries in
tools.rs(e.g.,archive_repository,enable_workflow,set_secret) are intentional forward-looking entries, not stale — they are explicitly annotated as such. ✅References