invoking-github
npx machina-cli add skill oaustegard/claude-skills/invoking-github --openclawInvoking GitHub
Programmatically interact with GitHub repositories from Claude.ai chat: read files, commit changes, create PRs, and persist state across sessions.
When to Use This Skill
Primary use cases:
- Commit code/documentation from Claude.ai chat (mobile/web)
- Auto-persist DEVLOG.md for iterating skill
- Manage state across sessions via GitHub branches
- Read and update repository files programmatically
- Create pull requests from chat interface
Trigger patterns:
- "Commit this to the repository"
- "Update the README on GitHub"
- "Save this to a feature branch"
- "Create a PR with these changes"
- "Persist DEVLOG to GitHub"
- "Read the config file from my repo"
Not needed for:
- Claude Code environments (use native git commands)
- Read-only repository access (use GitHub UI or API directly)
Quick Start
Prerequisites
Create a GitHub Personal Access Token and add to Project Knowledge:
- Go to https://github.com/settings/tokens
- Create new token (classic or fine-grained)
- Required scopes:
repo(orpublic_repofor public repos only) - In Claude.ai, add to Project Knowledge:
- Title:
GITHUB_API_KEY - Content: Your token (e.g.,
ghp_abc123...)
- Title:
Single File Commit
from invoking_github import commit_file
result = commit_file(
repo="username/repo-name",
path="README.md",
content="# Updated README\n\nNew content here...",
branch="main",
message="Update README with new instructions"
)
print(f"Committed: {result['commit_sha']}")
Read File
from invoking_github import read_file
content = read_file(
repo="username/repo-name",
path="config.json",
branch="main"
)
print(content)
Batch Commit (Multiple Files)
from invoking_github import commit_files
files = [
{"path": "src/main.py", "content": "# Python code..."},
{"path": "README.md", "content": "# Updated docs..."},
{"path": "tests/test.py", "content": "# Tests..."}
]
result = commit_files(
repo="username/repo-name",
files=files,
branch="feature-branch",
message="Add new feature implementation",
create_branch_from="main" # Create branch if it doesn't exist
)
print(f"Committed {len(files)} files: {result['commit_sha']}")
Create Pull Request
from invoking_github import create_pull_request
pr = create_pull_request(
repo="username/repo-name",
head="feature-branch",
base="main",
title="Add new feature",
body="## Changes\n- Implemented feature X\n- Updated docs\n- Added tests"
)
print(f"PR created: {pr['html_url']}")
Core Functions
read_file()
Read a file from repository:
read_file(
repo: str, # "owner/name"
path: str, # "path/to/file.py"
branch: str = "main" # Branch name
) -> str
Returns: File content as string
Raises: GitHubAPIError if file not found or access denied
commit_file()
Commit a single file (create or update):
commit_file(
repo: str, # "owner/name"
path: str, # "path/to/file.py"
content: str, # New file content
branch: str, # Target branch
message: str, # Commit message
create_branch_from: str = None # Create branch from this if doesn't exist
) -> dict
Returns: Dict with commit_sha, branch, file_path
Raises: GitHubAPIError on conflicts or auth failures
commit_files()
Commit multiple files in a single commit:
commit_files(
repo: str, # "owner/name"
files: list[dict], # [{"path": "...", "content": "..."}]
branch: str, # Target branch
message: str, # Commit message
create_branch_from: str = None # Create branch from this if doesn't exist
) -> dict
Returns: Dict with commit_sha, branch, files_committed
Raises: GitHubAPIError on failures
Note: Uses Git Trees API for efficiency - atomic commit of all files.
create_pull_request()
Create a pull request:
create_pull_request(
repo: str, # "owner/name"
head: str, # Source branch (your changes)
base: str, # Target branch (where to merge)
title: str, # PR title
body: str = "" # PR description (supports markdown)
) -> dict
Returns: Dict with number, html_url, state
Raises: GitHubAPIError if branches invalid or PR exists
Credential Configuration
This skill requires a GitHub Personal Access Token. Two configuration methods:
Method 1: Project Knowledge (Recommended)
Best for Claude.ai chat users (mobile/web):
- Create token at https://github.com/settings/tokens
- In Claude.ai Project settings → Add to Project Knowledge
- Create document titled
GITHUB_API_KEY - Paste your token as content
Permissions required:
- Classic token:
reposcope - Fine-grained token: Repository permissions → Contents (read/write) and Pull requests (read/write)
Method 2: API Credentials Skill (Fallback)
Alternatively, use combined credentials file:
- Create
API_CREDENTIALS.jsonin project knowledge - Add:
{"github_api_key": "ghp_your-token-here"}
Integration with Iterating Skill
Auto-persist DEVLOG.md to GitHub for cross-session continuity:
# In your DEVLOG update function
from invoking_github import commit_file
from pathlib import Path
def update_devlog_with_sync(data, repo="user/project", branch="devlog"):
"""Update DEVLOG.md locally and sync to GitHub"""
# Update local DEVLOG
update_devlog(data) # Your existing function
# Auto-sync to GitHub
try:
devlog_content = Path("DEVLOG.md").read_text()
result = commit_file(
repo=repo,
path="DEVLOG.md",
content=devlog_content,
branch=branch,
message=f"DEVLOG: {data['title']}",
create_branch_from="main"
)
print(f"✓ DEVLOG synced to GitHub ({repo}:{branch})")
return result
except Exception as e:
print(f"⚠ DEVLOG sync failed: {e}")
# Continue anyway - local DEVLOG.md still updated
return None
Benefits:
- Automatic backup of session progress
- Cross-device access to development logs
- Git history of decisions and progress
- No manual copy/paste to Project Knowledge
See references/iterating-integration.md for complete patterns.
Error Handling
All functions raise GitHubAPIError with descriptive messages:
from invoking_github import commit_file, GitHubAPIError
try:
result = commit_file(
repo="user/repo",
path="file.py",
content="...",
branch="main",
message="Update"
)
except GitHubAPIError as e:
if e.status_code == 404:
print("Repository or branch not found")
elif e.status_code == 401:
print("Authentication failed - check your token")
elif e.status_code == 403:
print("Access denied - check token permissions")
elif e.status_code == 409:
print("Conflict - file was modified since last read")
else:
print(f"GitHub API error: {e}")
Common errors:
- 404: Repository, branch, or file not found
- 401/403: Invalid token or insufficient permissions
- 409: Merge conflict (file changed concurrently)
- 422: Validation error (invalid branch name, etc.)
- Rate limit: Too many requests (wait before retrying)
Best Practices
-
Use descriptive commit messages
- Bad: "Update files"
- Good: "Add authentication middleware and update user routes"
-
Batch commits when possible
- Use
commit_files()for related changes - Single atomic commit = cleaner git history
- Use
-
Create feature branches
- Don't commit directly to main
- Use
create_branch_from="main"parameter - Create PR for review
-
Handle errors gracefully
- Always wrap in try-except
- Provide fallback behavior
- Don't fail silently
-
Secure token management
- Use fine-grained tokens with minimal scopes
- Set expiration dates
- Rotate regularly
- Never commit tokens to repositories
Advanced Usage
Conditional Commits
Only commit if file content changed:
from invoking_github import read_file, commit_file, GitHubAPIError
try:
current_content = read_file(repo, path, branch)
if current_content != new_content:
commit_file(repo, path, new_content, branch, "Update file")
else:
print("No changes detected, skipping commit")
except GitHubAPIError as e:
if e.status_code == 404:
# File doesn't exist, create it
commit_file(repo, path, new_content, branch, "Create file")
else:
raise
Session-Specific Branches
Avoid conflicts with unique branch names:
import datetime
session_id = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
branch_name = f"devlog-{session_id}"
commit_file(
repo="user/project",
path="DEVLOG.md",
content=devlog_content,
branch=branch_name,
message="Session progress",
create_branch_from="main"
)
Multi-Repository Workflows
Work across multiple repos:
repos = ["user/frontend", "user/backend", "user/docs"]
for repo in repos:
commit_file(
repo=repo,
path="VERSION",
content="2.0.0\n",
branch="release-2.0",
message="Bump version to 2.0.0"
)
Limitations
- Target environment: Claude.ai chat only (not Claude Code)
- No OAuth: Must use Personal Access Tokens manually
- No git operations: Pure REST API (no clone, pull, rebase, etc.)
- File size: GitHub API limits ~100MB per file
- Rate limits: 5000 requests/hour for authenticated users
- Network required: All operations require internet access
See Also
- references/api-reference.md - Detailed API documentation
- references/credential-setup.md - Step-by-step credential guide
- references/iterating-integration.md - DEVLOG auto-sync patterns
- references/troubleshooting.md - Common issues and solutions
- GitHub REST API Docs - Official GitHub API reference
Token Efficiency
This skill uses ~800 tokens when loaded but provides essential GitHub operations for claude.ai chat environments where native git access isn't available. Enables persistent state management and cross-session workflows.
Source
git clone https://github.com/oaustegard/claude-skills/blob/main/invoking-github/SKILL.mdView on GitHub Overview
Invoking GitHub enables Claude.ai to read and update repository files, commit changes, and create pull requests from the chat. It also supports persisting state across sessions via GitHub branches and DEVLOG updates. Not needed in Claude Code, which has native Git access.
How This Skill Works
Core functions read_file, commit_file, commit_files, and create_pull_request operate against a GitHub repository using a configured API token. The token should be stored in Project Knowledge with the required scopes (repo or public_repo). The skill handles branch creation, PR wiring, and returns actionable results like commit_sha and html_url.
When to Use It
- Commit code or documentation from Claude.ai chat (mobile/web).
- Auto-persist DEVLOG.md for iterating the skill.
- Manage state across sessions via GitHub branches.
- Read and update repository files programmatically.
- Create pull requests directly from the chat interface.
Quick Start
- Step 1: Create a GitHub token and add it to Project Knowledge as GITHUB_API_KEY with repo scopes.
- Step 2: Use helpers like commit_file, read_file, commit_files, or create_pull_request as shown in the examples.
- Step 3: Review results (commit_sha, html_url) in your chat output and verify changes in GitHub.
Best Practices
- Store and scope your GitHub API token securely in Project Knowledge (e.g., GITHUB_API_KEY).
- Use create_branch_from to safely create or update on feature branches rather than main.
- Provide clear, descriptive commit messages and PR titles.
- Validate file paths and encodings before commit to avoid errors.
- Handle conflicts and API errors gracefully; monitor rate limits and retries.
Example Use Cases
- Commit an updated README.md with a new instruction set from the chat.
- Persist DEVLOG.md content after an iteration to the repository.
- Read a config.json to guide the next steps in the chat flow.
- Create a PR named 'Add new feature' from feature-branch to main.
- Batch commit multiple files (src/main.py, README.md, tests/test.py) in one go.