github-agent 1.1.1__tar.gz → 1.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. {github_agent-1.1.1 → github_agent-1.4.1}/PKG-INFO +15 -5
  2. {github_agent-1.1.1 → github_agent-1.4.1}/README.md +14 -4
  3. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/agent_server.py +1 -1
  4. github_agent-1.4.1/github_agent/api/api_client_dependabot.py +98 -0
  5. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api_client.py +2 -0
  6. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/kg_ingest.py +122 -1
  7. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/__init__.py +2 -0
  8. github_agent-1.4.1/github_agent/mcp/mcp_dependabot.py +172 -0
  9. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp_server.py +253 -0
  10. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/ontology/github.ttl +83 -0
  11. github_agent-1.4.1/github_agent/skills/github-backlog-planner/SKILL.md +113 -0
  12. github_agent-1.4.1/github_agent/skills/github-backlog-planner/references/addressed-heuristics.md +59 -0
  13. github_agent-1.4.1/github_agent/skills/github-backlog-planner/scripts/build_plan.py +178 -0
  14. github_agent-1.4.1/github_agent/skills/github-ci-failure-sweep/SKILL.md +111 -0
  15. github_agent-1.4.1/github_agent/skills/github-ci-failure-sweep/references/actions-tool-cheatsheet.md +60 -0
  16. github_agent-1.4.1/github_agent/skills/github-ci-failure-sweep/scripts/summarize_runs.py +156 -0
  17. github_agent-1.4.1/github_agent/skills/github-dependabot-review/SKILL.md +103 -0
  18. github_agent-1.4.1/github_agent/skills/github-org-remediation-loop/SKILL.md +295 -0
  19. github_agent-1.4.1/github_agent/skills/github-org-remediation-loop/scripts/classify_fix_risk.py +169 -0
  20. github_agent-1.4.1/github_agent/skills/github-pr-review-sweep/SKILL.md +112 -0
  21. github_agent-1.4.1/github_agent/skills/github-pr-review-sweep/references/pulls-tool-cheatsheet.md +42 -0
  22. github_agent-1.4.1/github_agent/skills/github-pr-review-sweep/scripts/summarize_prs.py +171 -0
  23. github_agent-1.4.1/github_agent/skills/github-project-provisioner/SKILL.md +58 -0
  24. github_agent-1.4.1/github_agent/skills/github-project-provisioner/scripts/enable_pages.py +53 -0
  25. github_agent-1.4.1/github_agent/skills/github-tools/SKILL.md +152 -0
  26. github_agent-1.4.1/github_agent/skills/github-tools/code-reviewer.md +146 -0
  27. github_agent-1.4.1/github_agent/skills/github-tools/scripts/fetch_comments.py +249 -0
  28. github_agent-1.4.1/github_agent/skills/github-tools/scripts/inspect_pr_checks.py +532 -0
  29. github_agent-1.4.1/github_agent/skills/github-triage-resolver/SKILL.md +116 -0
  30. github_agent-1.4.1/github_agent/skills/github-triage-resolver/references/resolution-rules.md +64 -0
  31. github_agent-1.4.1/github_agent/skills/github-triage-resolver/scripts/classify_safe.py +212 -0
  32. github_agent-1.4.1/github_agent/skills/github-triage-resolver/scripts/gh_write.py +131 -0
  33. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/PKG-INFO +15 -5
  34. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/SOURCES.txt +24 -0
  35. {github_agent-1.1.1 → github_agent-1.4.1}/pyproject.toml +1 -1
  36. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_kg_ingest.py +95 -0
  37. {github_agent-1.1.1 → github_agent-1.4.1}/LICENSE +0 -0
  38. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/__init__.py +0 -0
  39. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/__main__.py +0 -0
  40. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/__init__.py +0 -0
  41. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_base.py +0 -0
  42. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_branches.py +0 -0
  43. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_commits.py +0 -0
  44. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_contents.py +0 -0
  45. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_issues.py +0 -0
  46. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_orgs.py +0 -0
  47. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_pages.py +0 -0
  48. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_pulls.py +0 -0
  49. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_releases.py +0 -0
  50. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_repos.py +0 -0
  51. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_search.py +0 -0
  52. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/api/api_client_workflows.py +0 -0
  53. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/auth.py +0 -0
  54. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/connectors/__init__.py +0 -0
  55. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/connectors/mcp_source_presets.json +0 -0
  56. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/github_gql.py +0 -0
  57. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/github_input_models.py +0 -0
  58. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/github_response_models.py +0 -0
  59. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_action.py +0 -0
  60. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_branch.py +0 -0
  61. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_collaborator.py +0 -0
  62. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_commit.py +0 -0
  63. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_content.py +0 -0
  64. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_issue.py +0 -0
  65. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_org.py +0 -0
  66. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_pull.py +0 -0
  67. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_release.py +0 -0
  68. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_repo.py +0 -0
  69. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp/mcp_search.py +0 -0
  70. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/mcp_config.json +0 -0
  71. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/ontology/__init__.py +0 -0
  72. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/prompts/__init__.py +0 -0
  73. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/prompts/code_collaboration_specialist.json +0 -0
  74. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/prompts/main_agent.json +0 -0
  75. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/__init__.py +0 -0
  76. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/github-actions-ci-review/SKILL.md +0 -0
  77. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/github-issue-tracking/SKILL.md +0 -0
  78. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/github-pull-request-create/SKILL.md +0 -0
  79. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/github-pull-request-review/SKILL.md +0 -0
  80. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent/skills/github-repository-management/SKILL.md +0 -0
  81. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/dependency_links.txt +0 -0
  82. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/entry_points.txt +0 -0
  83. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/requires.txt +0 -0
  84. {github_agent-1.1.1 → github_agent-1.4.1}/github_agent.egg-info/top_level.txt +0 -0
  85. {github_agent-1.1.1 → github_agent-1.4.1}/scripts/security_sanitizer.py +0 -0
  86. {github_agent-1.1.1 → github_agent-1.4.1}/scripts/validate_a2a_agent.py +0 -0
  87. {github_agent-1.1.1 → github_agent-1.4.1}/scripts/verify_api_integration.py +0 -0
  88. {github_agent-1.1.1 → github_agent-1.4.1}/setup.cfg +0 -0
  89. {github_agent-1.1.1 → github_agent-1.4.1}/tests/conftest.py +0 -0
  90. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_action_discovery.py +0 -0
  91. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_api_client_endpoints.py +0 -0
  92. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_api_validation.py +0 -0
  93. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_auth_client_edge_cases.py +0 -0
  94. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_concept_parity.py +0 -0
  95. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_github_agent_api_brute_force_coverage.py +0 -0
  96. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_github_agent_brute_force_coverage.py +0 -0
  97. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_github_gql.py +0 -0
  98. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_hardening.py +0 -0
  99. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_init_dynamics.py +0 -0
  100. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_mcp_coverage.py +0 -0
  101. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_model_fields.py +0 -0
  102. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_org_crud.py +0 -0
  103. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_pages.py +0 -0
  104. {github_agent-1.1.1 → github_agent-1.4.1}/tests/test_startup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-agent
