GitHub + Linear Dev Workflows
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GITHUB_TOKEN | No | GitHub personal access token with the repo and read:user scopes. Alternatively, store it in your OS keychain with `github-linear-mcp login github`. A variable set in your client's config always wins over the keychain. | |
| LINEAR_API_KEY | No | Linear personal API key. Alternatively, store it in your OS keychain with `github-linear-mcp login linear`. | |
| NOTION_API_KEY | No | Notion integration secret (ntn_…). Share the pages it should see with the integration. Alternatively, store it in your OS keychain with `github-linear-mcp login notion`. | |
| TAVILY_API_KEY | No | Tavily API key. Alternatively, store it in your OS keychain with `github-linear-mcp login tavily`. | |
| SLACK_BOT_TOKEN | No | Slack bot token (xoxb-…) from your own Slack app. Alternatively, store it in your OS keychain with `github-linear-mcp login slack`. | |
| GOOGLE_CLIENT_ID | No | Client id of your own Google OAuth client, used for browser sign-in. | |
| FIRECRAWL_API_KEY | No | Firecrawl API key. Alternatively, store it in your OS keychain with `github-linear-mcp login firecrawl`. | |
| GOOGLE_CLIENT_SECRET | No | Client secret of your own Google OAuth client, used for browser sign-in. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| github_actions_list_workflow_runsB | List CI runs, most recent first. The single |
| github_actions_list_jobs_for_runA | List a run's jobs, each with its conclusion and its failing steps named. This is what turns 'the run failed' into 'the |
| github_actions_download_job_logsA | Read a failing job's log. Returns the last 200 lines plus every line that looks like an error, with the line numbers and the log's real length — not the whole file, which is routinely megabytes. Use this after |
| linear_issue_createA | Create an issue. |
| slack_chat_post_messageA | Send a message to a Slack channel, private group, or DM. Provide |
| github_pulls_listA | List pull requests. Filter by |
| linear_attachments_for_urlA | Find which issues an external URL is attached to. This is the tool for 'is this pull request already linked to an issue?'. |
| linear_search_issuesA | Search issues by text, across titles and descriptions. Set |
| linear_attachment_createA | Link an issue to something outside Linear. Linear deduplicates by URL: creating an attachment whose URL is already on the issue updates that one rather than adding a second. |
| github_dependabot_list_alertsA | List a repository's Dependabot alerts: which dependency, how severe, and the first version that fixes it. Several filters take a comma-separated list, so |
| github_code_scanning_list_alertsA | List code scanning alerts, each with the rule that fired and the file and line it fired on. Filter to one pull request with |
| github_secret_scanning_list_alertsA | List secret scanning alerts: which pattern matched, which provider, and whether the credential is still valid. The detected secret itself is never returned by this tool — it is dropped from the response whatever the request asked for, because triage does not need it. Requires administrator access. |
| github_releases_get_latestA | Get the latest published release — GitHub's definition, meaning the most recent release that is neither a draft nor a prerelease. Not simply the newest one. |
| github_repos_compare_commitsA | Compare two refs and get what is in one and not the other: the status, how far ahead or behind, the commits and the changed files. |
| notion_pages_createA | Create a page — as a subpage of another page, or as a row of a database by giving its |
| github_search_issuesA | Search issues and pull requests across GitHub with qualifiers, e.g. 'repo:owner/name is:issue is:open label:bug'. Use this when the repository is unknown or the filter is richer than issues_list_for_repo supports. Rate limited to 30 requests per minute. |
| linear_issues_listA | List issues, optionally filtered. Conditions on one filter object combine with AND. To find a team's open work, filter on team.key and state.type. |
| slack_conversations_openA | Open a direct message with one person, or a group message with up to eight. The channel id for a following |
| github_pulls_list_requested_reviewersA | List who has been asked to review and has not answered yet. A reviewer drops off this list once they submit, so an empty list means nobody is outstanding — not that nobody was asked. |
| slack_users_listA | List members of the workspace. Use this to resolve a person's name to the user ID that Slack mentions and filters expect. |
| linear_issue_getA | Get one issue with its description, comments, sub-issues, relations and attachments. Accepts either the issue's UUID or its human identifier, such as 'ENG-123'. |
| github_git_refs_getA | Get a reference and the commit SHA it points at — how you read a branch's current head before building on it. |
| github_git_refs_createA | Create a branch or tag pointing at an existing commit. The reference must be fully qualified, like 'refs/heads/my-branch'. |
| github_pulls_createA | Open a pull request from |
| slack_conversations_historyB | Fetch recent messages from a Slack channel. |
| github_repos_list_commitsA | List commits, newest first. Narrow with |
| gdocs_documents_createA | Create a blank document with a title. Only the title is honoured — the document is created empty. To add content, call this and then documents_batch_update with the returned documentId. |
| gdocs_documents_getA | Read a document's full structural content. The document ID is the long string in its URL, between '/d/' and '/edit'. Pass include_tabs_content=true for a document with several tabs, since the default response covers only the first. |
| linear_issue_relation_createA | Link two issues as blocking, duplicate, related or similar. 'blocks' and 'duplicate' are directional: the issue in |
| gcalendar_events_insertC | Create a calendar event; returns details of the event. |
| slack_conversations_repliesA | Fetch a thread of messages. Pass the parent message's |
| github_issues_list_for_repoA | List issues in a repository. Note that GitHub counts pull requests as issues, so results include both; the ones that are pull requests are marked |
| github_issues_create_commentA | Post a comment on an issue or pull request. Pull requests take their own number here — GitHub treats them as issues for commenting. |
| firecrawl_monitor_createB | Create a scheduled monitor for scrape, crawl, or search targets. |
| firecrawl_monitor_checks_listC | List checks for a monitor. |
| github_search_codeA | Search code across GitHub. Only default branches are indexed and only files under 384 KB. The query needs a real search term, not just qualifiers. This endpoint allows ten requests per minute and returns at most 1,000 results. |
| gcalendar_events_listC | List events matching a given search filter. |
| github_notifications_listA | List your unread notifications — mentions, review requests, assignments — most recently updated first. This is how an agent finds out it is needed without polling repositories. |
| github_actions_list_pending_deploymentsA | List the environments a run is waiting on for approval, and who can approve them. This is where a run sits when it is neither failing nor progressing. |
| github_actions_review_pending_deploymentsA | Approve or reject a run's pending deployments. Takes the environment ids from |
| github_actions_list_runs_for_workflowA | List the runs of one workflow, most recent first — 'is this pipeline green', rather than 'is anything red'. The same single |
| github_checks_list_annotationsA | List a check run's annotations: each failure with the file, the line range, a level and a message, already extracted by whoever ran the check. The cheapest way to find out why a build is red — try this before downloading any log. GitHub returns at most 50 per page. |
| gsheets_spreadsheets_values_appendC | Appends values to a spreadsheet. |
| github_actions_get_run_usageA | Get a run's total run time and its billable milliseconds per runner operating system. Billable minutes apply only to private repositories on GitHub-hosted runners. GitHub has this endpoint closing down. |
| github_pulls_getA | Get a single pull request, including its mergeability and the counts of changed files, additions and deletions. These details are only present on this endpoint, not on |
| github_pulls_list_filesA | List the files a pull request changes, with per-file additions, deletions and patch text. A large pull request returns a lot of diff: keep |
| github_pulls_get_diffA | Get a pull request's whole change as a unified diff, in one call. The same endpoint as |
| tavily_searchA | Execute a real-time web search optimized for AI agents. Use when sources are unknown or current web context is needed. Prefer search_depth advanced with chunks_per_source 3 for stronger evidence per source. |
| github_search_repositoriesA | Search repositories with qualifiers, e.g. 'topic:cli language:go stars:>500'. Rate limited to 30 requests per minute. |
| github_repos_getA | Get a repository's metadata, including its default branch and topics. |
| github_repos_list_contributorsA | List contributors, most commits first — who to ask about a repository. GitHub links only the first 500 author email addresses to accounts; the rest come back anonymous. An empty repository returns an empty object. |
| github_repos_create_or_update_fileA | Create a file or replace an existing one, in a single commit. Write the content as plain text. To replace a file, read it first and pass its |
| github_repos_get_readmeA | Get the repository's README, decoded to text. GitHub picks the preferred file itself across the spellings a repository might use, which saves guessing at |
| github_repos_list_languagesA | List a repository's languages with bytes of code each — the quickest way to find out what a repository is written in before reading any of it. Answers with an object keyed by language, so there is nothing to page. |
| github_pulls_updateA | Update a pull request's title, body, state or base branch. Closing one is |
| gsheets_spreadsheets_values_updateC | Sets values in a range of a spreadsheet. |
| github_repos_get_contentA | Read a file, or list a directory. Pass an empty |
| notion_pages_update_markdownA | Replace a page's content with Markdown, which Notion parses into blocks. This replaces the whole body, so read it first if you mean to edit rather than overwrite. |
| github_releases_updateA | Update a release; anything omitted is left unchanged. Publishing a draft is this call with |
| connectA | Connect one app this server uses. For an app that issues keys, says where to get one and the terminal command that stores it. For Google, once the user's own OAuth client is set, starts the browser sign-in and returns at once: the user approves in the browser and the next call works. To see which apps are connected, call |
| connection_statusA | See which apps this server is connected to, and how to connect each one that is not. Changes nothing. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| setup | Connect every app this server uses, the quickest way each one allows. |
| failing_ci_to_bug_with_the_log_excerpt | A red main branch becomes an owned issue with the failing step quoted, not a channel ping. |
| link_every_pr_to_its_linear_issue | No orphan PRs, so cycle reports and changelogs stop missing work. |
| security_alerts_to_linear | Critical alerts get owners and due dates in the tracker the team actually reads. |
| leaked_secret_to_page_a_human | An exposed key is an urgent issue and a loud message within minutes. |
| release_to_changelog_page_and_announcement | Every release has a readable changelog without a release manager writing it. |
| standup_digest_per_person | Yesterday's PRs and today's issues in a DM, so standup is about blockers. |
| stale_review_nudger | PRs waiting more than a day get a polite DM to the right reviewer. |
| linear_issue_to_branch_and_draft_pr | Starting work on an issue sets up the branch, the PR and the link. |
| incident_timeline_to_postmortem_draft | The timeline is assembled from what happened, and action items are tracked from minute one. |
| postmortem_actions_tracked_to_done | Follow-ups from the postmortem become linked issues with a review date. |
| slack_bug_report_to_linear | The thread becomes an issue with repro steps, and the thread gets the link. |
| github_issues_mirrored_into_linear | Open-source reports enter the internal tracker without double triage. |
| vendor_deprecation_to_affected_files | A deprecation notice arrives already mapped to the code that uses the old API. |
| on_call_handoff | The next on-call starts with open urgents and unread alerts in one message. |
| deploy_approval_from_slack | Production deploys gated on an explicit 'approve' in a thread, with the reviewer on record. |
| flaky_test_ledger | Tests that fail and pass on retry get counted until one crosses the line and gets an issue. |
| ci_spend_report | Which workflows burn the minutes, weekly, before the bill does it. |
| pr_to_design_note_in_docs | A large PR gets a readable explanation for reviewers outside the team. |
| dependency_choice_with_real_repo_health | Library choices recorded with stars, activity and bus factor, not vibes. |
| slack_debate_to_adr_in_the_repo | The decision and its reasons get committed next to the code they govern. |
| repo_onboarding_doc | A new engineer gets a map of an unfamiliar repo and who to ask. |
| stale_pr_cleanup | Month-old PRs are closed with a note and the author is told, so the queue means something. |
| todo_fixme_debt_register | Debt hiding in comments becomes a list someone can prioritise. |
| repo_docs_to_engineering_wiki | The wiki mirrors docs/ in the repo instead of drifting from it. |
| release_credits_for_contributors | Every release thanks the people who made it, by name. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 61 tools
Most tools have clearly distinct provider+resource+action scopes, and descriptions often explicitly disambiguate near-neighbors (e.g. actions_list_jobs_for_run vs download_job_logs vs checks_list_annotations). However, several pairs overlap enough to risk misselection: github_pulls_get vs github_pulls_get_diff, github_repos_get_content vs github_repos_get_readme, and github_actions_list_workflow_runs vs github_actions_list_runs_for_workflow.
The dominant pattern is service_resource_action (e.g. github_pulls_list, linear_issue_create, notion_pages_create), which is predictable and readable. Minor deviations exist: connect and connection_status lack a service prefix, and GitHub Actions tools use variable ordering (actions_get_run_usage, actions_list_workflow_runs), but nothing is chaotic.
61 tools is far beyond the 15-tool well-scoped range and spans at least eight services (GitHub, Linear, Google Docs/Calendar/Sheets, Slack, Notion, Firecrawl, Tavily). Even for a multi-app integration server, this breadth creates heavy surface area and cognitive load, making selection harder than it needs to be.
Coverage is broad but shallow in critical areas. For a dev-workflow server, there is no GitHub issue creation or update, no PR merge operation, no Linear issue update/delete, no Slack channel listing, and Google Docs batch update is referenced in descriptions but not exposed as a tool, creating dead ends in core workflows.