@matimo/github
v0.1.0-alpha.12.1
Published
GitHub API tools for Matimo - Full-featured GitHub integration with OAuth2 and PAT support
Readme
@matimo/github — GitHub Tools for Matimo
Comprehensive GitHub REST API integration for Matimo. Execute 22 focused tools across search, issues, repositories, pull requests, commits, collaborators, releases, and code scanning.
Installation
npm install @matimo/github
# or
pnpm add @matimo/githubQuick Start
Factory Pattern
import { MatimoInstance } from '@matimo/core';
const matimo = await MatimoInstance.init({
autoDiscover: true // Auto-loads @matimo/github from node_modules
});
// Search repositories
const repos = await matimo.execute('github-search-repositories', {
query: 'language:typescript stars:>1000'
});
// Create issue
const issue = await matimo.execute('github-create-issue', {
owner: 'nodejs',
repo: 'node',
title: 'Bug: Memory leak in event loop',
body: 'Description of the issue...'
});
// Merge pull request
const merged = await matimo.execute('github-merge-pull-request', {
owner: 'nodejs',
repo: 'node',
pull_number: 42,
merge_method: 'squash'
});Decorator Pattern
import { MatimoInstance, setGlobalMatimoInstance, tool } from '@matimo/core';
const matimo = await MatimoInstance.init({ autoDiscover: true });
setGlobalMatimoInstance(matimo);
class GitHubAgent {
@tool('github-search-repositories')
async searchRepos(query: string) { /* auto-executed */ }
@tool('github-create-issue')
async createIssue(owner: string, repo: string, title: string, body: string) {
/* auto-executed */
}
}
const agent = new GitHubAgent();
await agent.searchRepos('language:typescript');LangChain Integration
import { MatimoInstance } from '@matimo/core';
const matimo = await MatimoInstance.init({ autoDiscover: true });
// Get all GitHub tools as LangChain function schemas
const ghTools = matimo.listTools()
.filter(t => t.name.startsWith('github-'))
.map(tool => ({
type: 'function',
function: {
name: tool.name,
description: tool.description,
parameters: {
type: 'object',
properties: tool.parameters || {},
required: Object.entries(tool.parameters || {})
.filter(([_, p]) => p.required)
.map(([name]) => name)
}
}
}));
// Use with your LLM + function callingAvailable Tools
| Tool | Description | HTTP Method |
|------|-------------|------------|
| Search | | |
| github-search-repositories | Search repositories by name, stars, topics | GET |
| github-search-code | Search code across repositories | GET |
| github-search-issues | Search issues and pull requests | GET |
| github-search-users | Search users by location, followers | GET |
| Issues | | |
| github-list-issues | List repository issues with filtering | GET |
| github-create-issue | Create a new issue | POST |
| github-get-issue | Get specific issue details | GET |
| github-update-issue | Update issue title, body, state | PATCH |
| Repositories | | |
| github-list-repositories | List organization/user repositories | GET |
| github-create-repository | Create new repository | POST |
| github-get-repository | Get repository details (120+ fields) | GET |
| github-delete-repository | Delete repository (admin only) | DELETE |
| Pull Requests | | |
| github-list-pull-requests | List pull requests with filtering | GET |
| github-create-pull-request | Create new pull request | POST |
| github-merge-pull-request | Merge pull request | PUT |
| Commits | | |
| github-list-commits | List repository commits | GET |
| Collaborators | | |
| github-list-collaborators | List repository collaborators | GET |
| github-add-collaborator | Add user as collaborator | PUT |
| Releases | | |
| github-list-releases | List repository releases | GET |
| github-create-release | Create new release | POST |
| Code Scanning | | |
| github-list-code-alerts | List security scanning alerts | GET |
| github-update-code-alert | Update alert status (dismiss/reopen) | PATCH |
Authentication
Personal Access Token (PAT)
Create token at https://github.com/settings/tokens
Choose scopes:
- repo — Full access to repositories
- gist — Full access to gists
- user — Read user profile
- admin:org_hook — Write organization webhooks (optional)
- security_events — Read code scanning alerts
Set environment variable:
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxFine-grained Personal Access Token
- Create at https://github.com/settings/personal-access-tokens/new
- Minimum required permissions:
- Repository (selected): Code, Commit, Issues, Pull Requests, Releases, Security events
- Set environment variable:
export GITHUB_TOKEN=github_pat_xxxxxxxxxxxxxxxxOAuth2 (GitHub App)
- Create GitHub App at https://github.com/settings/apps
- Get Client ID from app settings
- Use OAuth2Handler for authorization:
import { OAuth2Handler } from '@matimo/core';
const handler = new OAuth2Handler('github');
const { authorize_url, state } = handler.getAuthorizationUrl();
// Redirect user to authorize_url
// Handle callback with authorization code
const tokens = await handler.exchangeAuthorizationCode(code, state);
// tokens.access_token ready for use
process.env.GITHUB_TOKEN = tokens.access_token;Rate Limiting
GitHub has multiple rate limits:
- Primary: 5,000 requests/hour (authenticated), 60/hour (unauthenticated)
- Search: 30 requests/minute (general), 10 requests/minute (code search)
- Secondary: 100 concurrent requests, 900 points/minute
Handling Rate Limits
Tools include exponential backoff and retry logic. When you hit rate limits:
- Get reset time from response header:
x-ratelimit-reset(Unix timestamp) - Wait until reset time, then retry
- Check remaining quota with
x-ratelimit-remainingheader
// Automatic retry with exponential backoff
try {
const result = await matimo.execute('github-search-code', {
query: 'language:python'
});
} catch (error) {
// If 429 (rate limited), solution automatically retries with backoff
// If still fails after retries, throws MatimoError with details
}Error Handling
All tools throw MatimoError with structured error information:
import { MatimoError } from '@matimo/core';
try {
await matimo.execute('github-create-issue', { /* ... */ });
} catch (error) {
if (error instanceof MatimoError) {
console.error('Code:', error.code); // EXECUTION_FAILED
console.error('Message:', error.message); // User-friendly message
console.error('Details:', error.details); // { statusCode: 404, toolName: '...' }
// Handle specific scenarios
if (error.code === 'EXECUTION_FAILED' && error.details?.statusCode === 404) {
console.error('Repository not found');
}
}
}Common GitHub API errors:
- 401 Unauthorized — Invalid or expired token
- 403 Forbidden — Insufficient permissions, rate limited, or GHSA disabled
- 404 Not Found — Repository, issue, or user doesn't exist
- 422 Unprocessable Entity — Invalid parameters
- 429 Too Many Requests — Rate limit exceeded
Examples
Search and Report
const matimo = await MatimoInstance.init({ autoDiscover: true });
// Find high-quality TypeScript projects
const results = await matimo.execute('github-search-repositories', {
query: 'language:typescript stars:>5000'
});
console.log(`Found ${results.total_count} matching repositories`);
results.items?.slice(0, 5).forEach(repo => {
console.log(`- ${repo.full_name}: ⭐ ${repo.stargazers_count}`);
});Create and Manage Issues
// Create an issue
const issue = await matimo.execute('github-create-issue', {
owner: 'myorg',
repo: 'myrepo',
title: 'Feature request: Add dark mode',
body: '# Description\nUsers want a dark mode theme\n\n# Solution\nImplement CSS dark mode support'
});
console.log(`Created issue #${issue.number}: ${issue.html_url}`);
// Update the issue
await matimo.execute('github-update-issue', {
owner: 'myorg',
repo: 'myrepo',
issue_number: issue.number,
state: 'closed'
});Pull Request Workflow
// List open PRs
const prs = await matimo.execute('github-list-pull-requests', {
owner: 'kubernetes',
repo: 'kubernetes',
state: 'open',
sort: 'updated'
});
// Merge a PR
if (prs.length > 0) {
const merged = await matimo.execute('github-merge-pull-request', {
owner: 'kubernetes',
repo: 'kubernetes',
pull_number: prs[0].number,
merge_method: 'squash'
});
console.log(`Merged as commit ${merged.sha}`);
}Security Scanning
// List critical security alerts
const alerts = await matimo.execute('github-list-code-alerts', {
owner: 'myorg',
repo: 'myrepo',
state: 'open',
severity: 'critical'
});
// Dismiss false positives
for (const alert of alerts.filter(a => a.rule.id === 'false-positive')) {
await matimo.execute('github-update-code-alert', {
owner: 'myorg',
repo: 'myrepo',
alert_number: alert.number,
state: 'dismissed',
dismissed_reason: 'false positive'
});
}Troubleshooting
"401 Unauthorized"
- Verify
GITHUB_TOKENis set:echo $GITHUB_TOKEN - Token may be expired or revoked — create new one
- For fine-grained PAT, verify it hasn't been expired
"403 Forbidden" for private repos
- Ensure token has
reposcope - For fine-grained tokens, ensure organization/repository is added
- Check GitHub Advanced Security is enabled (for code scanning)
"404 Not Found"
- Verify owner/repo names are correct
- Check repository exists and is accessible with token
- For code scanning, ensure Advanced Security is enabled
Rate limited (429)
- Wait for
x-ratelimit-resettimestamp - Consider implementing request queuing for bulk operations
- Use search filters to reduce unnecessary API calls
- For Enterprise, higher rate limits (15,000/hour) available
Code scanning not available
- Requires GitHub Advanced Security (Enterprise or public repos with premium)
- Verify
security_events:readscope in token - Check repository has security scanning enabled
API Reference
Parameters and Response Schemas
Each tool accepts specific parameters documented in its definition. Common patterns:
Pagination: per_page (1-100, default 30) and page (starting at 1)
Filtering: state, sort, direction, labels, assignee (varies by tool)
Templating: URL parameters use {placeholders} syntax
Responses are validated against output_schema defined in each tool. All responses include status codes in x-github- headers for monitoring rate limits.
HTTP Headers
All requests include:
Accept: application/vnd.github+json
Authorization: Bearer {GITHUB_TOKEN}
X-GitHub-Api-Version: 2022-11-28
Content-Type: application/json (for POST/PATCH/PUT)Rate limit headers in all responses:
x-ratelimit-limit: 5000
x-ratelimit-remaining: 4999
x-ratelimit-reset: 1234567890
x-ratelimit-used: 1Contributing
For bug reports, feature requests, or tool improvements, visit the main Matimo repository CONTRIBUTING guidelines.
License
Part of the Matimo ecosystem. See main repository for licensing information.
Need help? Check the Matimo documentation or open an issue in the main repository.