3
- Version: 1.1.1
3
+ Version: 1.4.1
4
4
  Summary: GitHub Agent for MCP
5
5
  Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
6
  License: MIT
@@ -48,7 +48,7 @@ Dynamic: license-file
48
48
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
49
49
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
50
50
 
51
- *Version: 1.1.1*
51
+ *Version: 1.4.1*
52
52
 
53
53
  > **Documentation** — Installation, deployment, and usage across the MCP, API, and
54
54
  > CLI interfaces, including the integrated A2A agent server, are maintained in the
@@ -98,8 +98,10 @@ _Auto-generated from the live MCP server — do not edit by hand._
98
98
  | `github_collaborators` | `COLLABORATORTOOL` | Manage repository collaborators. |
99
99
  | `github_commits` | `COMMITTOOL` | Manage GitHub commits. |
100
100
  | `github_contents` | `CONTENTTOOL` | Manage GitHub contents. |
101
+ | `github_dependabot` | `DEPENDABOTTOOL` | Review and manage GitHub Dependabot vulnerability alerts. |
101
102
  | `github_discover_graphql_schema` | `GRAPHQLTOOL` | Discover the live GitHub GraphQL schema (types, fields, and attributes) in real-time. |
102
103
  | `github_graphql` | `GRAPHQLTOOL` | Execute raw GraphQL queries and mutations natively on GitHub. |
104
+ | `github_ingest_pipelines` | `INGESTTOOL` | Natively ingest GitHub Actions workflow runs into epistemic-graph. |
103
105
  | `github_ingest_repos` | `INGESTTOOL` | Natively ingest GitHub repositories into epistemic-graph as typed :Repository nodes. |
104
106
  | `github_issues` | `ISSUETOOL` | Manage GitHub issues. |
105
107
  | `github_orgs` | `ORGTOOL` | Manage GitHub organizations. |
@@ -111,7 +113,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
111
113
  #### Verbose 1:1 API-mapped tools (`MCP_TOOL_MODE=verbose` or `both`)
112
114
 
113
115
  <details>
114
- <summary>72 per-operation tools — one per public API method (click to expand)</summary>
116
+ <summary>76 per-operation tools — one per public API method (click to expand)</summary>
115
117
 
116
118
  | MCP Tool | Toggle Env Var | Description |
117
119
  |----------|----------------|-------------|
@@ -144,8 +146,11 @@ _Auto-generated from the live MCP server — do not edit by hand._
144
146
  | `github_get_commit` | `APITOOL` | Get a single commit in a repository. |
145
147
  | `github_get_commits` | `APITOOL` | List commits for a repository. |
146
148
  | `github_get_contents` | `APITOOL` | Get contents of a file or directory in a repository. |
149
+ | `github_get_dependabot_alert` | `APITOOL` | Get a single Dependabot alert. |
150
+ | `github_get_dependabot_alerts` | `APITOOL` | List Dependabot alerts for a repository. |
147
151
  | `github_get_issue` | `APITOOL` | Get a single issue in a repository. |
148
152
  | `github_get_issues` | `APITOOL` | List issues for a repository. |
153
+ | `github_get_org_dependabot_alerts` | `APITOOL` | List Dependabot alerts for an entire organization. |
149
154
  | `github_get_org_members` | `APITOOL` | List members for an organization. |
150
155
  | `github_get_org_repos` | `APITOOL` | List repositories for an organization. |
151
156
  | `github_get_org_teams` | `APITOOL` | List teams for an organization. |
