Skip to main content
Glama

ghark

ghark watches GitHub pull requests and reports new activity to one coding session. It runs as a local stdio MCP server. Claude Code can receive live channel messages. Any MCP client can ask for pending events.

Each server process owns its subscriptions. No webhook endpoint, public host, or shared service is required. The process polls GitHub while the session is open. It stops when the session ends.

Requirements

  • Python 3.11 or later

  • A GitHub personal access token in GH_TOKEN or GITHUB_TOKEN

  • uv to run the server

  • Claude Code for channel delivery; other clients can use pending_events

The token needs read access to the repositories and pull requests you watch. Fine-grained tokens need Pull requests: read-only, Contents: read-only, and read access to checks and commit statuses.

Related MCP server: GitHub PR Reviewer MCP

Run

Install the project in editable mode:

uv sync

Add it to Claude Code as a local MCP server:

claude mcp add --scope user ghark -- uv run --directory /path/to/checkout ghark

To enable channel delivery in Claude Code, start the session with the channel server enabled:

claude --dangerously-load-development-channels server:ghark

Custom channels are a Claude Code preview feature. Without the channel flag, the tools still work and events remain available through pending_events.

For Codex, add a stdio server entry to ~/.codex/config.toml:

[mcp_servers.ghark]
command = "uv"
args = ["run", "--directory", "/path/to/checkout", "ghark"]

Codex does not receive MCP channel pushes. Ask it to call pending_events when you want to check for activity.

Tools

  • subscribe watches its pr argument. It accepts a GitHub PR URL or OWNER/REPO#N.

  • unsubscribe takes the same pr argument and stops watching it.

  • subscriptions lists this process's active PRs.

  • pending_events returns unread events and reports any events dropped at the queue limit.

The server reports commits, reviews, comments, check status changes, merge state changes, and PR closure, merge, or reopen activity. It combines events from a PR into a short notification. Merged and closed PRs leave the watch list.

Subscriptions and unread events live in memory. They end with the stdio server process. A restarted session must subscribe again. Channel delivery is best effort. The pending queue holds up to 1,000 events; pending_events reports how many older events were dropped when that limit was reached.

Development

uv run ghark

Check formatting and lint with:

uv run ruff format --check ghark
uv run ruff check ghark

Run the behavior and MCP stdio checks with:

uv run python -m unittest discover -s tests -v

Set GHARK_POLL_SECONDS to change the polling interval. The default is 30 seconds. Set GHARK_BATCH_SECONDS to change the event coalescing window. The default is 5 seconds.

See DESIGN.md for architecture and behavior details.

Available Tools

4 tools
pending_eventsB

Read pending events and report any events dropped at the queue limit.

NameRequiredDescriptionDefault

No parameters

TDQS

B3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions reporting dropped events but never says whether reading consumes/removes pending events, what auth is needed, or what the response looks like — a major gap for a queue-reading tool that may be stateful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the primary action is stated first and the secondary reporting behavior follows. Brevity is appropriate for a zero-parameter tool, though the sentence is a bit thin given the behavioral unknowns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations, no output schema, and no sibling routing guidance, the description does not cover enough: the critical question of whether reading pending events drains the queue is unaddressed, and the return shape of the dropped-events report is unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description correctly implies no inputs are needed, and there is nothing further to clarify.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (read pending events) plus a secondary behavior (report dropped events at queue limit), so the agent knows exactly what operation this is. It does not explicitly distinguish itself from siblings like subscribe/unsubscribe, though the read semantics imply the difference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus the subscription-management siblings, nor any preconditions or exclusions. Usage is only implied by the name and the phrase 'read pending events'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subscribeB

Watch a GitHub pull request for new activity.

