mcpField
G
github-tools

github-tools

Local
github.com/craft-agentVersion Control0Updated today

About github-tools

github-tools gives coding agents GitHub operations through the GitHub CLI, covering issues, project boards, pull requests, repositories, releases, and Actions. It is delivered as plugins for several agent harnesses or as an MCP server, with skills that explain how to use each toolset.

Key features

  1. 01Manage issues and their relationships
  2. 02Read and operate on pull requests and stacks
  3. 03Create and maintain project boards
  4. 04Access repositories, releases, and Actions
  5. 05Support multiple agent harnesses with skills

Use cases

  1. 01Create and update GitHub issues in agent workflows
  2. 02Inspect pull requests, review changes, and merge
  3. 03Add issues or pull requests to project boards
  4. 04Enable GitHub tools across different agent harnesses

MCP support

github-tools can run as an MCP server for other MCP hosts and is also supplied as an MCP server and skills in plugin setups such as Claude Code and Codex. It exposes toolsets for GitHub issues, pull requests, projects, and more.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"craft-agent-github-tools": {
"command": "npx",
"args": [
"-y",
"@craftsamo/github-tools"
]
}
}
}
Run commandnpx -y @craftsamo/github-tools

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npm@craftsamo/github-tools0.15.0

Tools

20

Saved tool list · updated today