@@ -181,6 +186,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
181
186
  | `github_trigger_workflow_dispatch` | `APITOOL` | Trigger a workflow dispatch event. |
182
187
  | `github_update_branch_protection` | `APITOOL` | Update branch protection configuration. |
183
188
  | `github_update_content` | `APITOOL` | Update a file in a repository. |
189
+ | `github_update_dependabot_alert` | `APITOOL` | Update the state of a Dependabot alert. |
184
190
  | `github_update_issue` | `APITOOL` | Update an issue in a repository. |
185
191
  | `github_update_organization` | `APITOOL` | Update an organization's profile and member settings. |
186
192
  | `github_update_pages` | `APITOOL` | Update the GitHub Pages configuration for a repository. |
@@ -190,7 +196,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
190
196
 
191
197
  </details>
192
198
 
193
- _14 action-routed tool(s) (default) · 72 verbose 1:1 tool(s). Each is enabled unless its `<DOMAIN>TOOL` toggle is set false; `MCP_TOOL_MODE` selects the surface (`condensed` default · `verbose` 1:1 · `both`). Auto-generated — do not edit._
199
+ _16 action-routed tool(s) (default) · 76 verbose 1:1 tool(s). Each is enabled unless its `<DOMAIN>TOOL` toggle is set false; `MCP_TOOL_MODE` selects the surface (`condensed` default · `verbose` 1:1 · `both`). Auto-generated — do not edit._
194
200
  <!-- MCP-TOOLS-TABLE:END -->
195
201
 
196
202
  Detailed tool schemas, parameter shapes, and validation constraints are preserved in [docs/mcp.md](docs/mcp.md).
@@ -245,6 +251,7 @@ When query strings or parameters are supplied, an LLM-free **Knowledge Graph res
245
251
  "COLLABORATORTOOL": "True",
246
252
  "COMMITTOOL": "True",
247
253
  "CONTENTTOOL": "True",
254
+ "DEPENDABOTTOOL": "True",
248
255
  "GITHUB_ALLOW_DESTRUCTIVE": "False",
249
256
  "GITHUB_HTTP_CONNECT_TIMEOUT": "10",
250
257
  "GITHUB_HTTP_READ_TIMEOUT": "30",
@@ -291,6 +298,7 @@ When query strings or parameters are supplied, an LLM-free **Knowledge Graph res
291
298
  "COLLABORATORTOOL": "True",
292
299
  "COMMITTOOL": "True",
293
300
  "CONTENTTOOL": "True",
301
+ "DEPENDABOTTOOL": "True",
294
302
  "GITHUB_ALLOW_DESTRUCTIVE": "False",
295
303
  "GITHUB_HTTP_CONNECT_TIMEOUT": "10",
296
304
  "GITHUB_HTTP_READ_TIMEOUT": "30",
@@ -338,6 +346,7 @@ docker run -d \
338
346
  -e COLLABORATORTOOL=True \
339
347
  -e COMMITTOOL=True \
340
348
  -e CONTENTTOOL=True \
349
+ -e DEPENDABOTTOOL=True \
341
350
  -e GITHUB_ALLOW_DESTRUCTIVE=False \
342
351
  -e GITHUB_HTTP_CONNECT_TIMEOUT=10 \
343
352
  -e GITHUB_HTTP_READ_TIMEOUT=30 \
@@ -408,6 +417,7 @@ consumed from a **remote deployment**. The
408
417
  | `COLLABORATORTOOL` | `True` | |
409
418
  | `COMMITTOOL` | `True` | |
410
419
  | `CONTENTTOOL` | `True` | |
420
+ | `DEPENDABOTTOOL` | `True` | |
411
421
  | `GRAPHQLTOOL` | `True` | |
412
422
  | `INGESTTOOL` | `True` | |
413
423
  | `ISSUETOOL` | `True` | |
@@ -434,7 +444,7 @@ consumed from a **remote deployment**. The
434
444
  | `MODEL_ID` | `gpt-4o` | Model id for the agent |
435
445
  | `ENABLE_WEB_UI` | `True` | Serve the AG-UI web interface |
436
446
 
437
- _33 package + 12 inherited variable(s). Auto-generated from `.env.example` + the shared agent-utilities set — do not edit._
447
+ _34 package + 12 inherited variable(s). Auto-generated from `.env.example` + the shared agent-utilities set — do not edit._
438
448
  <!-- ENV-VARS-TABLE:END -->
439
449
 
440
450
 
@@ -20,7 +20,7 @@
20
20
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/github-agent)
21
21
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/github-agent)
22
22
 
23
- *Version: 1.1.1*
23
+ *Version: 1.4.1*
24
24
 
25
25
  > **Documentation** — Installation, deployment, and usage across the MCP, API, and
26
26
  > CLI interfaces, including the integrated A2A agent server, are maintained in the
@@ -70,8 +70,10 @@ _Auto-generated from the live MCP server — do not edit by hand._
70
70
  | `github_collaborators` | `COLLABORATORTOOL` | Manage repository collaborators. |
71
71
  | `github_commits` | `COMMITTOOL` | Manage GitHub commits. |
72
72
  | `github_contents` | `CONTENTTOOL` | Manage GitHub contents. |
73
+ | `github_dependabot` | `DEPENDABOTTOOL` | Review and manage GitHub Dependabot vulnerability alerts. |
73
74
  | `github_discover_graphql_schema` | `GRAPHQLTOOL` | Discover the live GitHub GraphQL schema (types, fields, and attributes) in real-time. |
74
75
  | `github_graphql` | `GRAPHQLTOOL` | Execute raw GraphQL queries and mutations natively on GitHub. |
76
+ | `github_ingest_pipelines` | `INGESTTOOL` | Natively ingest GitHub Actions workflow runs into epistemic-graph. |
75
77
  | `github_ingest_repos` | `INGESTTOOL` | Natively ingest GitHub repositories into epistemic-graph as typed :Repository nodes. |
76
78
  | `github_issues` | `ISSUETOOL` | Manage GitHub issues. |
77
79
  | `github_orgs` | `ORGTOOL` | Manage GitHub organizations. |
@@ -83,7 +85,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
83
85
  #### Verbose 1:1 API-mapped tools (`MCP_TOOL_MODE=verbose` or `both`)
84
86
 
85
87
  <details>
86
- <summary>72 per-operation tools — one per public API method (click to expand)</summary>
88
+ <summary>76 per-operation tools — one per public API method (click to expand)</summary>
87
89
 
88
90
  | MCP Tool | Toggle Env Var | Description |
89
91
  |----------|----------------|-------------|
@@ -116,8 +118,11 @@ _Auto-generated from the live MCP server — do not edit by hand._
116
118
  | `github_get_commit` | `APITOOL` | Get a single commit in a repository. |
117
119
  | `github_get_commits` | `APITOOL` | List commits for a repository. |
118
120
  | `github_get_contents` | `APITOOL` | Get contents of a file or directory in a repository. |
121
+ | `github_get_dependabot_alert` | `APITOOL` | Get a single Dependabot alert. |
122
+ | `github_get_dependabot_alerts` | `APITOOL` | List Dependabot alerts for a repository. |
119
123
  | `github_get_issue` | `APITOOL` | Get a single issue in a repository. |
120
124
  | `github_get_issues` | `APITOOL` | List issues for a repository. |
125
+ | `github_get_org_dependabot_alerts` | `APITOOL` | List Dependabot alerts for an entire organization. |
121
126
  | `github_get_org_members` | `APITOOL` | List members for an organization. |
122
127
  | `github_get_org_repos` | `APITOOL` | List repositories for an organization. |
123
128
  | `github_get_org_teams` | `APITOOL` | List teams for an organization. |
@@ -153,6 +158,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
153
158
  | `github_trigger_workflow_dispatch` | `APITOOL` | Trigger a workflow dispatch event. |
154
159
  | `github_update_branch_protection` | `APITOOL` | Update branch protection configuration. |
155
160
  | `github_update_content` | `APITOOL` | Update a file in a repository. |
161
+ | `github_update_dependabot_alert` | `APITOOL` | Update the state of a Dependabot alert. |
156
162
  | `github_update_issue` | `APITOOL` | Update an issue in a repository. |
157
163
  | `github_update_organization` | `APITOOL` | Update an organization's profile and member settings. |
158
164
  | `github_update_pages` | `APITOOL` | Update the GitHub Pages configuration for a repository. |
@@ -162,7 +168,7 @@ _Auto-generated from the live MCP server — do not edit by hand._
162
168
 
163
169
  </details>
164
170
 
165
- _14 action-routed tool(s) (default) · 72 verbose 1:1 tool(s). Each is enabled unless its `<DOMAIN>TOOL` toggle is set false; `MCP_TOOL_MODE` selects the surface (`condensed` default · `verbose` 1:1 · `both`). Auto-generated — do not edit._
171
+ _16 action-routed tool(s) (default) · 76 verbose 1:1 tool(s). Each is enabled unless its `<DOMAIN>TOOL` toggle is set false; `MCP_TOOL_MODE` selects the surface (`condensed` default · `verbose` 1:1 · `both`). Auto-generated — do not edit._
166
172
  <!-- MCP-TOOLS-TABLE:END -->
167
173
 
168
174
  Detailed tool schemas, parameter shapes, and validation constraints are preserved in [docs/mcp.md](docs/mcp.md).
@@ -217,6 +223,7 @@ When query strings or parameters are supplied, an LLM-free **Knowledge Graph res
217
223
  "COLLABORATORTOOL": "True",
218
224
  "COMMITTOOL": "True",
219
225
  "CONTENTTOOL": "True",
226
+ "DEPENDABOTTOOL": "True",
220
227
  "GITHUB_ALLOW_DESTRUCTIVE": "False",
221
228
  "GITHUB_HTTP_CONNECT_TIMEOUT": "10",
222
229
  "GITHUB_HTTP_READ_TIMEOUT": "30",
@@ -263,6 +270,7 @@ When query strings or parameters are supplied, an LLM-free **Knowledge Graph res
263
270
  "COLLABORATORTOOL": "True",
264
271
  "COMMITTOOL": "True",
265
272
  "CONTENTTOOL": "True",
273
+ "DEPENDABOTTOOL": "True",
266
274
  "GITHUB_ALLOW_DESTRUCTIVE": "False",
267
275
  "GITHUB_HTTP_CONNECT_TIMEOUT": "10",
268
276
  "GITHUB_HTTP_READ_TIMEOUT": "30",
