Ask nanobot about your GitHub pull requests from your phone

Connect GitHub's remote MCP server to nanobot with a read-only token, limit its tools, and get a weekday list of pull requests waiting on you.

· ranx.cloud

Illustration of a ring of brass keys on a wall hook above a small wooden tray of sorted index cards and a pair of reading glasses

This guide is for developers and maintainers who want to check on their repositories away from the laptop: which pull requests wait for their review, what changed on an issue, whether last night's PR got merged. You connect nanobot to GitHub's hosted MCP server with a token that can only read, trim the tool list so it stays cheap, and set up a weekday message listing the pull requests that need you. Ask from the WebUI or from a chat app such as Telegram.

Setup is done in the nanobot WebUI and on github.com. Labels were checked against nanobot v0.4.0, its MCP presets, and the remote GitHub MCP server docs as of November 2026.

Why the remote preset

nanobot's Apps → MCP catalogue has two GitHub entries. GitHub runs GitHub's server locally through Docker, which needs Docker on the machine running nanobot. GitHub (remote) connects over HTTPS to https://api.githubcopilot.com/mcp/, the server GitHub hosts. It needs nothing installed, authenticates with a personal access token sent as an Authorization: Bearer header, and has no browser sign-in step. Use the remote one.

nanobot calls GitHub from the server; GitHub never calls nanobot. Nothing has to be reachable from outside.

Step 1: Create a fine-grained, read-only token

On GitHub, open Settings → Developer settings → Fine-grained tokens → Generate new token:

Field Value
Token name nanobot
Expiration 90 days (put a calendar reminder on the renewal)
Resource owner your account, or the organization that owns the repositories
Repository access Only select repositories, pick the ones you care about
Permissions → Repository Contents: Read-only, Issues: Read-only, Pull requests: Read-only, Metadata: Read-only (added automatically)

Generate it and copy the token (it starts with github_pat_). For an organization's repositories, the organization may need to approve fine-grained tokens before this one works.

A read-only token is the actual safety boundary here. Even if the agent is talked into calling a write tool, GitHub refuses it. Don't reuse a classic token with the broad repo scope.

Step 2: Add the server in nanobot

  1. In the WebUI, open Apps and go to MCP.
  2. Search for GitHub and pick GitHub (remote). Choose Connect.
  3. Paste the token into GitHub personal access token. Paste only the token; nanobot adds the Bearer prefix.
  4. Choose Enable service, then restart nanobot if the page shows "Restart nanobot to connect updated MCP tools."
  5. Open the server's Manage panel and choose Test. The Tools list should show the server's tools, such as get_me, list_pull_requests, search_pull_requests, pull_request_read, list_issues and issue_read.

Step 3: Cut the tool list down

GitHub's default toolset exposes five groups (context, repos, issues, pull requests, users), several dozen tools in total, and nanobot sends the definition of every enabled tool to the model on every call. That's a few thousand tokens per message before you've asked anything, and a long menu makes small models pick the wrong tool more often.

In Manage → Tools, choose Disable all, then use Search tools to turn these back on:

get_me
search_pull_requests
pull_request_read
list_pull_requests
search_issues
issue_read
list_issues
get_file_contents

Save changes and restart if asked. Leave write tools such as create_pull_request, merge_pull_request or issue_write off. With a read-only token they'd fail anyway, and disabled tools aren't offered to the model at all.

If you'd rather enforce read-only on GitHub's side as well, add a custom server instead of the preset: under Apps → MCP, choose Add MCP, then Custom. Pick the HTTP transport, enter the URL https://api.githubcopilot.com/mcp/readonly, set Authentication to Headers, and enter Headers (JSON):

{
  "Authorization": "Bearer github_pat_...",
  "X-MCP-Toolsets": "context,issues,pull_requests,repos"
}

The /readonly path exposes only read tools, and X-MCP-Toolsets limits which groups load.

Step 4: Ask questions

Start a new topic in the WebUI. Typing @ in the composer opens a menu where you can pick the GitHub server and attach it to the message, which is the most reliable way to make the model use it. Pick it and ask:

Who am I logged in as on GitHub?

get_me should answer with your GitHub username. Then try:

Which open pull requests in acme/api request my review? For each: number,
title, author, how long it has been open, and whether CI passed.
Summarize what changed in acme/api#482 since yesterday, in five lines.
Find open issues labelled "bug" in acme/web with no assignee.

From Telegram there's no @ menu; name the repository and say "on GitHub" in the question. The tools are available in every chat on the instance.

Step 5: A weekday "waiting on you" message

In the chat where you want it (a Telegram DM, or a WebUI topic), ask:

Every weekday at 09:15, use GitHub to find open pull requests where my
review is requested, in any repository the token can see. Reply with at
most 8, oldest first: "#number title (repo, author, N days)". Then list
my own open pull requests that have new review comments since yesterday.
If both lists are empty, reply "Nothing waiting on you."

nanobot creates a scheduled job linked to that chat. Open Automations, find it under My tasks, and run it once to check it works. It uses the timezone in Settings → System → Timezone.

What it costs

GitHub's remote MCP server and fine-grained tokens are free; the GitHub API rate limits for authenticated requests (5,000 requests an hour per user, per GitHub's REST docs) are far above this use.

The model is the cost. A question like "which PRs need my review" takes about three model calls: pick a tool, read the result, write the answer. Search results are verbose JSON, so assume 15,000 input tokens per call with the trimmed tool list and 400 output tokens for the answer:

3 calls × 15,000 = 45,000 input tokens, ~600 output tokens per question

Claude Haiku 5.5 ($0.10 in / $0.50 out per million, OpenRouter, Nov 2026):
  45,000 × 0.10 / 1e6 + 600 × 0.50 / 1e6 = $0.0048 per question
  daily job: 22 runs → $0.11/month; plus 5 questions/workday → $0.53/month

Claude Sonnet 5.5 ($2 / $10):
  45,000 × 2 / 1e6 + 600 × 10 / 1e6 = $0.096 per question
  same usage: ≈ $12.70/month

Prices from the OpenRouter model list. Check your real figures in Settings → Overview → Token usage, which separates Chat from Automations. If the defaults look higher than this, the tool list is usually why: with all default tools enabled, each call carries far more tool definitions.

What goes wrong

Test fails with 401 Unauthorized. The token was pasted with Bearer in front (nanobot adds it), it has expired, or an organization hasn't approved it. Generate a new one and use Update setup on the server.

The model says it has no GitHub access. The server is enabled but nanobot wasn't restarted, or every tool is disabled. Check that the Tools count isn't zero and restart nanobot.

Results miss a repository you can see on github.com. The fine-grained token only covers the repositories you selected. Edit the token on GitHub and add the repository; you don't have to change anything in nanobot.

"Resource not accessible by personal access token". A tool needs a permission the token lacks, for example Actions or Checks for CI status. Add the read-only permission it names, or accept that CI status shows as unknown.

The daily message is long and repeats yesterday's PRs. That's what you asked for: they're still waiting. Ask the job to mark PRs that also appeared yesterday with "(again)", or change the cutoff to "waiting more than 2 days".

A tool call times out. Search across many repositories can be slow. The preset uses a 60-second call timeout; narrow the question to one repository or organization.

Token leaks. The token is stored in nanobot's configuration on the instance. If you ever paste it into a chat by mistake, revoke it on GitHub right away and create a new one; chat history is sent to your model provider.