NameRequiredDescriptionDefault
prYesGitHub PR URL or OWNER/REPO#NUMBER.

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden and largely drops it. It does not say whether subscribing is idempotent, whether it requires GitHub auth or specific scopes, whether events accumulate into 'pending_events', how long the watch persists, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, front-loaded sentence with zero wasted words. It is arguably too terse given how much behavioral information is missing, but there is no padding or burying of the key point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations, no output schema, and sibling tools that clearly interact with this one ('unsubscribe', 'subscriptions', 'pending_events'), an agent needs to know how subscription state and events flow. None of that lifecycle context is present, leaving the definition under-specified for its role.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter 'pr' is fully documented in the schema (URL or OWNER/REPO#NUMBER), so the high coverage baseline of 3 applies. The description adds no format examples, validation notes, or edge-case guidance beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('watch') and resource ('GitHub pull request') and adds the purpose ('for new activity'), so the intent is unambiguous. It does not explicitly differentiate itself from the sibling 'unsubscribe' or explain the relationship to 'pending_events', so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for new activity' implies the use case of monitoring a PR, but there is no explicit when-to-use, no prerequisites (auth scope, whether a subscription must be unsubscribed first), and no mention of the alternatives that the siblings 'unsubscribe' and 'subscriptions' provide.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subscriptionsA

List pull requests watched by this session.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does add the useful scoping detail that results are limited to what *this session* has watched, but it omits ordering, size limits, and what the entries contain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero waste, front-loaded with the verb and resource, and carrying the one qualifier that matters (session scope).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is trivially simple — no parameters, no annotations, no output schema — so the description is not dangerous, but with no output schema it should at least sketch what a listed pull request looks like or in what order they return. As written the agent knows what it gets in aggregate but not the shape of the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The only semantic content is the scope of the list, which the description does state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb-and-resource pair ('List pull requests watched by this session') and the session scoping implicitly separates it from the subscribe/unsubscribe siblings, which mutate that watch list. It does not explicitly name those siblings, so an agent still has to infer the pairing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the description makes clear this is the read side of the subscribe/unsubscribe pair, but it never says when to call it versus pending_events, nor whether it is safe to call at any time. No explicit when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unsubscribeC

Stop watching a pull request.

NameRequiredDescriptionDefault
prYesGitHub PR URL or OWNER/REPO#NUMBER.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations at all, the description carries the full burden for a state-mutating tool, yet says nothing about idempotency, auth requirements, whether it errors on a non-subscription, or what the response looks like. Only the bare intent is conveyed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, front-loaded sentence with zero waste. It is somewhat under-specified rather than padded, but structure-wise nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an annotation-free mutation tool with no output schema, the description should cover success/failure semantics and subscription state implications. None of that is present, leaving meaningful gaps an agent would hit at call time.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single parameter `pr` is fully documented in the schema (GitHub PR URL or OWNER/REPO#NUMBER), so the 100% coverage baseline of 3 applies. The description adds no format or scoping detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Stop watching a pull request" is a specific verb plus resource, and reads clearly as the inverse of the sibling `subscribe`. It doesn't explicitly name or contrast with that sibling, so the differentiation is inferable rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus `subscribe` or `subscriptions`, no prerequisites, and no mention of what happens when the user isn't subscribed. The agent must guess at the operational context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedpending_events
    • First observedsubscribe
    • First observedsubscriptions
    • First observedunsubscribe

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a clearly distinct operation: subscribe and unsubscribe are opposite pair, subscriptions lists watches, and pending_events reads queued events. There is no realistic confusion between listing subscriptions and reading pending events, as they operate on different resources.

Naming Consistency4/5

Names are all snake_case and thematically coherent (subscribe/unsubscribe/subscriptions pair nicely). The only minor deviation is pending_events being a pure noun while the others read as verbs/plurals, but overall the pattern is predictable and readable.

Tool Count4/5

Four tools is well-matched to the narrow, focused purpose of watching pull requests for a session. It is on the lean side but each tool pulls its weight, so nothing feels redundant.

Completeness4/5

The watch lifecycle is fully covered: add (subscribe), remove (unsubscribe), list (subscriptions), and consume events (pending_events). Minor gaps exist around identifying the session or inspecting individual events, but the core workflow is complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers