GitHub API 集成:管理仓库、PR 和 Issue - Openclaw Skills
什么是 GitHub?
Openclaw Skills 的 GitHub 技能使开发人员和 AI 代理能够直接与 GitHub REST API 交互,而无需手动管理复杂的 OAuth 流程。通过安全网关代理请求,此技能可以无缝管理版本控制资产、团队协作工具和仓库数据。
此集成是构建自动化编码工作流、智能仓库助手或自定义 CI/CD 工具的重要组件。它处理了身份验证的繁重工作,让您可以专注于使用标准 HTTP 请求构建与庞大 GitHub 生态系统交互的功能。
下载入口:https://github.com/openclaw/skills/tree/main/skills/byungkyu/github-api
安装与下载
1. ClawHub CLI
从源直接安装技能的最快方式。
npx clawhub@latest install github-api
2. 手动安装
将技能文件夹复制到以下位置之一
全局模式~/.openclaw/skills/
工作区
<project>/skills/
优先级:工作区 > 本地 > 内置
3. 提示词安装
将此提示词复制到 OpenClaw 即可自动安装。
请帮我使用 Clawhub 安装 github-api。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
GitHub 应用场景
- 根据代理分析自动创建和管理 GitHub Issue 和拉取请求。
- 使用高级过滤器和参数搜索代码库或仓库,以查找特定逻辑或文档。
- 以编程方式更新仓库内容并提交更改,用于自动化文档或重构。
- 为企业级自动化管理团队成员身份和组织级资源。
- 构建 AI 驱动的 CI/CD 机器人,坚控仓库运行状况并提供提交反馈。
- 开发人员使用 Maton API 密钥进行身份验证,并通过控制平面建立 GitHub OAuth 连接。
- 请求被发送到网关 URL,该 URL 镜像了原生 GitHub API 路径结构(例如 /github/user/repos)。
- 网关自动将活动的 OAuth 令牌注入请求头中以进行安全身份验证。
- 该技能将请求直接代理到 GitHub 的 REST API 服务器。
- 响应以结构化 JSON 对象的形式返回,AI 代理或应用程序可以轻松解析该对象。
- 对于具有多个帐户的环境,可以使用特定的连接头将请求路由到正确的 GitHub 配置文件。
GitHub 配置指南
要开始使用 Openclaw Skills 的这项技能,请按照以下步骤操作:
- 在 maton.ai 登录或创建帐户,并从设置页面检索您的 API 密钥。
- 在终端中设置环境变量:
export MATON_API_KEY="YOUR_API_KEY"
- 创建一个新的 GitHub 连接以启动 OAuth 流程:
curl -X POST https://ctrl.maton.ai/connections r
-H "Authorization: Bearer $MATON_API_KEY" r
-H "Content-Type: application/json" r
-d '{"app": "github"}'
- 在浏览器中打开 JSON 响应中返回的
url,以在 GitHub 上授权该应用程序。 - 通过获取您的用户信息来验证连接是否有效:
curl https://gateway.maton.ai/github/user r
-H "Authorization: Bearer $MATON_API_KEY"
GitHub 数据架构与分类体系
该技能使用标准 GitHub REST API 模式组织数据。响应以 JSON 格式提供,通常遵循以下结构:
| 资源 | 描述 | 常用字段 |
|---|---|---|
| Repositories | 代码项目的元数据 | name, full_name, private, owner, html_url |
| Issues | 任务跟踪项 | number, title, state, labels, assignee |
| Pull Requests | 代码合并提案 | title, state, merged, head, base |
| Contents | 文件和目录数据 | path, sha, size, content (Base64) |
| Search Results | 分页查询匹配项 | total_count, items, score |
注意:创建或更新文件时,根据 GitHub 的要求,content 字段必须经过 Base64 编码。
name: github
description: |
GitHub API integration with managed OAuth. Access repositories, issues, pull requests, commits, branches, and users.
Use this skill when users want to interact with GitHub repositories, manage issues and PRs, search code, or automate workflows.
For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
compatibility: Requires network access and valid Maton API key
metadata:
author: maton
version: "1.0"
clawdbot:
emoji: ??
requires:
env:
- MATON_API_KEY
GitHub
Access the GitHub REST API with managed OAuth authentication. Manage repositories, issues, pull requests, commits, branches, users, and more.
Quick Start
# Get authenticated user
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/github/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/github/{native-api-path}
Replace {native-api-path} with the actual GitHub API endpoint path. The gateway proxies requests to api.github.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your GitHub OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=github&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'github'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "83e7c665-60f6-4a64-816c-5e287ea8982f",
"status": "ACTIVE",
"creation_time": "2026-02-06T03:00:43.860014Z",
"last_updated_time": "2026-02-06T03:01:06.027323Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "github",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple GitHub connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/github/user')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '83e7c665-60f6-4a64-816c-5e287ea8982f')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Users
Get Authenticated User
GET /github/user
Get User by Username
GET /github/users/{username}
List Users
GET /github/users?since={user_id}&per_page=30
Repositories
List User Repositories
GET /github/user/repos?per_page=30&sort=updated
Query parameters: type (all, owner, public, private, member), sort (created, updated, pushed, full_name), direction (asc, desc), per_page, page
List Organization Repositories
GET /github/orgs/{org}/repos?per_page=30
Get Repository
GET /github/repos/{owner}/{repo}
Create Repository (User)
POST /github/user/repos
Content-Type: application/json
{
"name": "my-new-repo",
"description": "A new repository",
"private": true,
"auto_init": true
}
Create Repository (Organization)
POST /github/orgs/{org}/repos
Content-Type: application/json
{
"name": "my-new-repo",
"description": "A new repository",
"private": true
}
Update Repository
PATCH /github/repos/{owner}/{repo}
Content-Type: application/json
{
"description": "Updated description",
"has_issues": true,
"has_wiki": false
}
Delete Repository
DELETE /github/repos/{owner}/{repo}
Repository Contents
List Contents
GET /github/repos/{owner}/{repo}/contents/{path}
Get File Contents
GET /github/repos/{owner}/{repo}/contents/{path}?ref={branch}
Create or Update File
PUT /github/repos/{owner}/{repo}/contents/{path}
Content-Type: application/json
{
"message": "Create new file",
"content": "SGVsbG8gV29ybGQh",
"branch": "main"
}
Note: content must be Base64 encoded.
Delete File
DELETE /github/repos/{owner}/{repo}/contents/{path}
Content-Type: application/json
{
"message": "Delete file",
"sha": "{file_sha}",
"branch": "main"
}
Branches
List Branches
GET /github/repos/{owner}/{repo}/branches?per_page=30
Get Branch
GET /github/repos/{owner}/{repo}/branches/{branch}
Rename Branch
POST /github/repos/{owner}/{repo}/branches/{branch}/rename
Content-Type: application/json
{
"new_name": "new-branch-name"
}
Merge Branches
POST /github/repos/{owner}/{repo}/merges
Content-Type: application/json
{
"base": "main",
"head": "feature-branch",
"commit_message": "Merge feature branch"
}
Commits
List Commits
GET /github/repos/{owner}/{repo}/commits?per_page=30
Query parameters: sha (branch name or commit SHA), path (file path), author, committer, since, until, per_page, page
Get Commit
GET /github/repos/{owner}/{repo}/commits/{ref}
Compare Two Commits
GET /github/repos/{owner}/{repo}/compare/{base}...{head}
Issues
List Repository Issues
GET /github/repos/{owner}/{repo}/issues?state=open&per_page=30
Query parameters: state (open, closed, all), labels, assignee, creator, mentioned, sort, direction, since, per_page, page
Get Issue
GET /github/repos/{owner}/{repo}/issues/{issue_number}
Create Issue
POST /github/repos/{owner}/{repo}/issues
Content-Type: application/json
{
"title": "Found a bug",
"body": "Bug description here",
"labels": ["bug"],
"assignees": ["username"]
}
Update Issue
PATCH /github/repos/{owner}/{repo}/issues/{issue_number}
Content-Type: application/json
{
"state": "closed",
"state_reason": "completed"
}
Lock Issue
PUT /github/repos/{owner}/{repo}/issues/{issue_number}/lock
Content-Type: application/json
{
"lock_reason": "resolved"
}
Unlock Issue
DELETE /github/repos/{owner}/{repo}/issues/{issue_number}/lock
Issue Comments
List Issue Comments
GET /github/repos/{owner}/{repo}/issues/{issue_number}/comments?per_page=30
Create Issue Comment
POST /github/repos/{owner}/{repo}/issues/{issue_number}/comments
Content-Type: application/json
{
"body": "This is a comment"
}
Update Issue Comment
PATCH /github/repos/{owner}/{repo}/issues/comments/{comment_id}
Content-Type: application/json
{
"body": "Updated comment"
}
Delete Issue Comment
DELETE /github/repos/{owner}/{repo}/issues/comments/{comment_id}
Labels
List Labels
GET /github/repos/{owner}/{repo}/labels?per_page=30
Create Label
POST /github/repos/{owner}/{repo}/labels
Content-Type: application/json
{
"name": "priority:high",
"color": "ff0000",
"description": "High priority issues"
}
Milestones
List Milestones
GET /github/repos/{owner}/{repo}/milestones?state=open&per_page=30
Create Milestone
POST /github/repos/{owner}/{repo}/milestones
Content-Type: application/json
{
"title": "v1.0",
"state": "open",
"description": "First release",
"due_on": "2026-03-01T00:00:00Z"
}
Pull Requests
List Pull Requests
GET /github/repos/{owner}/{repo}/pulls?state=open&per_page=30
Query parameters: state (open, closed, all), head, base, sort, direction, per_page, page
Get Pull Request
GET /github/repos/{owner}/{repo}/pulls/{pull_number}
Create Pull Request
POST /github/repos/{owner}/{repo}/pulls
Content-Type: application/json
{
"title": "New feature",
"body": "Description of changes",
"head": "feature-branch",
"base": "main",
"draft": false
}
Update Pull Request
PATCH /github/repos/{owner}/{repo}/pulls/{pull_number}
Content-Type: application/json
{
"title": "Updated title",
"state": "closed"
}
List Pull Request Commits
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/commits?per_page=30
List Pull Request Files
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/files?per_page=30
Check If Merged
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/merge
Merge Pull Request
PUT /github/repos/{owner}/{repo}/pulls/{pull_number}/merge
Content-Type: application/json
{
"commit_title": "Merge pull request",
"merge_method": "squash"
}
Merge methods: merge, squash, rebase
Pull Request Reviews
List Reviews
GET /github/repos/{owner}/{repo}/pulls/{pull_number}/reviews?per_page=30
Create Review
POST /github/repos/{owner}/{repo}/pulls/{pull_number}/reviews
Content-Type: application/json
{
"body": "Looks good!",
"event": "APPROVE"
}
Events: APPROVE, REQUEST_CHANGES, COMMENT
Search
Search Repositories
GET /github/search/repositories?q={query}&per_page=30
Example queries:
tetris+language:python- Repositories with "tetris" in Pythonreact+stars:>10000- Repositories with "react" and 10k+ stars
Search Issues
GET /github/search/issues?q={query}&per_page=30
Example queries:
bug+is:open+is:issue- Open issues containing "bug"author:username+is:pr- Pull requests by author
Search Code
GET /github/search/code?q={query}&per_page=30
Example queries:
addClass+repo:facebook/react- Search for "addClass" in a specific repofunction+extension:js- JavaScript functions
Note: Code search may timeout on broad queries.
Search Users
GET /github/search/users?q={query}&per_page=30
Organizations
List User Organizations
GET /github/user/orgs?per_page=30
Note: Requires read:org scope.
Get Organization
GET /github/orgs/{org}
List Organization Members
GET /github/orgs/{org}/members?per_page=30
Rate Limit
Get Rate Limit
GET /github/rate_limit
Response:
{
"rate": {
"limit": 5000,
"remaining": 4979,
"reset": 1707200000
},
"resources": {
"core": { "limit": 5000, "remaining": 4979 },
"search": { "limit": 30, "remaining": 28 }
}
}
Pagination
GitHub uses page-based and link-based pagination:
GET /github/repos/{owner}/{repo}/issues?per_page=30&page=2
Response headers include pagination links:
Link: <url>; rel="next", <url>; rel="last"
Common pagination parameters:
per_page: Results per page (max 100, default 30)page: Page number (default 1)
Some endpoints use cursor-based pagination with since parameter (e.g., listing users).
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/github/repos/owner/repo/issues?state=open&per_page=10',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const issues = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/github/repos/owner/repo/issues',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'state': 'open', 'per_page': 10}
)
issues = response.json()
Notes
- Repository names are case-insensitive but the API preserves case
- Issue numbers and PR numbers share the same sequence per repository
- Content must be Base64 encoded when creating/updating files
- Rate limits: 5000 requests/hour for authenticated users, 30 searches/minute
- Search queries may timeout on very broad patterns
- Some endpoints require specific OAuth scopes (e.g.,
read:orgfor organization operations). If you receive a scope error, contact Maton support at [email protected] with the specific operations/APIs you need and your use-case - IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing GitHub connection |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - insufficient permissions or scope |
| 404 | Resource not found |
| 408 | Request timeout (common for complex searches) |
| 422 | Validation failed |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from GitHub API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
github. For example:
- Correct:
https://gateway.maton.ai/github/user - Incorrect:
https://gateway.maton.ai/api.github.com/user
Resources
-
07.30
大周列国志国是诏书如何使用
-
07.30
烈火星辰传奇boss系统如何体验
-
07.30
汉家城市最新阵容一览表攻略
-
07.30
斗罗大陆武魂觉醒魂师唐晨如何培养
-
07.30
刮个爽点击小游戏成就如何解锁
-
07.30
洛克王国世界九龙天尊如何获取
-
- 银河掠夺者-2026最新兑换码分享
- 07.30
-
-
-
-
-
-
-
下载
- |
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- |
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