GitHub, GitLab & PR Code Review MCP Servers: Streamable HTTP & JSON-RPC Deep Dive
What actually goes over the wire when an agent reviews a pull request through MCP: the initialize handshake, the real 401 and OAuth metadata GitHub returns, and the JSON-RPC tools/call messages for reading diffs and drafting reviews.
Remote code-review MCP servers speak JSON-RPC 2.0 over Streamable HTTP: the client POSTs messages to a single endpoint and the server answers with JSON or an event stream. Protected servers answer an unauthenticated initialize with HTTP 401 and a WWW-Authenticate header that points to OAuth protected resource metadata, which tells the client where to sign in and which scopes exist. We captured these exchanges live from GitHub, Linear and Greptile on 25 Oct 2026.
Verified Capabilities Benchmarked in This Guide
Inspect Live JSON Feed ↗GitHub Official MCP — Repositories, Pull Requests, Actions & Code Search
Official GitHub MCP server for searching repositories, inspecting PR diffs and review comments, triaging issues, and reading GitHub Actions workflow runs.
Greptile MCP
Query full-repository semantic graphs, review pull requests with full codebase context, and trace cross-repo dependencies via MCP.
Linear Official Remote MCP — Issues, Cycles, Triage & Roadmaps
Official Linear Streamable HTTP MCP server: search and create engineering issues, update sprint cycle states, link GitHub PRs, and synthesize project statu
Gram by Speakeasy — OpenAPI-to-Hosted Streamable HTTP MCP Generator
Compile any OpenAPI 3.1 specification into a type-safe, hosted Streamable HTTP MCP server with curated tool subsets, OAuth passthrough, and rate limits.
MCP Expert — Protocol Spec Auditor & Server Security Grader
Audits any MCP server against the official Streamable HTTP & JSON-RPC 2.0 specification, grading schema clarity, error handling, and auth scoping.
GitLab Merge Requests, CI Pipelines & Issue Tracker MCP Server
Connect AI coding agents to GitLab self-hosted or cloud instances: inspect Merge Request diffs, debug failed GitLab CI jobs, and update issues.
1. Streamable HTTP in one paragraph
In the Streamable HTTP transport, the MCP server exposes one endpoint (for example https://api.githubcopilot.com/mcp/). The client sends each JSON-RPC message as an HTTP POST with an Accept header listing both application/json and text/event-stream. The server can reply with a single JSON body or open an SSE stream for long-running work and server-to-client messages. Sessions, when used, are tracked with an Mcp-Session-Id header returned at initialize. Local servers such as Graphite's gt mcp use the stdio transport instead, with the same JSON-RPC messages over standard input and output.
2. The handshake and auth discovery, captured live
This is the real exchange with GitHub's remote server on 25 Oct 2026 (headers trimmed). The 401 is not an error to work around; it is the discovery step. The client follows resource_metadata, learns the authorization server and scopes, runs OAuth (or you supply a PAT as a bearer token), then retries initialize.
3. How three real servers answered
We sent the identical initialize request to three code-review-related servers. Their behaviour differs in ways your client must handle.
| Server | Unauthenticated initialize | Auth discovery |
|---|---|---|
| GitHub MCP (api.githubcopilot.com/mcp/) | HTTP 401 | WWW-Authenticate with error, error_description and resource_metadata; metadata lists github.com/login/oauth and scopes |
| Linear MCP (mcp.linear.app/mcp) | HTTP 401 | WWW-Authenticate: Bearer realm="OAuth", resource_metadata=.../.well-known/oauth-protected-resource/mcp, scope="read write" |
| Greptile MCP (api.greptile.com/mcp) | HTTP 200 with an initialize result (protocolVersion 2025-03-26, serverInfo "Greptile MCP Server") | Handshake is open; tool calls require OAuth or an organisation API key |
4. The JSON-RPC messages of a pull request review
After initialize and notifications/initialized, a review is a sequence of tools/list and tools/call requests. These match the GitHub MCP server's documented tool names and arguments.
5. Errors your client must handle
Two kinds of failure look different on the wire and need different handling.
- Protocol errors use the JSON-RPC error object (for example code -32602 for invalid params or -32601 for an unknown method). Fix the request; retrying will not help.
- Tool execution errors come back as a normal result with isError: true and a text explanation, such as a missing PR or insufficient permission. Show these to the model so it can adjust.
- HTTP 401 means re-run auth discovery. HTTP 403 with insufficient_scope (GitLab returns this for unsupported token types) means the token type or scope is wrong, not expired.
- Version negotiation: the server may answer initialize with an older protocolVersion than you asked for, as Greptile did. Clients must use the version the server returns.
6. Build or audit your own server
If you want to expose your own review or CI API as a Streamable HTTP server, Gram by Speakeasy is listed in the catalog for generating hosted MCP servers from OpenAPI specs (its listed endpoint returned a 301 redirect on 25 Oct 2026, so check the vendor docs for the current URL). To grade an existing server against the spec, run the MCP Expert template. The /agent page lists LightState's own machine-readable discovery endpoints.
Frequently Asked Questions
What transport do remote code-review MCP servers use?
Streamable HTTP: JSON-RPC 2.0 messages POSTed to a single endpoint, with responses as JSON or a server-sent event stream. GitHub, Linear, Sentry and Greptile all expose remote endpoints this way.
Why does the GitHub MCP endpoint return 401?
Because no token was supplied. The 401 includes a WWW-Authenticate header whose resource_metadata URL lists GitHub's OAuth authorization server and supported scopes, which clients use to sign in.
What is OAuth protected resource metadata in MCP?
A JSON document at a .well-known/oauth-protected-resource path that names the resource, its authorization servers, supported scopes and how bearer tokens are sent. MCP clients use it to discover how to authenticate.
How is a tool error different from a JSON-RPC error?
A JSON-RPC error means the request itself was invalid. A tool error is a successful response whose result has isError set to true, meaning the tool ran but failed, for example because the PR does not exist.