Skip to content

Commit ca4689d

Browse files
ericdalloeca-agent
andcommitted
Use JSON-RPC ping for OAuth auth-discovery probe
The probe POST previously sent a JSON-RPC `initialize`, which a strict MCP mock (and potentially some real servers) counted as a real handshake alongside the actual ECA initialize. The integration test `mcp-remote-server-connects` asserts `(= 1 (count init-reqs))` and broke with `(not (= 1 2))`. Switch the probe to a JSON-RPC `ping`: - Still a valid JSON-RPC envelope, so OAuth-protected servers (Figma, Glean, etc.) still hit their auth middleware and emit the expected 401 + www-authenticate. - Never confused with the real MCP handshake by servers that maintain per-connection state or by test mocks that bucket requests by method. 🤖 Generated with [eca](https://eca.dev) Co-Authored-By: eca-agent <git@eca.dev>
1 parent a768784 commit ca4689d

2 files changed

Lines changed: 14 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Use a JSON-RPC `ping` (instead of `initialize`) for the OAuth auth-discovery probe, so the probe POST is never counted as a real handshake by servers or tests that track requests by method name.
6+
57
## 0.134.1
68

79
- Support optional `clientName` config field for MCP servers to override the OAuth Dynamic Client Registration `client_name` (useful for servers that allowlist clients by name, e.g. Figma).

src/eca/oauth.clj

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,26 +150,26 @@
150150
(and (= 401 (:status response))
151151
(some? (get (:headers response) "www-authenticate"))))
152152

153-
(def ^:private probe-initialize-body
154-
"JSON-RPC initialize body used to probe for OAuth challenges. Some servers
155-
(e.g. Figma) only return 401 + www-authenticate when the request body is a
156-
recognizable MCP initialize message; a bare '{}' is treated as malformed and
157-
yields a generic JSON-RPC error instead of an auth challenge."
153+
(def ^:private probe-ping-body
154+
"JSON-RPC ping body used to probe for OAuth challenges. Some servers
155+
(e.g. Figma) only return 401 + www-authenticate when the request body is
156+
a recognizable MCP message; a bare '{}' is treated as malformed and yields
157+
a generic JSON-RPC error instead of an auth challenge.
158+
`ping` is used (rather than `initialize`) so the probe is never confused
159+
with the real MCP handshake by servers that maintain per-connection state
160+
or by test mocks that count requests by method name."
158161
(json/generate-string
159162
{:jsonrpc "2.0"
160163
:id 0
161-
:method "initialize"
162-
:params {:protocolVersion "2024-11-05"
163-
:capabilities {}
164-
:clientInfo {:name "eca" :version "probe"}}}))
164+
:method "ping"}))
165165

166166
(defn ^:private probe-auth
167167
"Probe the MCP server for a 401 auth challenge with www-authenticate header.
168-
Tries HEAD first; falls back to POST with a JSON-RPC initialize body if HEAD
168+
Tries HEAD first; falls back to POST with a JSON-RPC ping body if HEAD
169169
doesn't return a valid challenge (some servers like Glean don't support HEAD,
170170
some proxies like istio-envoy return 401 on HEAD without actually requiring
171171
auth, and some servers like Figma only emit the auth challenge in response to
172-
a valid MCP initialize request)."
172+
a recognizable MCP request)."
173173
[^String url]
174174
(let [head-response (http/head url {:timeout 10000
175175
:throw-exceptions? false})]
@@ -179,7 +179,7 @@
179179
:throw-exceptions? false
180180
:headers {"Content-Type" "application/json"
181181
"Accept" "application/json, text/event-stream"}
182-
:body probe-initialize-body})]
182+
:body probe-ping-body})]
183183
(when (valid-auth-challenge? post-response)
184184
post-response)))))
185185

0 commit comments

Comments
 (0)