← Octocode MCP

Octocode MCP 18.2.2

npm · octocode-mcp · current release

14
Tools
0
Resources
0
Templates
0
Prompts

Observation

Observed 2026-08-15T22:07:50.241Z using mcpSecurity-inventory. Status: succeeded. Negotiated protocol: 2025-06-18.

Server capabilities
{
  "tools": {
    "listChanged": true
  }
}

Tools 14

ToolCategoryAnnotationsRisk
ghGetFileContentGithub | Read a file or a specific region from a GitHub repository. | Use after ghSearchCode/ghViewRepoStructure when you know the repo path — not for discovery. If a ghSearchCode snippet already answers the question, STOP — don't re-read the file. Least-cost path: unknown/large file → minify:"symbols" outline, then a region (matchString or startLine+endLine). fullContent only for genuinely small whole-file reads, never to scan. A small structured/config file (package.json, tsconfig, lockfile) → read it whole with minify:"none"/fullContent, don't minify it — compaction can elide object boundaries and break exact key/value membership. For a literal value or quote, read the defining region with minify:"none" and copy the exact bytes. Every response reports the file's full size (totalLines + sourceChars) and isPartial. A matchString/region read is a SLICE, not the whole file — it can cut a nested object mid-way; never conclude a key/field/value is absent or empty from a partial slice: continue via charOffset/next, or re-read the whole small structured file (package.json/tsconfig/lockfile) with minify:"none". Report only bytes you fetched — never invent a field, value, or quote. Param relations: choose one extraction mode: fullContent OR matchString OR startLine+endLine. matchString pairs with contextLines and returns matchRanges (padded windows, not the exact hit) plus matchedLines (exact hit lines — see matchString field); charOffset continues isPartial pages. type:"directory" materializes localPath for local tools when clone is enabled.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "owner": {
            "type": "string",
            "description": "Repository owner (user or org)."
          },
          "repo": {
            "type": "string",
            "description": "Repository name, without the owner."
          },
          "branch": {
            "description": "Branch, tag, or commit SHA; omit for the default branch.",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "startLine": {
            "description": "Requires endLine; exclusive with fullContent/matchString.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "endLine": {
            "description": "Requires startLine; must be >= startLine.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "fullContent": {
            "description": "Whole file; SMALL files only; exclusive with range/match. For large/unknown files use minify:symbols then a region instead.",
            "type": "boolean"
          },
          "matchString": {
            "description": "Anchor returning slices plus matchRanges ({start,end} padded windows) and matchedLines (exact hit line numbers).",
            "type": "string"
          },
          "matchStringIsRegex": {
            "description": "Makes matchString a regex.",
            "type": "boolean"
          },
          "matchStringCaseSensitive": {
            "description": "Case-sensitive matchString (default insensitive).",
            "type": "boolean"
          },
          "forceRefresh": {
            "description": "Bypass the 24h fetch cache and re-read from GitHub.",
            "type": "boolean"
          },
          "type": {
            "default": "file",
            "description": "\"file\" reads; \"directory\" materializes localPath.",
            "type": "string",
            "enum": [
              "file",
              "directory"
            ]
          },
          "contextLines": {
            "description": "Extra source lines around each match/anchor.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "charOffset": {
            "description": "Use pagination.nextCharOffset.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charLength": {
            "description": "Characters per content window; continue via the returned next offset when partial.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50000
          },
          "minify": {
            "description": "\"symbols\" outline, \"standard\" compact, \"none\" exact.",
            "type": "string",
            "enum": [
              "none",
              "standard",
              "symbols"
            ]
          }
        },
        "required": [
          "owner",
          "repo",
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub File Content Fetch",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghSearchCodeGithub | Search code contents or file paths across GitHub repositories. | Use for remote code/file discovery. Start match:"path" + concise for filenames; match:"file" only when snippets matter. Skip if you already have the path (ghGetFileContent) or need repo discovery (ghSearchRepos). One-shot: if a match:"file" snippet already contains the answer (a field value, a symbol name, a state), STOP — that snippet is the evidence; don't chain a structure view or a content read to "confirm" it. Param relations: owner+repo scopes tightly; path scopes a directory prefix; extension/language/filename narrow candidates; keywords are ANDed. Follow into ghGetFileContent, ghViewRepoStructure, or clone for AST/LSP proof. Empty/unindexed is not absence.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "keywords": {
            "description": "ANDed; keep a phrase as one item; alternatives need separate queries.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "owner": {
            "description": "Repository owner (user or org).",
            "type": "string"
          },
          "repo": {
            "description": "Repository name, without the owner.",
            "type": "string"
          },
          "extension": {
            "description": "File extension filter, e.g. \"ts\" (no dot).",
            "type": "string"
          },
          "filename": {
            "description": "Exact filename filter.",
            "type": "string"
          },
          "path": {
            "description": "Repo path prefix, not a full file path.",
            "type": "string"
          },
          "language": {
            "description": "GitHub language filter, e.g. \"typescript\".",
            "type": "string"
          },
          "match": {
            "default": "file",
            "description": "\"file\" searches file contents and returns snippets with matchIndices. \"path\" searches only file paths/names — no snippets, far cheaper; use it to confirm a file exists before reading it. (Unlike ghSearchRepos/ghSearchPullRequests, where `match` instead selects which text FIELDS to search — a different concept sharing this name.)",
            "type": "string",
            "enum": [
              "file",
              "path"
            ]
          },
          "limit": {
            "description": "Results per page (paginate with page).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "concise": {
            "description": "Flat \"owner/repo:path\" rows.",
            "type": "boolean"
          }
        }
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Code Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghSearchCommitsGithub | Walk a GitHub repository's commit history for a path or range. | Commit archaeology — when/why a file/area changed — not current code (ghSearchCode/ghGetFileContent) or PRs (ghSearchPullRequests). No message-keyword filter — only path/since/until/author/committer narrow the walk. Looking for a specific change (e.g. a rename) with no known SHA/path/date? Try ghSearchPullRequests/ghSearchCode for a lead first; otherwise page raw history by eye. One commit's exact changes: set base:"SHA^", head:"SHA", includeDiff:true — its files+patches in one call; don't page history or fetch files. owner+repo identify the repo; path scopes a file/dir (trailing / = subtree); since/until bound the window; branch selects a ref; includeDiff is heavy — scope to one SHA or a tight window; itemsPerPage/page walk history. For code identity, clone + local/LSP.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "owner": {
            "type": "string",
            "description": "Repository owner."
          },
          "repo": {
            "type": "string",
            "description": "Repository name."
          },
          "path": {
            "description": "File/dir prefix; trailing / scopes the subtree.",
            "type": "string"
          },
          "since": {
            "description": "Only commits after this point. ISO date (\"2026-01-01\") or a relative window (\"30d\", \"2w\", \"6m\", \"1y\").",
            "type": "string"
          },
          "until": {
            "description": "Only commits before this point. ISO date or a relative window (same formats as since).",
            "type": "string"
          },
          "branch": {
            "description": "Ref to walk; defaults to the default branch.",
            "type": "string"
          },
          "author": {
            "description": "Filter to commits by this author (GitHub login or email).",
            "type": "string"
          },
          "committer": {
            "description": "Filter to commits by this committer (GitHub login or email).",
            "type": "string"
          },
          "base": {
            "description": "Compare mode: set base+head (branch/tag/sha) to diff two refs (base...head) instead of walking history — returns status, ahead/behind counts, and the commits between them.",
            "type": "string"
          },
          "head": {
            "description": "Compare mode: the head ref for the base...head comparison.",
            "type": "string"
          },
          "itemsPerPage": {
            "default": 30,
            "description": "Commits returned per page (walk with page).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "includeDiff": {
            "default": false,
            "description": "Attach per-commit diffs. Scope it: with base:SHA^/head:SHA it returns one commit's full diff in a single call; heavier on a broad history walk.",
            "type": "boolean"
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "filePage": {
            "description": "With includeDiff: page through the changed-file list (walk with pagination.nextFilePage).",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "charOffset": {
            "description": "With includeDiff: start offset into a file's patch window — copy from patchPagination.nextCharOffset, do not compute.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charLength": {
            "description": "With includeDiff: characters of patch per window; continue via the returned next offset when hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "limit": {
            "description": "Commits per page — alias of itemsPerPage (preferred when both are set).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          }
        },
        "required": [
          "owner",
          "repo"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Commit History",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghSearchIssuesGithub | Search GitHub issues, or read one issue's body and comments. | Issue triage/archaeology — bug reports, feature threads — not PRs (ghSearchPullRequests) or code (ghSearchCode). List mode: keywordsToSearch+filters+sort/page. Detail mode: owner+repo+issueNumber + content selectors; body/comment windows continue via charOffset/commentBodyOffset, comments page via commentPage. totalCount appears only when one page is the full set (the endpoint also returns PRs, filtered out — so per-page counts aren't totals); an empty page with hasMore:true was PR-only — follow nextPage.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "owner": {
            "description": "Repository owner (user or org).",
            "type": "string"
          },
          "repo": {
            "description": "Repository name, without the owner.",
            "type": "string"
          },
          "keywordsToSearch": {
            "description": "Issue search terms.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "issueNumber": {
            "description": "Switches to issue detail mode; needs owner+repo.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "concise": {
            "description": "Issue list triage; ignored with issueNumber.",
            "type": "boolean"
          },
          "state": {
            "description": "open or closed.",
            "type": "string",
            "enum": [
              "open",
              "closed"
            ]
          },
          "assignee": {
            "description": "Filter by assigned GitHub login.",
            "type": "string"
          },
          "author": {
            "description": "Filter by issue author login.",
            "type": "string"
          },
          "commenter": {
            "description": "Filter by a login that commented.",
            "type": "string"
          },
          "mentions": {
            "description": "Filter by a mentioned login.",
            "type": "string"
          },
          "label": {
            "description": "Label name(s); multiple are ANDed.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "created": {
            "description": "Created-date filter, e.g. \">2024-01-01\" or \"2024-01-01..2024-06-30\".",
            "type": "string"
          },
          "updated": {
            "description": "Updated-date filter (same format as created).",
            "type": "string"
          },
          "closed": {
            "description": "Closed-date filter (same format as created).",
            "type": "string"
          },
          "comments": {
            "description": "Comment-count range filter (\">5\"); not comment content.",
            "type": "string"
          },
          "reactions": {
            "description": "Reaction-count range filter (\">10\").",
            "type": "string"
          },
          "match": {
            "description": "Keyword fields: title, body, comments.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "title",
                "body",
                "comments"
              ]
            }
          },
          "sort": {
            "description": "created, updated, comments, reactions, best-match.",
            "type": "string",
            "enum": [
              "created",
              "updated",
              "best-match",
              "comments",
              "reactions"
            ]
          },
          "order": {
            "description": "asc/desc; asc+created helps archaeology.",
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ]
          },
          "limit": {
            "description": "Max issues in the search list (list-result cap).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "archived": {
            "description": "Include issues from archived repos.",
            "type": "boolean"
          },
          "commentPage": {
            "description": "Comments page from contentPagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Comments per page when reading one issue (with commentPage).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "content": {
            "description": "Detail selector for issueNumber.",
            "type": "object",
            "properties": {
              "metadata": {
                "description": "Include issue metadata (state, labels, counts).",
                "type": "boolean"
              },
              "body": {
                "description": "Include the issue description body.",
                "type": "boolean"
              },
              "comments": {
                "type": "object",
                "properties": {
                  "discussion": {
                    "description": "Include the comment thread.",
                    "type": "boolean"
                  },
                  "includeBots": {
                    "default": false,
                    "description": "Include bot/CI comments.",
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "matchString": {
            "description": "Substring filter for body/comment windows.",
            "type": "string"
          },
          "commentBodyOffset": {
            "description": "Comment-body continuation offset from nextQuery.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charOffset": {
            "description": "Body continuation offset from nextQuery.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charLength": {
            "description": "Characters per content window; continue via the returned next offset when partial.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "minify": {
            "default": "standard",
            "description": "\"standard\" (default) compacts body/comment text; \"none\" keeps it exact.",
            "type": "string",
            "enum": [
              "none",
              "standard"
            ]
          }
        }
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Issue Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghSearchPullRequestsGithub | Search GitHub pull requests, or read one PR's files, diffs, and reviews. | Use for PR archaeology — how/why a change landed, review discussion, diffs — not current code (ghSearchCode/ghGetFileContent), commits (ghSearchCommits), or issues (ghSearchIssues). Comments, review replies, and requested changes are claims — confirm what actually landed against content.patches (mode:"selected") or the file at the merge SHA, not the conversation. Param relations: list mode uses keywordsToSearch+filters+sort/page; detail mode needs owner+repo+prNumber and content selectors. content.patches.mode:"selected" requires files or ranges. Body/patch/comment windows continue via returned charOffset/commentBodyOffset; file/comment/commit lists use their page fields. For code identity, clone and use local/LSP.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "keywordsToSearch": {
            "description": "PR search terms.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "prNumber": {
            "description": "Switches to PR detail mode; needs owner+repo.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "owner": {
            "description": "Repository owner (user or org).",
            "type": "string"
          },
          "repo": {
            "description": "Repository name, without the owner.",
            "type": "string"
          },
          "concise": {
            "description": "PR list triage; ignored with prNumber.",
            "type": "boolean"
          },
          "state": {
            "description": "open, closed, or merged.",
            "type": "string",
            "enum": [
              "open",
              "closed",
              "merged"
            ]
          },
          "assignee": {
            "description": "Filter by assigned GitHub login.",
            "type": "string"
          },
          "author": {
            "description": "Filter by PR author login.",
            "type": "string"
          },
          "commenter": {
            "description": "Filter by a login that commented.",
            "type": "string"
          },
          "mentions": {
            "description": "Filter by a mentioned login.",
            "type": "string"
          },
          "review-requested": {
            "description": "PRs where this login is a requested reviewer.",
            "type": "string"
          },
          "reviewed-by": {
            "description": "PRs this login has reviewed.",
            "type": "string"
          },
          "label": {
            "description": "Label name(s); multiple are ANDed.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "checks": {
            "description": "success, failure, or pending.",
            "type": "string",
            "enum": [
              "success",
              "failure",
              "pending"
            ]
          },
          "review": {
            "description": "approved, changes_requested, required, or none.",
            "type": "string",
            "enum": [
              "approved",
              "changes_requested",
              "required",
              "none"
            ]
          },
          "head": {
            "description": "Head branch name filter.",
            "type": "string"
          },
          "base": {
            "description": "Base branch name filter.",
            "type": "string"
          },
          "created": {
            "description": "Created-date filter, e.g. \">2024-01-01\" or \"2024-01-01..2024-06-30\".",
            "type": "string"
          },
          "updated": {
            "description": "Updated-date filter (same format as created).",
            "type": "string"
          },
          "closed": {
            "description": "Closed-date filter (same format as created).",
            "type": "string"
          },
          "merged-at": {
            "description": "Merged-date filter (same format as created).",
            "type": "string"
          },
          "comments": {
            "description": "Comment-count range filter (\">5\"); not comment content.",
            "type": "string"
          },
          "reactions": {
            "description": "Reaction-count range filter (\">10\").",
            "type": "string"
          },
          "draft": {
            "description": "true = only drafts; false = exclude drafts.",
            "type": "boolean"
          },
          "match": {
            "description": "Keyword fields: title, body, comments.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "title",
                "body",
                "comments"
              ]
            }
          },
          "sort": {
            "description": "created, updated, comments, reactions, best-match.",
            "type": "string",
            "enum": [
              "created",
              "updated",
              "best-match",
              "comments",
              "reactions"
            ]
          },
          "order": {
            "description": "asc/desc; asc+created helps archaeology.",
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ]
          },
          "limit": {
            "description": "Max PRs in the search list (list-result cap).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "archived": {
            "description": "Include PRs from archived repos.",
            "type": "boolean"
          },
          "filePage": {
            "description": "Changed-files page from contentPagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "commentPage": {
            "description": "Comments page from contentPagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "commitPage": {
            "description": "PR commits page from contentPagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per page when reading one PR's comments/files/commits (with page).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "reviewMode": {
            "description": "\"full\" fetches all PR detail surfaces.",
            "type": "string",
            "const": "full"
          },
          "content": {
            "description": "Detail selector for prNumber.",
            "type": "object",
            "properties": {
              "metadata": {
                "description": "Include PR metadata (state, refs, counts).",
                "type": "boolean"
              },
              "body": {
                "description": "Include the PR description body.",
                "type": "boolean"
              },
              "changedFiles": {
                "description": "Include the changed-file list with +/- counts.",
                "type": "boolean"
              },
              "patches": {
                "type": "object",
                "properties": {
                  "mode": {
                    "default": "none",
                    "description": "\"none\", \"selected\", or \"all\"; selected is cheapest.",
                    "type": "string",
                    "enum": [
                      "none",
                      "selected",
                      "all"
                    ]
                  },
                  "files": {
                    "description": "Restrict selected patches to these files (mode:\"selected\").",
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "ranges": {
                    "description": "Line ranges for selected patch hunks.",
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "file": {
                          "type": "string",
                          "description": "File the line range applies to."
                        },
                        "additions": {
                          "description": "Added-side line numbers to include.",
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 1000000000
                          }
                        },
                        "deletions": {
                          "description": "Deleted-side line numbers to include.",
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 1000000000
                          }
                        }
                      },
                      "required": [
                        "file"
                      ]
                    }
                  }
                }
              },
              "comments": {
                "type": "object",
                "properties": {
                  "discussion": {
                    "description": "Include the PR conversation timeline.",
                    "type": "boolean"
                  },
                  "reviewInline": {
                    "description": "Include inline review comments (threads via in_reply_to_id).",
                    "type": "boolean"
                  },
                  "includeBots": {
                    "default": false,
                    "description": "Include bot/CI comments.",
                    "type": "boolean"
                  },
                  "file": {
                    "description": "Filter comments to one file path.",
                    "type": "string"
                  }
                }
              },
              "reviews": {
                "description": "Include review verdicts per reviewer.",
                "type": "boolean"
              },
              "commits": {
                "description": "PR-bound commits selector.",
                "type": "object",
                "properties": {
                  "list": {
                    "description": "Include the PR's commit list.",
                    "type": "boolean"
                  },
                  "includeFiles": {
                    "description": "Attach per-commit file changes.",
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "matchString": {
            "description": "Substring filter for body/patch/comment windows.",
            "type": "string"
          },
          "commentBodyOffset": {
            "description": "Comment-body continuation offset from nextQuery.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charOffset": {
            "description": "Body/patch continuation offset from nextQuery.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charLength": {
            "description": "Characters per content window; continue via the returned next offset when partial.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "minify": {
            "default": "standard",
            "description": "\"standard\" compact patches; \"none\" exact diff; \"symbols\" not available.",
            "type": "string",
            "enum": [
              "none",
              "standard"
            ]
          }
        }
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Pull Request Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghSearchReposGithub | Discover GitHub repositories by name, topic, language, or popularity. | Find candidate repos before code search; skip when owner/repo is known (go straight to ghSearchCode/ghViewRepoStructure). Start concise:true, then inspect with ghViewRepoStructure/ghSearchCode. keywords ANDed; topics also required but sparse; owner scopes/enumerates; match picks searched text fields; sort/range rank candidates. Empty → drop filters/topics or broaden language/owner.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "keywords": {
            "description": "ANDed; keep a phrase as one item; alternatives need separate queries.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "topicsToSearch": {
            "description": "Sparse required topics; pair with keywords/language.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "description": "Primary language filter, e.g. \"rust\".",
            "type": "string"
          },
          "owner": {
            "description": "Repository owner (user or org).",
            "type": "string"
          },
          "stars": {
            "description": "Star range: \">100\", \"10..50\".",
            "type": "string"
          },
          "forks": {
            "description": "Fork range: \">50\", \"10..100\".",
            "type": "string"
          },
          "goodFirstIssues": {
            "description": "Good-first-issue count range, e.g. \">5\".",
            "type": "string"
          },
          "updated": {
            "description": "Last push date: \">2024-01-01\" or \"a..b\".",
            "type": "string"
          },
          "created": {
            "description": "Creation date: \">2023-01-01\" or \"a..b\".",
            "type": "string"
          },
          "size": {
            "description": "Repo size in KB: \">1000\", \"50..500\".",
            "type": "string"
          },
          "match": {
            "description": "Which text fields to search: name, description, and/or readme. Defaults to name+description; add 'readme' for broader, slower full-text search. (Unlike ghSearchCode, where `match` instead selects file-contents vs file-paths — a different concept sharing this name.)",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "name",
                "description",
                "readme"
              ]
            }
          },
          "sort": {
            "default": "best-match",
            "description": "stars, forks, updated, help-wanted-issues, best-match.",
            "type": "string",
            "enum": [
              "stars",
              "forks",
              "help-wanted-issues",
              "updated",
              "best-match"
            ]
          },
          "limit": {
            "description": "Results per page (paginate with page).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "archived": {
            "description": "true = archived only; default excludes archived.",
            "type": "boolean"
          },
          "visibility": {
            "description": "\"public\" or \"private\" (private needs token scope).",
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          },
          "license": {
            "description": "SPDX id, e.g. \"mit\".",
            "type": "string"
          },
          "concise": {
            "description": "Flat \"owner/repo\" rows for triage.",
            "type": "boolean"
          }
        }
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Repository Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
ghViewRepoStructureGithub | Browse a GitHub repository's directory tree. | Orient a repo/tree before fetching files, or verify paths/branches after 404s. Know a filename fragment? ghSearchCode(match:"path") is cheaper. Follow structure[] paths into ghGetFileContent or a clone sparsePath.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "owner": {
            "type": "string",
            "description": "Repository owner (user or org)."
          },
          "repo": {
            "type": "string",
            "description": "Repository name, without the owner."
          },
          "branch": {
            "description": "Ref; fallback warning means default branch was used.",
            "type": "string"
          },
          "path": {
            "description": "Repo-relative directory; \"\"/\".\" for root.",
            "type": "string"
          },
          "maxDepth": {
            "description": "Tree recursion depth.",
            "type": "integer",
            "minimum": 0,
            "maximum": 20
          },
          "page": {
            "description": "Advance only on hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per result page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 200
          },
          "include": {
            "description": "Optional repo enrichments (each adds ~1 API call, fetched concurrently): \"sizes\" per-file bytes; \"languages\" byte breakdown + dominant language; \"contributors\" top contributors; \"branches\"; \"tags\". Repo-level (ignore path) except \"sizes\".",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "sizes",
                "languages",
                "contributors",
                "branches",
                "tags"
              ]
            }
          }
        },
        "required": [
          "owner",
          "repo"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "GitHub Repository Structure Explorer",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive
localFindDeadCodeLocal | Find likely-unreferenced exports and dead-code clusters via whole-repo reachability analysis. | Repo-wide dead-export candidates — not single-symbol checks (use lspGetSemantics references/callers). One pass builds a file/symbol graph (native AST, no per-symbol round-trips) and walks reachability from entrypoints, so it scales with repo size, not candidate count. Catches mutually-referencing dead clusters (files that only call each other, unreachable from any entrypoint) that a one-symbol check misses. Retention is symbol-level: a same-file call retains its callee only if the caller is live; named re-exports are followed through export* barrels to the entrypoint. Each candidate carries viaHeuristic: "reexport-chain" (chain ended with no consumer — most fragile, verify first) or "lexical-count" (no import, no unexplained same-file use). Candidates, not proof — run next.verifyReferences (a prefilled lspGetSemantics references query) per candidate; zero references = confirmed dead. Follow file/line anchors into localGetFileContent or lspGetSemantics.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "entrypoints": {
            "description": "File paths considered reachability roots; omit to auto-detect from package.json main/exports/bin.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "includeTests": {
            "default": true,
            "description": "Treat test files (*.test.*, *.spec.*, __tests__/) as entrypoints (default true).",
            "type": "boolean"
          },
          "excludeDir": {
            "description": "Dir names to prune from the scan; defaults to node_modules/dist/build/out/coverage/.git/target/.next/.cache.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "maxFiles": {
            "description": "Cap total files scanned; scan stops and warns past this bound.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50000
          },
          "limit": {
            "description": "Dead-export result cap before pagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 5000
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per result page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          }
        },
        "required": [
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Local Find Dead Code",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
localFindFilesLocal | Find local files and directories by name, size, time, or permissions. | Local path discovery by name/type/metadata — not contents (localSearchCode) or tree shape (localViewStructure). All filters AND. Prunes common generated/vendor dirs by default (node_modules, .git, dist, build, out, coverage, target, .next, .cache) — excludeDir:[] prunes nothing, or set excludeDir explicitly. Follow paths into read/search/LSP.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "maxDepth": {
            "description": "Recurse at most this many levels below path (0 = path's own entries).",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "minDepth": {
            "description": "Requires <= maxDepth when both set.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "names": {
            "description": "Basename globs; ORed.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pathPattern": {
            "description": "Full-path glob.",
            "type": "string"
          },
          "regex": {
            "description": "Basename Rust regex.",
            "type": "string"
          },
          "empty": {
            "description": "Match only empty files/dirs.",
            "type": "boolean"
          },
          "time": {
            "description": "{ modifiedWithin?, modifiedBefore?, accessedWithin? } d/h/w/m windows.",
            "type": "object",
            "properties": {
              "modifiedWithin": {
                "type": "string"
              },
              "modifiedBefore": {
                "type": "string"
              },
              "accessedWithin": {
                "type": "string"
              }
            }
          },
          "size": {
            "description": "{ greater?, less? } e.g. 100k, 1m, 500b.",
            "type": "object",
            "properties": {
              "greater": {
                "type": "string"
              },
              "less": {
                "type": "string"
              }
            }
          },
          "permissions": {
            "description": "Exact permission filter.",
            "type": "string"
          },
          "access": {
            "description": "\"executable\", \"readable\", or \"writable\" filter.",
            "type": "string",
            "enum": [
              "executable",
              "readable",
              "writable"
            ]
          },
          "extensions": {
            "description": "Extensions to include, e.g. [\"ts\",\"tsx\"] (no dot); cheaper and clearer than a names glob for this.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "excludeDir": {
            "description": "Directory names to prune from the walk. Common generated/vendor dirs are pruned by default (node_modules, .git, dist, build, out, coverage, target, .next, .cache); pass [] to prune nothing, or pass an explicit list to choose pruned dirs.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "limit": {
            "description": "Discovery cap applied after sort, before pagination — total results are capped here; itemsPerPage/page page within that cap.",
            "type": "integer",
            "minimum": 1,
            "maximum": 10000
          },
          "detail": {
            "default": "basic",
            "description": "\"basic\" (default), \"modified\" (+mtime), or \"full\" (all metadata).",
            "type": "string",
            "enum": [
              "basic",
              "modified",
              "full"
            ]
          },
          "sortBy": {
            "default": "modified",
            "description": "\"modified\" (default), \"name\", \"path\", or \"size\".",
            "type": "string",
            "enum": [
              "modified",
              "name",
              "path",
              "size"
            ]
          },
          "entryType": {
            "description": "\"f\" files, \"d\" dirs.",
            "type": "string",
            "enum": [
              "f",
              "d"
            ]
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per result page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          }
        },
        "required": [
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Local Find Files",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
localGetFileContentLocal | Read a local file or a specific region. | Use after localSearchCode/localViewStructure/localFindFiles when you have a path — not for discovery. Unknown/large file: minify:"symbols" first, then exact range or matchString. A small structured/config file (package.json, tsconfig, lockfile) → read it whole with minify:"none"/fullContent, don't minify it — compaction can elide object boundaries and break exact key/value membership. For a literal value or quote, read the defining region with minify:"none" and copy the exact bytes. Every response reports the file's full size (totalLines + sourceChars) and isPartial. A matchString/region read is a SLICE, not the whole file — it can cut a nested object mid-way; never conclude a key/field/value is absent or empty from a partial slice: continue via charOffset/next, or re-read the whole small structured file with minify:"none". Report only bytes you fetched — never invent a field, value, or quote. Param relations: choose one extraction mode: fullContent OR matchString OR startLine+endLine. matchString pairs with contextLines and returns matchRanges ({start,end} line windows padded by contextLines, NOT the exact hit) plus matchedLines (the exact matched line numbers); charOffset continues isPartial pages. Follow matchedLines/matchRanges into LSP.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "fullContent": {
            "description": "Whole file; small files only; exclusive with range/match.",
            "type": "boolean"
          },
          "matchString": {
            "description": "Anchor returning slices plus matchRanges ({start,end} padded windows) and matchedLines (exact hit line numbers).",
            "type": "string"
          },
          "matchStringIsRegex": {
            "description": "Makes matchString a regex.",
            "type": "boolean"
          },
          "matchStringCaseSensitive": {
            "description": "Case-sensitive matchString (default insensitive).",
            "type": "boolean"
          },
          "startLine": {
            "description": "Requires endLine; exclusive with fullContent/matchString.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "endLine": {
            "description": "Requires startLine; must be >= startLine.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "contextLines": {
            "description": "Extra source lines around each match/anchor.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "charOffset": {
            "description": "Use pagination.nextCharOffset.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000000
          },
          "charLength": {
            "description": "Characters per content window; continue via the returned next offset when partial.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50000
          },
          "minify": {
            "description": "\"symbols\" outline, \"standard\" compact, \"none\" exact.",
            "type": "string",
            "enum": [
              "none",
              "standard",
              "symbols"
            ]
          }
        },
        "required": [
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Local Fetch Content",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
localSearchCodeLocal | Search local files for text, regex, or AST patterns to find file and line. | Find local file+line anchors — not path/name lookup (localFindFiles) or tree shape (localViewStructure). Modes: discovery=paths, paginated=snippets, detailed=context, structural=AST. text/regex need searchText (one string, not array); structural needs pattern XOR rule and rejects search knobs (langType is valid — scopes to that language's extensions). $$$ list captures are budgeted: metavarRanges gives pruned/truncated line anchors, captureText:true for verbatim. matchWindow/unique need output:"matchOnly"; maxMatchesPerFile pairs matchPage. Follow with localGetFileContent, lspGetSemantics.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "searchText": {
            "description": "The search pattern. regex:\"fixed\" for a literal match, \"perl\" for advanced features (lookaheads, backreferences), else \"smart\". (Unlike ghSearchCode/ghSearchRepos, where `keywords` is an array of ANDed terms — this is a single string.)",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "mode": {
            "default": "paginated",
            "description": "\"paginated\" snippets; \"discovery\" paths only; \"detailed\" snippets plus context; \"structural\" AST/code-shape search with pattern or rule. Structural matches return line/capture anchors that can feed lspGetSemantics when symbol identity matters. (Unrelated to ghSearchPullRequests's `content.patches.mode` — different concepts sharing this name.)",
            "type": "string",
            "enum": [
              "paginated",
              "discovery",
              "detailed",
              "structural"
            ]
          },
          "pattern": {
            "description": "Structural only: code-shaped AST pattern with $X (one node) or $$$ARGS (node list). Modifiers are part of the node — `function $NAME` does not match `async function` or `export function`; include the modifiers or use a YAML `kind` rule for modifier-agnostic matches. Use this to find syntax shape, then use lspGetSemantics for semantic proof.",
            "type": "string"
          },
          "rule": {
            "description": "Structural only: YAML ast-grep rule for not/inside/has/all/any. Use for partial or relational AST queries before escalating matched anchors to lspGetSemantics.",
            "type": "string"
          },
          "regex": {
            "default": "smart",
            "description": "\"smart\" (default), \"fixed\" (literal), or \"perl\" (advanced).",
            "type": "string",
            "enum": [
              "smart",
              "fixed",
              "perl"
            ]
          },
          "caseMode": {
            "default": "smart",
            "description": "\"smart\" (default), \"sensitive\", or \"insensitive\".",
            "type": "string",
            "enum": [
              "smart",
              "sensitive",
              "insensitive"
            ]
          },
          "wholeWord": {
            "description": "Match whole words only (text/regex modes).",
            "type": "boolean"
          },
          "invertMatch": {
            "description": "Return non-matching lines (text/regex modes).",
            "type": "boolean"
          },
          "include": {
            "description": "Glob(s) of files to include.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "exclude": {
            "description": "Glob(s) of files to exclude.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "excludeDir": {
            "description": "Directory names to prune from the walk.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "noIgnore": {
            "description": "Also search .gitignored files.",
            "type": "boolean"
          },
          "hidden": {
            "description": "Include dot-files.",
            "type": "boolean"
          },
          "contextLines": {
            "description": "Extra source lines around each match/anchor.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "matchContentLength": {
            "description": "Characters of matched-line content kept per hit; longer lines are truncated (numeric default/bounds live in the schema).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "maxMatchesPerFile": {
            "description": "Pairs with matchPage.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "maxFiles": {
            "description": "Cap total matched files.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000
          },
          "multiline": {
            "default": "off",
            "description": "\"off\" (default), \"on\", or \"dotall\" (. spans newlines).",
            "type": "string",
            "enum": [
              "off",
              "on",
              "dotall"
            ]
          },
          "sort": {
            "default": "relevance",
            "description": "\"relevance\" (default), \"matchCount\", \"path\", \"modified\", \"accessed\", or \"created\".",
            "type": "string",
            "enum": [
              "relevance",
              "matchCount",
              "path",
              "modified",
              "accessed",
              "created"
            ]
          },
          "sortReverse": {
            "description": "Reverse the sort order.",
            "type": "boolean"
          },
          "rankingProfile": {
            "default": "auto",
            "description": "Language-aware relevance tuning for sort:\"relevance\"; \"auto\" (default) detects, else a language id or \"generic\".",
            "type": "string",
            "enum": [
              "auto",
              "typescript",
              "javascript",
              "rust",
              "python",
              "go",
              "java",
              "scala",
              "markdown",
              "json",
              "yaml",
              "generic"
            ]
          },
          "langType": {
            "description": "Restrict to a language/file type, e.g. \"ts\" (ripgrep --type; in structural mode it maps to that language's include globs).",
            "type": "string"
          },
          "captureText": {
            "description": "Structural only: return full verbatim capture text for `$$$` list metavars (bodies, arg lists). Default false — list-capture text is omitted from `metavars`, and `metavarRanges` entries are comment-pruned and truncated to keep results lean; ranges always remain as line anchors.",
            "type": "boolean"
          },
          "output": {
            "default": "content",
            "description": "\"content\" (default) matches with line text; \"files\"/\"filesWithout\" return matching/non-matching paths; \"countLines\"/\"countMatches\" return per-file counts; \"matchOnly\" returns just the matched substring (required for unique/matchWindow). (\"files\" is unlike localViewStructure's `filesOnly`, which filters a directory listing to file entries.)",
            "type": "string",
            "enum": [
              "content",
              "files",
              "filesWithout",
              "countLines",
              "countMatches",
              "matchOnly"
            ]
          },
          "unique": {
            "default": "off",
            "description": "Needs output:\"matchOnly\". \"list\" returns each matched value once per file; \"count\" adds its frequency.",
            "type": "string",
            "enum": [
              "off",
              "list",
              "count"
            ]
          },
          "matchWindow": {
            "description": "Requires output:\"matchOnly\".",
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "matchPage": {
            "description": "Per-file match page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per result page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "maxDepth": {
            "description": "Keep files at most this many directory levels below the search root (0 = files directly in the root). Structural mode pushes this into the native walker; text/regex mode applies it after the native search and emits a warning when it filters deeper matches.",
            "type": "integer",
            "minimum": 0,
            "maximum": 20
          },
          "semanticRanking": {
            "description": "DISABLED in this build — do not pass. sort:\"relevance\" already includes declaration/export/AST signals."
          }
        },
        "required": [
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Local Ripgrep Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
localViewStructureLocal | Browse a local directory tree — cheapest first orientation step; no content loaded. | Cheapest local orientation before reading. Metadata/name filters → localFindFiles; files containing text → localSearchCode(mode:"discovery"). path is the root; pattern/extensions/entryType filter names; recursive enables maxDepth; detail switches output shape; page advances only on hasMore. Follow paths into localGetFileContent/search/LSP.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "Target path. GitHub tools: repo-relative, exact case, no leading slash. Local tools: absolute path."
          },
          "detail": {
            "default": "basic",
            "description": "\"basic\" (default), \"modified\" (+mtime), or \"full\" (size/perms).",
            "type": "string",
            "enum": [
              "basic",
              "modified",
              "full"
            ]
          },
          "hidden": {
            "description": "Include dot-files/dirs.",
            "type": "boolean"
          },
          "sortBy": {
            "default": "name",
            "description": "\"name\" (default), \"size\", \"time\", or \"extension\".",
            "type": "string",
            "enum": [
              "name",
              "size",
              "time",
              "extension"
            ]
          },
          "reverse": {
            "description": "Reverse the sort order.",
            "type": "boolean"
          },
          "pattern": {
            "description": "Name glob/substr; use localFindFiles for regex.",
            "type": "string"
          },
          "entryType": {
            "description": "\"f\" files only, \"d\" dirs only; omit for both.",
            "type": "string",
            "enum": [
              "f",
              "d"
            ]
          },
          "recursive": {
            "description": "Enables maxDepth.",
            "type": "boolean"
          },
          "extensions": {
            "description": "Allowlist without dots.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "maxDepth": {
            "description": "Maximum recursion depth: 1 = the target directory's immediate children, 2 = children + grandchildren, and so on (upper bound lives in the schema). Setting maxDepth on its own enables recursion to that depth — recursive:true is not required. Effective depth when OMITTED: 1 (immediate children only) if recursive is unset, or 5 if recursive:true. maxDepth:0 is treated as unset and falls back to those defaults.",
            "type": "integer",
            "minimum": 0,
            "maximum": 20
          },
          "limit": {
            "description": "Discovery cap before pagination.",
            "type": "integer",
            "minimum": 1,
            "maximum": 10000
          },
          "page": {
            "description": "Result page, 1-based. Advance only while pagination.hasMore.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "Items per result page.",
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          },
          "excludeDir": {
            "description": "Directory names to prune from recursive walks (default: common generated/vendor dirs such as node_modules, dist, build, out, coverage, target). Pass [] to inspect everything.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "path"
        ]
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Local View Structure",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
lspGetSemanticsLocal | Run LSP semantic queries — definitions, references, call hierarchy, symbols, type hierarchy, diagnostics. | Use after search/read gives a real file+line anchor. documentSymbols/diagnostic need uri only; workspaceSymbol needs symbolName; others need uri+symbolName+lineHint. lineHint must come from a prior anchor, never guessed; orderHint disambiguates same-line symbols; references take groupByFile/includeDeclaration; callers/callees/callHierarchy take depth/contextLines; format:"compact" saves tokens. Empty/serverUnavailable → re-anchor or fall back to search.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "uri": {
            "description": "Target file path/URI; required for every type except workspaceSymbol.",
            "type": "string"
          },
          "type": {
            "default": "definition",
            "description": "Semantic operation for local code intelligence. Use after text or structural AST search when you need identity, references, call flow, type relations, hover, symbols, or diagnostics.",
            "type": "string",
            "enum": [
              "definition",
              "references",
              "callers",
              "callees",
              "callHierarchy",
              "hover",
              "documentSymbols",
              "typeDefinition",
              "implementation",
              "workspaceSymbol",
              "supertypes",
              "subtypes",
              "diagnostic"
            ]
          },
          "symbolName": {
            "description": "Exact bare identifier at the lineHint anchor for symbol operations; workspaceSymbol uses this as the fuzzy project-wide symbol query.",
            "type": "string",
            "minLength": 1,
            "maxLength": 1024
          },
          "lineHint": {
            "description": "Real line containing symbolName; never guess.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000000000
          },
          "orderHint": {
            "description": "Disambiguate repeated symbols on one line.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100000
          },
          "depth": {
            "description": "Traversal depth for call-hierarchy / type-hierarchy queries (0 = direct only).",
            "type": "integer",
            "minimum": 0,
            "maximum": 20
          },
          "includeDeclaration": {
            "default": true,
            "description": "references only; defaults true, which counts the declaration itself as one hit — set false (or expect a floor of 1) before treating a low count as unused.",
            "type": "boolean"
          },
          "groupByFile": {
            "description": "references summary mode.",
            "type": "boolean"
          },
          "page": {
            "description": "Result page for paginated reference/symbol lists (advance while pagination.hasMore).",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          },
          "itemsPerPage": {
            "description": "References/symbols returned per page (with page).",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "contextLines": {
            "description": "Lines of surrounding source shown around each result location.",
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "format": {
            "default": "structured",
            "description": "\"compact\" saves tokens; \"structured\" has typed locations.",
            "type": "string",
            "enum": [
              "structured",
              "compact"
            ]
          },
          "workspaceRoot": {
            "description": "Use when auto-root is wrong.",
            "type": "string"
          }
        }
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Get Semantic Content",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": false
}
Read only · Non-destructive
npmSearchNPM | Look up npm packages and find their source repositories. | Resolve a package to its source repository; skip if owner/repo is known. Exact name → one rich result; keywords → paged candidates. Follow repository into GitHub tools.
Input schema
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "queries": {
      "minItems": 1,
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "description": "Stable ID to correlate this query with its result in a batch.",
            "type": "string"
          },
          "mainResearchGoal": {
            "description": "Goal shared by every query in this batch; set once per call.",
            "type": "string"
          },
          "researchGoal": {
            "description": "The specific sub-question this query answers.",
            "type": "string"
          },
          "reasoning": {
            "description": "Why this query advances the goal.",
            "type": "string"
          },
          "packageName": {
            "type": "string",
            "description": "Exact package or keyword query; include scope."
          },
          "keywords": {
            "description": "Registry keyword query (string; an array of terms is accepted and joined with spaces).",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "page": {
            "description": "Keyword-result page only.",
            "type": "integer",
            "minimum": 1,
            "maximum": 1000
          }
        },
        "required": [
          "packageName"
        ],
        "additionalProperties": false
      },
      "description": "Parallel queries."
    },
    "responseCharOffset": {
      "description": "Full-response char offset; re-call with returned value when hasMore.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000000
    },
    "responseCharLength": {
      "description": "Full-response char window.",
      "type": "integer",
      "minimum": 1,
      "maximum": 50000
    }
  },
  "required": [
    "queries"
  ]
}
Annotations
{
  "title": "Package Search",
  "readOnlyHint": true,
  "destructiveHint": false,
  "idempotentHint": true,
  "openWorldHint": true
}
Read only · Non-destructive

Resources 0

Resource templates 0

Prompts 0

Let’s talk about MCP security.

Share your details and our security team will contact you.