Christophy52 downloadsRead, comment on, and approve/request-changes on GitHub issues & PRs inside Obsidian. GitHub stays the source of truth.
Review GitHub issues and pull requests in Obsidian — built for reading and reviewing Markdown spec / design documents, which render poorly on GitHub's web UI.
You read and discuss specs in Obsidian's native Markdown, and every action writes straight back to GitHub. Comments and reviews are made as the token owner, and approvals use GitHub's native PR review, so branch protection recognises them. GitHub stays the single source of truth — nothing is stored locally.
Organised around the spec-review flow:
.claude/mcp.json automatically, so
a client like Claudian picks it up with no manual setup; then just ask "what's this PR about?".
Your repo's files come for free, since those clients run with the vault as their working directory.
No port, no token, no running service — the client spawns the server on demand with node, and
your GitHub token never leaves the plugin. See
Connect a Claude client.See docs/ARCHITECTURE.md for the module layout.
main.js, manifest.json, and styles.css from the
latest release.<your-vault>/.obsidian/plugins/github-review/.git clone <this-repo> && cd obsidian-github-review
npm install
npm run build # produces main.js
./scripts/link-to-vault.sh /path/to/vault # symlink main.js / manifest.json / styles.css into the vault
Then enable the plugin in Obsidian. Use npm run dev for a watch build and Cmd/Ctrl+R to reload.
Open Settings → GitHub Review:
| Setting | What it does |
|---|---|
| GitHub token | Your fine-grained PAT (stored in the vault's data.json). |
| Follow this vault's GitHub repository | On: scope the queue to the repo this vault belongs to. Off: use the manual list below. |
| Repositories | owner/repo per line, used when not following the vault repo (or none detected). |
| Include closed issues & PRs | Also list closed/merged items. |
| Auto-refresh interval (seconds) | Poll open views with conditional requests; 0 disables. |
| Claude client integration (MCP) | Expose the open PR/issue to a Claude client via a local stdio MCP server (no port, no token, read-only). On by default; Copy config is for non-Claudian clients. |
When the integration is enabled, the plugin writes the issue/PR you're viewing to a small store file
and writes a tiny stdio MCP server (mcp-stdio.js, embedded in main.js) into its own plugin
folder. A Claude client spawns that server on demand with node — no port, no running service, no
token (any client that runs Claude Code already has Node). For
Claudian you don't configure anything — the plugin registers
the server in your vault's .claude/mcp.json (which Claudian reads), so it shows up automatically.
The agent is told to call get_current_item for "this / the current PR or issue", so it pulls the
context without you pasting a link. Other tools: get_changed_file (a file's content/diff) and
get_item (pin to a specific item you have open, by owner/repo/number/type). The server is
read-only and holds no token — it only reads the store file, which contains the items you have open
(no token is written anywhere; it never leaves the plugin).
Other Claude clients (e.g. the claude CLI): use Copy config and add the entry to that
client (it's a standard stdio MCP server: command + args).
Heads-up: Claudian keeps its own conversation history and isn't tied to a specific PR/issue — switching review tabs doesn't switch its session, and its history won't auto-load per item. Use
get_itemto pin a conversation to one open item, orget_current_itemfor whichever is active.
Use a fine-grained personal access token scoped to the repos you review, with:
| Permission | Level |
|---|---|
| Contents | Read |
| Pull requests | Read & write |
| Issues | Read & write |
| Metadata | Read |
The token is stored in plaintext in the vault's
data.json. Don't sync a vault containing it to an untrusted location. GitHub also forbids approving your own PR — the Approve option is disabled then.
@ in any comment box to mention a repo bot.npm run dev # esbuild watch -> main.js
npm run build # tsc typecheck + production bundle
npm run lint # eslint
npm run test:unit # tsc --noEmit + mocha unit tests
npm run test:e2e # WebdriverIO against a real sandboxed Obsidian (downloads Obsidian on first run)
.github/workflows/ci.yml runs lint + build + unit + end-to-end tests (the E2E spin up a real
sandboxed Obsidian) on every push and pull request, so a green CI means the requirement tests
actually passed.
To require a green CI before merging into main, enable a branch protection rule (or
repository ruleset) on main that requires the test status check and "branches up to date".
A workflow can't enforce this on its own — it's a one-time GitHub repository setting
(Settings → Branches / Rules).
Versions follow the Obsidian convention (the git tag is the version, no v prefix):
npm version patch # bumps manifest.json + versions.json, commits, and tags
git push --follow-tags
Pushing the tag triggers the Release workflow, which builds and attaches main.js,
manifest.json, styles.css, and github-review.zip to a GitHub release.