@@ -310,6 +318,7 @@ docker run -d \
310
318
  -e COLLABORATORTOOL=True \
311
319
  -e COMMITTOOL=True \
312
320
  -e CONTENTTOOL=True \
321
+ -e DEPENDABOTTOOL=True \
313
322
  -e GITHUB_ALLOW_DESTRUCTIVE=False \
314
323
  -e GITHUB_HTTP_CONNECT_TIMEOUT=10 \
315
324
  -e GITHUB_HTTP_READ_TIMEOUT=30 \
@@ -380,6 +389,7 @@ consumed from a **remote deployment**. The
380
389
  | `COLLABORATORTOOL` | `True` | |
381
390
  | `COMMITTOOL` | `True` | |
382
391
  | `CONTENTTOOL` | `True` | |
392
+ | `DEPENDABOTTOOL` | `True` | |
383
393
  | `GRAPHQLTOOL` | `True` | |
384
394
  | `INGESTTOOL` | `True` | |
385
395
  | `ISSUETOOL` | `True` | |
@@ -406,7 +416,7 @@ consumed from a **remote deployment**. The
406
416
  | `MODEL_ID` | `gpt-4o` | Model id for the agent |
407
417
  | `ENABLE_WEB_UI` | `True` | Serve the AG-UI web interface |
408
418
 
409
- _33 package + 12 inherited variable(s). Auto-generated from `.env.example` + the shared agent-utilities set — do not edit._
419
+ _34 package + 12 inherited variable(s). Auto-generated from `.env.example` + the shared agent-utilities set — do not edit._
410
420
  <!-- ENV-VARS-TABLE:END -->
411
421
 
412
422
 
@@ -4,7 +4,7 @@ import os
4
4
  import sys
5
5
  import warnings
6
6
 
7
- __version__ = "1.1.1"
7
+ __version__ = "1.4.1"
8
8
 
9
9
  logging.basicConfig(
10
10
  level=logging.INFO,
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python
2
+ from typing import Any
3
+
4
+ from agent_utilities.decorators import require_auth
5
+
6
+ from github_agent.api.api_client_base import BaseApiClient
7
+ from github_agent.github_response_models import Response
8
+
9
+
10
+ class Api(BaseApiClient):
11
+ @require_auth
12
+ def get_dependabot_alerts(self, owner: str, repo: str, **filters) -> Response:
13
+ """List Dependabot alerts for a repository.
14
+
15
+ GET /repos/{owner}/{repo}/dependabot/alerts. Optional filters passed
16
+ straight through as query parameters (state, severity, ecosystem,
17
+ package, scope, sort, direction, per_page, page). Returns the raw JSON
18
+ list of alerts in ``Response.data``.
19
+ """
20
+ params = {k: v for k, v in filters.items() if v is not None}
21
+ response = self._session.get(
22
+ url=f"{self.url}/repos/{owner}/{repo}/dependabot/alerts",
23
+ params=params or None,
24
+ headers=self.headers,
25
+ verify=self.verify,
26
+ proxies=self.proxies,
27
+ )
28
+ response.raise_for_status()
29
+ return Response(response=response, data=response.json())
30
+
31
+ @require_auth
32
+ def get_dependabot_alert(
33
+ self, owner: str, repo: str, alert_number: int
34
+ ) -> Response:
35
+ """Get a single Dependabot alert.
36
+
37
+ GET /repos/{owner}/{repo}/dependabot/alerts/{alert_number}.
38
+ """
39
+ response = self._session.get(
40
+ url=(f"{self.url}/repos/{owner}/{repo}/dependabot/alerts/{alert_number}"),
41
+ headers=self.headers,
42
+ verify=self.verify,
43
+ proxies=self.proxies,
44
+ )
45
+ response.raise_for_status()
46
+ return Response(response=response, data=response.json())
47
+
48
+ @require_auth
49
+ def get_org_dependabot_alerts(self, org: str, **filters) -> Response:
50
+ """List Dependabot alerts for an entire organization.
51
+
52
+ GET /orgs/{org}/dependabot/alerts. Optional filters passed straight
53
+ through as query parameters (state, severity, ecosystem, package,
54
+ scope, sort, direction, per_page, page). Returns the raw JSON list of
55
+ alerts in ``Response.data``.
56
+ """
57
+ params = {k: v for k, v in filters.items() if v is not None}
58
+ response = self._session.get(
59
+ url=f"{self.url}/orgs/{org}/dependabot/alerts",
60
+ params=params or None,
61
+ headers=self.headers,
62
+ verify=self.verify,
63
+ proxies=self.proxies,
64
+ )
65
+ response.raise_for_status()
66
+ return Response(response=response, data=response.json())
67
+
68
+ @require_auth
69
+ def update_dependabot_alert(
70
+ self,
71
+ owner: str,
72
+ repo: str,
73
+ alert_number: int,
74
+ state: str,
75
+ dismissed_reason: str | None = None,
76
+ dismissed_comment: str | None = None,
77
+ ) -> Response:
78
+ """Update the state of a Dependabot alert.
79
+
80
+ PATCH /repos/{owner}/{repo}/dependabot/alerts/{alert_number}. ``state``
81
+ is ``dismissed`` or ``open``. ``dismissed_reason`` is required when
82
+ dismissing (one of ``fix_started``, ``inaccurate``, ``no_bandwidth``,
83
+ ``not_used``, ``tolerable_risk``); ``dismissed_comment`` is optional.
84
+ """
85
+ payload: dict[str, Any] = {"state": state}
86
+ if dismissed_reason is not None:
87
+ payload["dismissed_reason"] = dismissed_reason
88
+ if dismissed_comment is not None:
89
+ payload["dismissed_comment"] = dismissed_comment
90
+ response = self._session.patch(
91
+ url=(f"{self.url}/repos/{owner}/{repo}/dependabot/alerts/{alert_number}"),
92
+ json=payload,
93
+ headers=self.headers,
94
+ verify=self.verify,
95
+ proxies=self.proxies,
96
+ )
97
+ response.raise_for_status()
98
+ return Response(response=response, data=response.json())
@@ -3,6 +3,7 @@ from github_agent.api.api_client_base import logger # noqa: F401
3
3
  from github_agent.api.api_client_branches import Api as BranchesApi
4
4
  from github_agent.api.api_client_commits import Api as CommitsApi
5
5
  from github_agent.api.api_client_contents import Api as ContentsApi
6
+ from github_agent.api.api_client_dependabot import Api as DependabotApi
6
7
  from github_agent.api.api_client_issues import Api as IssuesApi
7
8
  from github_agent.api.api_client_orgs import Api as OrgsApi
8
9
  from github_agent.api.api_client_pages import Api as PagesApi
@@ -39,6 +40,7 @@ class Api(
39
40
  BranchesApi,
40
41
  CommitsApi,
41
42
  ContentsApi,
43
+ DependabotApi,
42
44
  IssuesApi,
43
45
  OrgsApi,
44
46
  PagesApi,
@@ -3,7 +3,8 @@
3
3
  CONCEPT:AU-KG.ingest.enterprise-source-extractor. The github-agent connector natively
4
4
  pushes its data into the ONE epistemic-graph knowledge graph as **typed OWL nodes**
5
5
  (``:Repository``, ``:PullRequest``, ``:Issue``, ``:Release``, ``:Organization``,
6
- ``:Person``) plus links, and release notes as **:Document** nodes for semantic search —
6
+ ``:Person``, ``:PipelineRun``, ``:CheckRun``) plus links, and release notes as
7
+ **:Document** nodes for semantic search —
7
8
  using the lightweight engine client (``GraphComputeEngine()._client`` + ``txn``), the
8
9
  same fast client the blob ``MediaStore`` uses, NOT the heavy in-process ingestion engine.
9
10
 
@@ -355,3 +356,123 @@ def ingest_release_notes(
355
356
  }
356
357
  )
