@foundation0/git
v1.3.4
Published
Foundation 0 Git API and MCP server
Maintainers
Readme
git
@foundation0/git exposes a generated Git API object where methods follow the shape repo.issue.create(...), repo.pr.merge(...), etc.
The API client maps GH-style feature paths to Gitea REST endpoints and executes real HTTP requests through fetch.
Install
Install globally:
pnpm add -g @foundation0/gitRun MCP server through npm without a global install:
npx -y -p @foundation0/git f0-git-mcp --helpUsing pnpm:
pnpm dlx @foundation0/git f0-git-mcp --helpInstallation in this monorepo
From repo root:
pnpm installRun tests:
pnpm --filter @foundation0/git testQuick start
import { createGitServiceApi } from '@foundation0/git'
const api = createGitServiceApi({
config: {
platform: 'GITEA',
giteaHost: 'https://gitea.example.com',
giteaToken: process.env.GITEA_TOKEN,
},
defaultOwner: 'example-org',
defaultRepo: 'example-repo',
})You can also import the singleton:
import { gitServiceApi } from '@foundation0/git'All methods return:
type GitServiceApiExecutionResult = {
mapping: GitApiFeatureMapping
request: {
url: string
method: string
headers: Record<string, string>
query: string[]
body?: unknown
}
status: number
ok: boolean
body: unknown
}Core request shapes
Write methods accept request fields directly (recommended), or you can set the raw request body with data / json / payload / requestBody.
await api.repo.issue.create({
title: 'Bug report',
body: 'Describe issue details',
labels: ['bug'],
})
// equivalent explicit-body form
await api.repo.issue.create({
data: { title: 'Bug report', body: 'Describe issue details', labels: ['bug'] },
})Use headers to pass custom headers and query for additional URL params.
await api.repo.issue.list({
headers: { 'X-Request-Id': 'local' },
query: { state: 'open', limit: 20, page: 1 },
})Popular workflow examples
1) Issue lifecycle (most used)
// List issues in the default repo
await api.repo.issue.list()
// Create a new issue
await api.repo.issue.create({
data: {
title: 'Login fails with 401',
body: 'Repro: open login page and click submit.',
labels: ['bug'],
},
})
// View an issue
await api.repo.issue.view('17')
// Comment on an issue
await api.repo.issue.comment('17', {
data: { body: 'We are investigating this now.' },
})
// Edit title/body
await api.repo.issue.edit('17', {
data: {
title: 'Login fails with 401 (investigating)',
body: 'Updated with steps to reproduce.',
},
})
// Close and reopen
await api.repo.issue.close('17', { reason: 'not_planned' })
await api.repo.issue.reopen('17')2) Pull request workflow
// Open a pull request
await api.repo.pr.create({
data: {
title: 'chore: improve error handling',
body: 'Adds retries and better messaging.',
head: 'feature/error-handling',
base: 'main',
},
})
// List and inspect PRs
await api.repo.pr.list({ query: { state: 'open' } })
await api.repo.pr.view('42')
// Add a review comment
await api.repo.pr.comment('42', {
data: { body: 'Looks good, please add one test for this branch.' },
})
// Manage PR lifecycle
await api.repo.pr.close('42')
await api.repo.pr.reopen('42')
await api.repo.pr.merge('42')3) Release flow
await api.repo.release.create({
data: {
tag_name: 'v1.2.0',
name: 'v1.2.0',
body: 'Changelog and upgrade notes.',
},
})
await api.repo.release.list()
await api.repo.release.view('v1.2.0')
await api.repo.release.delete('v1.2.0')4) Repository setup and sync
// Read current repo
await api.repo.view()
// Create repository for authenticated user
await api.repo.create({ data: { name: 'new-repo', description: 'Automation workspace' } })
// Fork and sync mirror repo
await api.repo.fork()
await api.repo.sync()5) Team triage with labels
await api.repo.label.listManaged()
await api.repo.label.upsert('priority-high', {
color: '#d73a4a',
description: 'Initial escalation label',
})
await api.repo.label.getByName('priority-high')
await api.repo.label.upsert('priority-high', {
color: '#fbca04',
description: 'Escalated issue',
})
await api.repo.label.deleteByName('priority-high')6) Search and discovery
await api.search.issues({
query: {
q: 'repo:example-org/example-repo is:open',
sort: 'created',
},
})
await api.search.prs({
query: {
q: 'repo:example-org/example-repo is:pr is:open',
sort: 'updated',
},
})
await api.search.repos({
query: {
q: 'name:example-repo',
limit: 10,
},
})7) CI workflow dispatch
await api.workflow.list()
await api.workflow.view('ci.yml')
await api.workflow.run('ci.yml', {
data: {
ref: 'main',
},
})
await api.workflow.disable('ci.yml')
await api.workflow.enable('ci.yml')8) Security material for automation
await api.secret.list()
await api.variable.list()
await api.variable.set('CANARY', {
data: {
value: 'true',
},
})Targeting a specific repository
Defaults can be replaced per call by passing owner/repo arguments.
await api.repo.issue.create('acme', 'infra', {
data: {
title: 'Issue in another repo',
body: 'Cross-repo task',
},
})Notes
- Some endpoints expose top-level methods too (for example
api.issue.create(...)), butrepo.*is the canonical usage style for this package. - This package currently ships with Gitea mapping, with
PLATFORM/GITEA_*configuration ready for multi-platform expansion. - Use the generated feature matrix/spec to discover every mapped command before adding new workflows.