ParameterTypeRequiredDescription
kindstringNolist: the kind to match, such as bug: the organization's Issue Type of that name, else the type:<kind> label.
repostringNoowner/name; defaults to the working tree's repository (its origin). Used for a bare number.
issuestringNoview: the issue, as 12, #12, owner/repo#12 or its URL.
labelstringNolist: a label every issue must carry.
limitintegerNolist: the most issues to return (default 30).
querystringNolist: more GitHub search words, such as "sort:updated-desc crash"; repo:, org: and user: are refused.
stateenumNolist: open, closed or all (default open).open | closed | all
methodenumYes"view" reads one issue in full; "list" lists issues.view | list
parentstringNolist: an issue (12, #12, owner/repo#12 or URL) whose sub-issues to list instead of searching.
assigneestringNolist: a login, "@me", or "none" for unassigned issues.
commentsintegerNoview: how many of the latest comments to include (default 5, 0 for none).
milestonestringNolist: a milestone title, or "none" for issues without one.

Details

From the project README

github-tools

GitHub tools for coding agents: issues, boards, pull requests, repositories, releases and Actions.

The tools cover issues, project boards, pull requests and native stacks, repositories, releases and Actions, through the GitHub CLI. One implementation, delivered to each agent harness in the form that suits it best.

HarnessDeliveryPinned by
OpenCode V2native plugin (npm package, with skills)the version in the package
OpenCode V1native plugin (npm package, no skills)the version in the package
Claude Codeplugin: MCP server and skillsthe release tag, as the ref
Codexplugin: MCP server and skillsthe release tag, as the ref
Grok Buildplugin: MCP server and skillsthe release tag, as @ref
Antigravityplugin: MCP server and skillsthe release tag's tree URL
Hermes Agentnative plugin (Python, calls the command line)the release commit, as the SHA
other MCP hostMCP server from npmthe version in the package

0.3.0 moved the package from craftsamo/agent-github to craft-agent/github-tools and renamed it: npm @craftsamo/github-tools (was @craftsamo/agent-github, now removed from npm), plugin and MCP server github-tools, programs github-tools and github-tools-cli, settings GITHUB_TOOLS_*. Allow rules, plugin installs and MCP configurations written for 0.2.0 change; the tool IDs do not.

The tools need Node.js 24 or later and the GitHub CLI, authenticated as you. docs/conventions.md describes how the tools are named and how they behave.

Install

Install from a release, never from the default branch: a release is a tag whose commit carries the built dist/, and the default branch does not. In the commands below, <version> is a release's version (1.2.3) and <sha> is the commit its tag names:

gh api repos/craft-agent/github-tools/commits/v<version> --jq .sha
OpenCode

OpenCode V2 takes the package and its options in opencode.json:

{
  "plugins": [
    {
      "package": "@craftsamo/github-tools@<version>",
      "options": { "toolsets": ["issues", "pull_requests", "projects"] }
    }
  ],
  "permissions": [{ "action": "github_*", "resource": "*", "effect": "ask" }]
}

OpenCode V1 takes the package as a string, or as a pair with its options:

{
  "plugin": [["@craftsamo/github-tools@<version>", { "toolsets": ["issues", "pull_requests", "projects"] }]],
  "permission": { "github_*": "ask" }
}

OpenCode allows any action no rule names, so the plugin's request is granted silently unless a rule says ask. Read tools never ask, so the github_* glob is safe.

V1 registers no skills. Unpack the package and copy its skills/* folders into ~/.config/opencode/skills/:

npm pack @craftsamo/github-tools@<version>
tar -xzf craftsamo-github-tools-<version>.tgz
mkdir -p ~/.config/opencode/skills
cp -r package/skills/* ~/.config/opencode/skills/
rm -rf package craftsamo-github-tools-<version>.tgz
Claude Code
claude plugin marketplace add craft-agent/github-tools#v<version>
claude plugin install github-tools@craft-agent
Codex
codex plugin marketplace add craft-agent/github-tools --ref v<version>
codex plugin add github-tools@craft-agent

Codex turns - into _ in server names, so it shows the tools as mcp__github_tools__github_issue_*. It starts the MCP server in the plugin's install directory and passes no roots, so the server takes each call's directory from what Codex sends with the call: its sandbox state, which the server asks for, else the one workspace it names.

The plugin declares default_tools_approval_mode = "writes": Codex asks before every tool not marked read-only. A user's [plugins."<plugin>".mcp_servers.<server>] setting can only tighten it. Setting auto there yields prompt (reads asked too), since Codex treats auto and writes as incomparable.

Grok Build
grok plugin install craft-agent/github-tools@v<version> --trust

Grok starts the MCP server in the session's working directory, so inside a clone a bare issue number names an issue of that repository.

Antigravity

Install from the tree of the release tag, never from the default branch, which has no built dist/; Antigravity clones the tag into ~/.gemini/config/plugins/github-tools.

agy plugin install https://github.com/craft-agent/github-tools/tree/v<version>
Hermes Agent

Hermes installs a commit, not a tag, and the plugin installs disabled:

hermes plugins install craft-agent/github-tools --ref <sha>
hermes plugins enable github-tools

If a Hermes gateway is already running, restart it (hermes gateway restart) to load the plugin.

The plugin runs the Node it found when Hermes started. If a version manager removes that version while Hermes runs, a call looks for Node again; when it finds none, restart Hermes from a shell where node runs.

Any other MCP host

Add the server to the host's MCP configuration. Flags go in args:

{
  "mcpServers": {
    "github-tools": {
      "command": "npx",
      "args": ["-y", "@craftsamo/github-tools@<version>", "--toolsets", "issues,pull_requests,projects"]
    }
  }
}

Tools and skills

Each toolset comes with a skill that tells an agent how to use its tools. A skill names its toolset under metadata in its frontmatter (metadata: { toolset: issues }, written as a block). OpenCode V2 and Hermes register it only when the settings register at least one of that toolset's tools, so a profile with the toolset off, or with all its tools removed, does not see it; a skill without a toolset is always registered. Claude Code, Codex, Grok Build and Antigravity install the skill folder whole and pass the settings only to the MCP server, so they list every skill whatever the settings select. OpenCode V1 registers no skills, and its copied skills are all listed too.

Issues (issues)
ToolWhat it doesClass
github_issue_readview one issue in full, or list a repository's issues or a parent's sub-issues, with their issue fieldsread
github_issue_createcreate an issue with its kind, labels, assignees, milestone, parent and blocked-by issues, issue fields and a boardadd
github_issue_editchange the title, body (or append to it), kind, labels, assignees, milestone or issue fieldsoverwrite
github_issue_commentcomment on an issueadd
github_issue_closeclose with a reason (completed, not_planned, duplicate)overwrite
github_issue_reopenreopen a closed issueoverwrite
github_issue_relateset the parent, sub-issues, blocked-by and blocking issues, sending only what differsidempotent
github_issue_developcreate a branch on GitHub linked to the issue, or return the one already linkedidempotent

The skill is github-issues, shown as github-tools:github-issues in Claude Code and github-tools:issues in Hermes. An issue's kind is the organization's Issue Type of that name when it defines one, otherwise a type:<kind> label. Issue fields (Priority, Effort, Start date, Target date and any others) are the organization's own, so only an organization's repositories have them; list filters by one with field.<name>:<value> in query.

Pull requests and stacks (pull_requests)
ToolWhat it doesClass
github_pr_readview one pull request in full, list a repository's pull requests, read its checks (waiting up to 45 seconds, with failed job logs) or its diffread
github_pr_createopen a pull request from a pushed branch, with labels, assignees, reviewers, milestone, closing issues, a board and attachmentsadd
github_pr_editchange the title, body (or append to it), base, labels, assignees, reviewers, milestone or closing issuesoverwrite
github_pr_commentcomment, with attachmentsadd
github_pr_reviewapprove, request changes or comment, with line commentsadd
github_pr_readymark ready for review, or turn back into a draftidempotent
github_pr_closecloseoverwrite
github_pr_reopenreopen a closed pull requestoverwrite
github_pr_mergemerge, with the open layers below it in a stack when askedadministrative
github_stack_readview a native stack by its number or a pull request in it, or list a repository's stacksread
github_stack_linkjoin pull requests into a stack, or add them on top of oneidempotent
github_stack_unlinkdissolve a stack, leaving its pull requests openoverwrite

The skill is github-pull-requests, shown as github-tools:github-pull-requests in Claude Code and github-tools:pull-requests in Hermes. The tools do not push: push the branch first and pass the commit it pushed as head_sha, so a pull request opens, is reviewed or merges on exactly that commit. Closing issues are kept as Closes #N lines in the body, since GitHub has no other way to link them. Stacks use GitHub's REST stack endpoints, so the gh stack extension is not needed. Attachments need gh 2.99 or newer.

Project boards (projects)
ToolWhat it doesClass
github_project_readview a board with its fields and views, list boards, or item_list a board's itemsread
github_project_createcreate a board, or reuse the one of that title, with the standard fields and viewsidempotent
github_project_field_ensureadd a field, or the missing options of a single selectidempotent
github_project_view_ensureadd a saved view with its fields, columns, grouping and sortidempotent
github_project_linklink a board to a repository of the same owneridempotent
github_project_unlinkunlink a board from a repositoryidempotent
github_project_item_addput an issue or pull request on a board, or return its item, with field valuesidempotent
github_project_item_createcreate a draft item with field valuesadd
github_project_item_editset or clear field values, and change a draft's title and bodyoverwrite
github_project_item_archivearchive an itemoverwrite
github_project_item_unarchivebring an archived item backoverwrite
github_project_item_convertturn a draft into an issue, with its kind, labels and milestoneadd

The skill is github-projects, shown as github-tools:github-projects in Claude Code and github-tools:projects in Hermes. A board is named by its number, owner/N, URL or title (Roadmap when none is given), and found among the boards linked to the repository, then its organization's, then the viewer's. The token needs the project scope (gh auth refresh -s project). No API sets a roadmap view's date fields, so after github_project_create set the Roadmap view's "Date fields" to Start and Target in the web UI. A column that mirrors an organization's issue field is read like any other, but its value is the issue's own: the board tools refuse to set or clear it, and github_issue_edit does both. github_project_field_ensure with issue_field: true adds such a column, and github_project_create with dates: "issue_fields" uses the issue fields Start date and Target date as an organization board's dates.

Repositories (repos)
ToolWhat it doesClass
github_repo_readview a repository's settings, features, merge settings and the viewer's permission, or list an owner's repositoriesread
github_repo_createcreate a repository, empty or from a templateadministrative
github_repo_editchange the description, homepage, default branch, topics, features or merge settingsoverwrite
github_repo_visibilitymake a repository public, private or internaladministrative
github_repo_archivearchive a repositoryadministrative
github_repo_unarchiveunarchive a repositoryoverwrite
github_label_readlist a repository's labelsread
github_label_createcreate a labeladd
github_label_editrename, recolor or redescribe a labeloverwrite
github_label_deletedelete a label, removing it from every issue and pull requestadministrative
github_milestone_readlist a repository's milestones, with progressread
github_milestone_createcreate a milestoneadd
github_milestone_editchange a milestone's title, due date or description, or close or reopen itoverwrite
github_ruleset_readlist the rulesets and classic branch protection, or view one rulesetread
github_ruleset_createcreate a ruleset with its refs, rules and bypass actorsadministrative
github_ruleset_editreplace parts of a ruleset, stopping as stale when it changed since it was readadministrative
github_ruleset_deletedelete a rulesetadministrative

The toolset is off by default: add repos to toolsets. The skill is github-repos, shown as github-tools:github-repos in Claude Code and github-tools:repos in Hermes. Most settings changes need admin permission on the repository, and rulesets on a private repository need a paid plan. Deleting, renaming, transferring or forking a repository is left to the user.

Releases (releases)
ToolWhat it doesClass
github_release_readlist a repository's releases, drafts included, or view one by tag with its notes and commitread
github_release_createcreate a draft release, optionally with generated notesadd
github_release_editchange the title, notes, prerelease flag, latest status or a draft's targetoverwrite
github_release_publishpublish a draft, stopping as stale when its commit differs from head_shaadministrative
github_release_deletedelete a release and its assets, keeping its tagadministrative

The toolset is off by default: add releases to toolsets. The skill is github-releases, shown as github-tools:github-releases in Claude Code and github-tools:releases in Hermes. A new release is always a draft; assets are not covered yet.

Actions (actions)
ToolWhat it doesClass
github_workflow_readlist a repository's workflows, disabled ones included, or view one with its file at a branch or tagread
github_run_readlist workflow runs by branch, workflow, status, event or commit, or view one with its jobs and failed logs, waiting while it runsread
github_workflow_runstart a workflow by hand with its inputs, stopping as stale when the ref differs from head_shaadministrative
github_run_rerunre-run a finished run's failed jobs, every job, or one jobadministrative
github_run_cancelcancel a queued or running runadministrative

The toolset is off by default: add actions to toolsets. The skill is github-actions, shown as github-tools:github-actions in Claude Code and github-tools:actions in Hermes. Every Actions write asks each time, since a workflow can deploy or publish whatever its name says. Enabling or disabling a workflow, deleting a run and downloading artifacts are not covered yet.

Planning

github-planning adds no tool. It says how to plan with the issue and board tools: when work is one issue or a parent issue with sub-issues, how to size a sub-issue, how steps outside the repository (an approval, a vendor's answer) enter the plan, the form of each body, the order to file in, and what a later change rewrites in a body or says in a comment. It is shown as github-tools:github-planning in Claude Code and github-tools:planning in Hermes. It is linked to the issues toolset, which it cannot work without, and says what to skip when the board tools are off.

Adding a tool

  1. Write the spec in src/core/<domain>/<verb>.ts with defineTool: an ID <prefix>_<domain>_<verb>, a title and description, the Zod argument and output schemas, its toolset and write class, and execute(args, context). A write tool also gives targets(args, context): what the call writes to, as a permission rule should name it.
  2. Test it beside the spec (<verb>.test.ts), calling it through invoke as the entry points do. A tool that runs a program is tested against a fake of that program on PATH; no test reaches a real service.
  3. List it in src/tools.ts. A new toolset goes into toolsets in src/project.ts (and defaultToolsets when it is on by default), a setting of the package's own into options (and OPTIONS in project.py with config_schema in plugin.yaml), and a variable the tool reads besides the settings into toolVariables.
  4. Add or update the toolset's skill, skills/<prefix>-<toolset>/SKILL.md, whose frontmatter names the toolset under metadata.
  5. Run pnpm run build && pnpm run manifests to list the tool in plugin.yaml and its variables in Codex's manifest, then describe it under "Tools and skills".

docs/conventions.md has the rules each step follows.

Reads and writes

Every read tool is named <prefix>_<domain>_read. Reads can run unasked; writes are confirmed by the harness.

HarnessReads without asking
OpenCodealways; the plugin asks only before a write
Claude Codethe rule mcp__plugin_github-tools_github-tools__*_read in permissions.allow of ~/.claude/settings.json
Codexalways; Codex runs tools that declare readOnlyHint unasked, as the read tools do
Grok Buildgrok --allow 'MCPTool(github-tools__*_read)' --allow 'MCPTool(github_*_read)' (both rules; see below)
Antigravitythe rule mcp(github-tools_github-tools/<tool id>) in permissions.allow, one for each read tool
Hermesalways; the plugin asks only before a write

Where a write is asked about, and where it is not:

  • OpenCode grants any action no rule names, so a write runs unasked unless a rule asks for it: add the github_* rule shown under OpenCode.
  • Codex asks before every write because of the plugin's approval mode. Under codex exec it refuses with "MCP tool call requires approval, but approval policy is never".
  • Grok Build under grok -p refuses a write it cannot ask about, unless it is allowed beforehand.
  • Grok Build calls the plugin's tools through its use_tool tool, and the agent often names a tool without its server first. Grok checks the rules against the name as given, so the server-qualified rule alone does not match that first call. The second rule matches the short name; a write still matches neither.
  • Antigravity asks before any MCP tool no rule allows, reads included, and names the plugin's server github-tools_github-tools (plugin, then server). agy -p refuses a tool it cannot ask about.
  • Hermes hermes chat -q refuses a write it cannot ask about; hermes -z and --yolo skip approval, so writes then run unasked.

Settings

Every entry point takes the same settings. A flag wins over its environment variable, and an option or setting wins over the variable too.

SettingFlagVariableMeaning
toolsets--toolsetsGITHUB_TOOLS_TOOLSETSissues, pull_requests, projects, repos, releases, actions or all; default issues, pull_requests and projects
read_only--read-onlyGITHUB_TOOLS_READ_ONLYregisters no tool that writes; wins over every other setting
tools--toolsGITHUB_TOOLS_TOOLSsingle tools to add by ID, whatever their toolset
exclude_tools--exclude-toolsGITHUB_TOOLS_EXCLUDE_TOOLSsingle tools to remove by ID; wins over tools and toolsets
confirm--confirmGITHUB_TOOLS_CONFIRMMCP server only: harness (default) or elicitation, as the conventions say
language--languageGITHUB_TOOLS_LANGUAGEnative plugins only: the approval prompt's language, such as ja
emoji——Hermes only: the emoji shown beside each toolset, by toolset name ("" for none)

Lists are comma-separated in a flag or a variable. A package's own settings, listed in options in src/project.ts, take a row each here and are read the same way. GitHub Actions does not let a secret or configuration variable be named GITHUB_*, so in a workflow pass a value through env: from a secret of another name, e.g. GITHUB_TOOLS_READ_ONLY: ${{ secrets.TOOLS_READ_ONLY }} (setting such an environment variable in env: is allowed). Where each harness reads them:

  • OpenCode takes the plugin options shown above, with lists as arrays and read_only as a boolean, and falls back to the variables. V2 runs plugins in its background service, which keeps the environment it started with: a variable set where opencode run starts has no effect until the service is restarted in that environment (opencode service restart). V1 runs plugins in its own process.

  • Hermes takes plugins.entries.github-tools.settings in config.yaml:

    plugins:
      entries:
        github-tools:
          settings:
            toolsets: [issues, pull_requests, projects]
            read_only: false
            exclude_tools: [github_pr_merge]
    

    Without a language setting, the approval card follows Hermes's own display.language (or HERMES_LANGUAGE), the language of its approval buttons, and else stays in English. The plugin passes its own environment to the command line it runs, so the variables work too. A running gateway keeps the environment it started with; restart it (hermes gateway restart) after changing one.

  • Claude Code, Grok Build and Antigravity start the plugin's server without flags and pass it the client's environment, so set the variables in the environment the harness runs in.

  • Codex passes a plugin's MCP server only a few basic variables (such as PATH and HOME) and those the plugin's manifest names, which are the variables above: set them in the environment Codex runs in. A variable the tools read besides the settings belongs in toolVariables in src/project.ts; pnpm run manifests adds it to the manifest after the settings' variables. To pass flags, or to give the server a variable the package does not name, add the server under [mcp_servers] in Codex's config.toml instead of using the plugin: flags go in args, env_vars names the variables to forward from Codex's environment, and env sets fixed values.

    [mcp_servers.github-tools]
    command = "npx"
    args = ["-y", "@craftsamo/github-tools@<version>", "--toolsets", "issues,pull_requests,projects"]
    env_vars = ["GITHUB_TOOLS_READ_ONLY"]
    

Layout

  • src/project.ts — the package's name, tool ID prefix, setting prefix, toolsets, tool options and the other variables its tools read.
  • src/core/ — the tool contract and the tools, free of any harness and of the project's names.
  • src/tools.ts — the list of every tool, which each entry point registers.
  • src/words.ts — the translations of the tools' words, per language, which the native plugins use in their approval prompts.
  • src/mcp/ — the MCP server, built to dist/mcp.js and run by github-tools.
  • src/opencode/ — the OpenCode plugin, built to dist/opencode.js.
  • src/cli/ — the command line the Hermes plugin calls, built to dist/cli.js and run by github-tools-cli.
  • src/hermes/, plugin.yaml and __init__.py — the Hermes plugin.
  • skills/ — one skill per toolset and one for planning with them, skills/<name>/SKILL.md, which every harness that takes skills loads from the package or plugin root; the native plugins load only those of the toolsets that are on.
  • .claude-plugin/, .codex-plugin/, .agents/plugins/, .mcp.json, .antigravity-plugin/ and mcp_config.json — the plugin manifests of the other harnesses. Codex reads .codex-plugin/plugin.json; a root plugin.json would make it load the plugin as an Agent Plugin, whose tool budget hides tools past a fixed size. The root .mcp.json is the configuration Grok Build reads (with ${CLAUDE_PLUGIN_ROOT}, the variable both Grok Build and Claude Code expand); when working on this repository in Claude Code, decline the project MCP server it offers from that file.

How a release is made is in RELEASING.md.

License

AGPL-3.0 with Commons Clause

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.