357
358
  return ingest_documents(docs, client=client, graph=graph)
359
+
360
+
361
+ def _duration_seconds(start: Any, end: Any) -> int | None:
362
+ """Whole-second wall-clock duration between two ISO-8601 timestamps, or ``None``."""
363
+ if not start or not end:
364
+ return None
365
+ try:
366
+ import datetime as _dt
367
+
368
+ started = _dt.datetime.fromisoformat(str(start).replace("Z", "+00:00"))
369
+ ended = _dt.datetime.fromisoformat(str(end).replace("Z", "+00:00"))
370
+ return max(0, int((ended - started).total_seconds()))
371
+ except (ValueError, TypeError):
372
+ return None
373
+
374
+
375
+ def ingest_pipeline_runs(
376
+ runs: list[dict[str, Any]],
377
+ *,
378
+ repo_full_name: str | None = None,
379
+ repo_node_id: str | None = None,
380
+ jobs_by_run: dict[int, list[dict[str, Any]]] | None = None,
381
+ client: Any | None = None,
382
+ graph: str | None = None,
383
+ ) -> dict[str, int] | None:
384
+ """Map GitHub Actions workflow runs (+ jobs/check-runs) → ``:PipelineRun``/``:CheckRun``.
385
+
386
+ ``runs``: raw ``WorkflowRun`` records (``client.get_workflow_runs`` /
387
+ ``.get_workflow_run`` ``model_dump()``). ``jobs_by_run``: optional ``{run_id:
388
+ [job_or_check_run, ...]}`` from ``client.get_workflow_run_jobs`` (or the Checks
389
+ API) — each becomes a child ``:CheckRun`` linked via ``hasJob``.
390
+
391
+ Uses the SAME ``:PipelineRun``/``:CheckRun`` classes and ``ranFor``/``hasJob``
392
+ edge names as gitlab-api's ingestion so GitHub Actions and GitLab CI/CD unify
393
+ under one CI node shape in the knowledge graph. ``ranFor`` is emitted once per
394
+ known target — the repo, the head commit, and (if the run lists it) the PR.
395
+ Stable ids: ``github:pipelinerun:<repo>:<id>`` / ``github:checkrun:<repo>:<id>``.
396
+ """
397
+ entities: list[dict[str, Any]] = []
398
+ relationships: list[dict[str, Any]] = []
399
+ jobs_by_run = jobs_by_run or {}
400
+ for run in runs or []:
401
+ run_id = run.get("id")
402
+ if run_id is None:
403
+ continue
404
+ repo = repo_full_name or (run.get("repository") or {}).get("full_name")
405
+ node_id = f"github:pipelinerun:{repo}:{run_id}"
406
+ run_started = run.get("run_started_at")
407
+ run_updated = run.get("updated_at")
408
+ entities.append(
409
+ {
410
+ "id": node_id,
411
+ "type": "PipelineRun",
412
+ "status": run.get("status"),
413
+ "conclusion": run.get("conclusion"),
414
+ "headSha": run.get("head_sha"),
415
+ "headBranch": run.get("head_branch"),
416
+ "event": run.get("event"),
417
+ "htmlUrl": _str(run.get("html_url")),
418
+ "runStartedAt": run_started,
419
+ "runUpdatedAt": run_updated,
420
+ "durationSeconds": _duration_seconds(run_started, run_updated),
421
+ "externalToolId": str(run_id),
422
+ }
423
+ )
424
+
425
+ if repo_node_id:
426
+ relationships.append(
427
+ {"source": node_id, "target": repo_node_id, "type": "ranFor"}
428
+ )
429
+
430
+ head_sha = run.get("head_sha")
431
+ if repo and head_sha:
432
+ commit_id = f"github:commit:{repo}:{head_sha}"
433
+ entities.append(
434
+ {
435
+ "id": commit_id,
436
+ "type": "Commit",
437
+ "sha": head_sha,
438
+ "externalToolId": head_sha,
439
+ }
440
+ )
441
+ relationships.append(
442
+ {"source": node_id, "target": commit_id, "type": "ranFor"}
443
+ )
444
+
445
+ for pr in run.get("pull_requests") or []:
446
+ pr_id = pr.get("id")
447
+ if pr_id is None:
448
+ continue
449
+ relationships.append(
450
+ {
451
+ "source": node_id,
452
+ "target": f"github:pullrequest:{pr_id}",
453
+ "type": "ranFor",
454
+ }
455
+ )
456
+
457
+ for job in jobs_by_run.get(run_id) or []:
458
+ job_id = job.get("id")
459
+ if job_id is None:
460
+ continue
461
+ job_node_id = f"github:checkrun:{repo}:{job_id}"
462
+ entities.append(
463
+ {
464
+ "id": job_node_id,
465
+ "type": "CheckRun",
466
+ "name": job.get("name"),
467
+ "status": job.get("status"),
468
+ "conclusion": job.get("conclusion"),
469
+ "startedAt": job.get("started_at"),
470
+ "completedAt": job.get("completed_at"),
471
+ "htmlUrl": _str(job.get("html_url")),
472
+ "externalToolId": str(job_id),
473
+ }
474
+ )
475
+ relationships.append(
476
+ {"source": node_id, "target": job_node_id, "type": "hasJob"}
477
+ )
478
+ return ingest_entities(entities, relationships, client=client, graph=graph)
@@ -9,6 +9,7 @@ from github_agent.mcp.mcp_branch import register_branch_tools
9
9
  from github_agent.mcp.mcp_collaborator import register_collaborator_tools
10
10
  from github_agent.mcp.mcp_commit import register_commit_tools
11
11
  from github_agent.mcp.mcp_content import register_content_tools
12
+ from github_agent.mcp.mcp_dependabot import register_dependabot_tools
12
13
  from github_agent.mcp.mcp_issue import register_issue_tools
13
14
  from github_agent.mcp.mcp_org import register_org_tools
14
15
  from github_agent.mcp.mcp_pull import register_pull_tools
@@ -22,6 +23,7 @@ __all__ = [
22
23
  "register_collaborator_tools",
23
24
  "register_commit_tools",
24
25
  "register_content_tools",
26
+ "register_dependabot_tools",
25
27
  "register_issue_tools",
26
28
  "register_org_tools",
27
29
  "register_pull_tools",
@@ -0,0 +1,172 @@
1
+ """MCP tools for Dependabot alert operations.
2
+
3
+ Auto-generated from mcp_server.py during ecosystem standardization.
4
+ """
5
+
6
+ from agent_utilities.mcp_utilities import resolve_action, run_blocking
7
+ from fastmcp import Context, FastMCP
8
+ from fastmcp.dependencies import Depends
9
+ from pydantic import Field
10
+
11
+ from github_agent.auth import allow_destructive_default, get_client
12
+
13
+ #: Dependabot actions gated behind allow_destructive / GITHUB_ALLOW_DESTRUCTIVE.
14
+ DESTRUCTIVE_DEPENDABOT_ACTIONS = {"update"}
15
+
16
+ #: Valid Dependabot actions for the shared ``resolve_action`` discovery helper.
17
+ DEPENDABOT_ACTIONS = ("list", "get", "list_org", "update")
18
+
19
+
20
+ def register_dependabot_tools(mcp: FastMCP):
21
+ @mcp.tool(tags={"dependabot"})
22
+ async def github_dependabot(
23
+ action: str = Field(
24
+ description="Action to perform. Must be one of: 'list', 'get', 'list_org', 'update'"
25
+ ),
26
+ params_json: str = Field(
27
+ default="{}", description="JSON string of parameters to pass to the action."
28
+ ),
29
+ allow_destructive: bool = Field(
30
+ default=False,
31
+ description="Confirm a guarded write ('update' — dismiss/reopen an alert). Also honoured via GITHUB_ALLOW_DESTRUCTIVE.",
32
+ ),
33
+ client=Depends(get_client),
34
+ ctx: Context | None = Field(
35
+ default=None, description="MCP context for progress reporting"
36
+ ),
37
+ ) -> dict:
38
+ """Review and manage GitHub Dependabot vulnerability alerts.
39
+
40
+ Actions (parameters via params_json):
41
+ - 'list': {"owner", "repo", plus optional filters: state
42
+ (open/dismissed/fixed/auto_dismissed), severity
43
+ (low/medium/high/critical), ecosystem, package, scope
44
+ (development/runtime), sort, direction, per_page} — list a repo's
45
+ Dependabot alerts (GET /repos/{owner}/{repo}/dependabot/alerts).
46
+ - 'get': {"owner", "repo", "alert_number"} — a single alert.
47
+ - 'list_org': {"org", plus the same optional filters} — every
48
+ Dependabot alert across an organization
49
+ (GET /orgs/{org}/dependabot/alerts).
50
+ - 'update': {"owner", "repo", "alert_number", "state":
51
+ "dismissed"|"open", plus "dismissed_reason" (required to dismiss:
52
+ fix_started/inaccurate/no_bandwidth/not_used/tolerable_risk) and
53
+ optional "dismissed_comment"} — dismiss or reopen an alert. Guarded
54
+ by allow_destructive / GITHUB_ALLOW_DESTRUCTIVE.
55
+ """
56
+ if ctx:
57
+ await ctx.info("Executing github_dependabot action...")
58
+ import json
59
+
60
+ try:
61
+ kwargs = json.loads(params_json)
62
+ except Exception as e:
63
+ return {"status": 400, "error": f"Invalid params_json: {e}", "data": None}
64
+
65
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
66
+
67
+ resolved = resolve_action(action, DEPENDABOT_ACTIONS, service="github-agent")
68
+ if isinstance(resolved, dict):
69
+ return resolved
70
+ action = resolved
71
+
72
+ if action in DESTRUCTIVE_DEPENDABOT_ACTIONS and not (
73
+ allow_destructive is True or allow_destructive_default()
74
+ ):
75
+ return {
76
+ "status": 403,
77
+ "error": (
78
+ f"Action '{action}' is a guarded write and blocked by default. "
79
+ "Re-run with allow_destructive=true (or set "
80
+ "GITHUB_ALLOW_DESTRUCTIVE=True) to confirm."
81
+ ),
82
+ "data": None,
83
+ }
84
+
85
+ try:
86
+ if action == "list":
87
+ owner = kwargs.pop("owner", None)
88
+ repo = kwargs.pop("repo", None)
89
+ if not owner or not repo:
90
+ return {
91
+ "status": 400,
92
+ "error": "Missing 'owner' or 'repo' parameter",
93
+ "data": None,
94
+ }
95
+ response = await run_blocking(
96
+ client.get_dependabot_alerts, owner=owner, repo=repo, **kwargs
97
+ )
98
+ return {
99
+ "status": 200,
100
+ "message": "Dependabot alerts retrieved successfully",
101
+ "data": response.data,
102
+ }
103
+ elif action == "get":
104
+ owner = kwargs.get("owner")
105
+ repo = kwargs.get("repo")
106
+ alert_number = kwargs.get("alert_number")
107
+ if not owner or not repo or not alert_number:
108
+ return {
109
+ "status": 400,
110
+ "error": "Missing 'owner', 'repo', or 'alert_number' parameter",
111
+ "data": None,
112
+ }
113
+ response = await run_blocking(
114
+ client.get_dependabot_alert,
115
+ owner=owner,
116
+ repo=repo,
117
+ alert_number=int(alert_number),
118
+ )
119
+ return {
120
+ "status": 200,
121
+ "message": "Dependabot alert retrieved successfully",
122
+ "data": response.data,
123
+ }
124
+ elif action == "list_org":
125
+ org = kwargs.pop("org", None)
126
+ if not org:
127
+ return {
128
+ "status": 400,
129
+ "error": "Missing required 'org' parameter",
130
+ "data": None,
131
+ }
132
+ response = await run_blocking(
133
+ client.get_org_dependabot_alerts, org=org, **kwargs
134
+ )
135
+ return {
136
+ "status": 200,
137
+ "message": "Organization Dependabot alerts retrieved successfully",
138
+ "data": response.data,
139
+ }
140
+ elif action == "update":
141
+ owner = kwargs.get("owner")
142
+ repo = kwargs.get("repo")
143
+ alert_number = kwargs.get("alert_number")
144
+ state = kwargs.get("state")
145
+ if not owner or not repo or not alert_number or not state:
146
+ return {
147
+ "status": 400,
148
+ "error": "Missing 'owner', 'repo', 'alert_number', or 'state' parameter",
149
+ "data": None,
150
+ }
151
+ response = await run_blocking(
152
+ client.update_dependabot_alert,
153
+ owner=owner,
154
+ repo=repo,
155
+ alert_number=int(alert_number),
156
+ state=state,
157
+ dismissed_reason=kwargs.get("dismissed_reason"),
158
+ dismissed_comment=kwargs.get("dismissed_comment"),
159
+ )
160
+ return {
161
+ "status": 200,
162
+ "message": "Dependabot alert updated successfully",
163
+ "data": response.data,
164
+ }
165
+ else:
166
+ return {
167
+ "status": 400,
168
+ "error": f"Unknown action: {action}",
169
+ "data": None,
170
+ }
171
+ except Exception as e:
172
+ return {"status": 500, "error": str(e), "data": None}