antvis / antvis/mcp-server-chart
missing PRM hinders oauth
- Dominant language
- TypeScript
- Stars
- 4.4k
- Forks
- 417
- Avg merge
- 5d 16h
- Merged PRs (30d)
- 1
Description
```
Command: authprobe scan --llm-max-tokens=1080 --openai-api-key=***REDACTED*** http://localhost:8024/mcp
Scanning: http://localhost:8024/mcp
Scan time: Feb 20, 2026 06:58:55 UTC
Github: https://github.com/authprobe/authprobe
Funnel
[1] MCP probe (401 + WWW-Authenticate) [-] SKIP
probe returned 405; checking PRM for OAuth config
[2] MCP initialize + tools/list [+] PASS
initialize -> 200
notifications/initialized -> 202
tools/list -> 200 (tools: generate_area_chart, generate_bar_chart,
generate_boxplot_chart, generate_column_chart, +23 more)
[3] PRM fetch matrix [X] FAIL
PRM unreachable or unusable; OAuth discovery unavailable
[4] Auth server metadata [-] SKIP
auth not required
[5] Token endpoint readiness (heuristics) [-] SKIP
auth not required
[6] Dynamic client registration (RFC 7591) [-] SKIP
auth not required
┌───────────────────────┤ CALL TRACE ├───────────────────────┐
Call Trace Using: https://github.com/authprobe/authprobe
┌────────────┐ ┌────────────┐
│ authprobe │ │ MCP Server │
└─────┬──────┘ └─────┬──────┘
│ │
│ ╔═══ Step 1: MCP probe ═══════╪═══════════════════╗
│ GET http://localhost:8024/mcp
│ Reason: 401 + WWW-Authenticate discovery
│ Accept: text/event-stream
│ Host: localhost:8024
├─────────────────────────────────────────────────────────────────►│
│ 405 Method Not Allowed
│ Connection: keep-alive
│ Date: Fri, 20 Feb 2026 06:58:51 GMT
│ Keep-Alive: timeout=5
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ ╔═══ Step 2: MCP initialize ═══════╪═══════════════════╗
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (pre-init tools/list)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 200 OK
│ Cache-Control: no-cache
│ Connection: keep-alive
│ Content-Type: text/event-stream
│ Date: Fri, 20 Feb 2026 06:58:51 GMT
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (initialize)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 200 OK
│ Cache-Control: no-cache
│ Connection: keep-alive
│ Content-Type: text/event-stream
│ Date: Fri, 20 Feb 2026 06:58:52 GMT
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (notifications/initialized)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 202 Accepted
│ Connection: keep-alive
│ Content-Type: text/plain; charset=UTF-8
│ Date: Fri, 20 Feb 2026 06:58:52 GMT
│ Keep-Alive: timeout=5
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (null id probe)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 400 Bad Request
│ Connection: keep-alive
│ Content-Length: 101
│ Content-Type: application/json
│ Date: Fri, 20 Feb 2026 06:58:52 GMT
│ Keep-Alive: timeout=5
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (notification id probe)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 200 OK
│ Cache-Control: no-cache
│ Connection: keep-alive
│ Content-Type: text/event-stream
│ Date: Fri, 20 Feb 2026 06:58:52 GMT
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (origin probe)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
│ Origin: http://invalid.example
├─────────────────────────────────────────────────────────────────►│
│ 200 OK
│ Cache-Control: no-cache
│ Connection: keep-alive
│ Content-Type: text/event-stream
│ Date: Fri, 20 Feb 2026 06:58:53 GMT
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (protocol version probe)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: invalid
├─────────────────────────────────────────────────────────────────►│
│ 400 Bad Request
│ Connection: keep-alive
│ Content-Length: 195
│ Content-Type: application/json
│ Date: Fri, 20 Feb 2026 06:58:54 GMT
│ Keep-Alive: timeout=5
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
│ │
│ POST http://localhost:8024/mcp
│ Reason: Step 2: MCP initialize + tools/list (tools/list)
│ Accept: application/json, text/event-stream
│ Content-Type: application/json
│ Host: localhost:8024
│ Mcp-Protocol-Version: 2025-11-25
├─────────────────────────────────────────────────────────────────►│
│ 200 OK
│ Cache-Control: no-cache
│ Connection: keep-alive
│ Content-Type: text/event-stream
│ Date: Fri, 20 Feb 2026 06:58:54 GMT
│ X-Powered-By: Express
│◄─────────────────────────────────────────────────────────────────┤
▼ ▼
```
┌──────────────────┤ ROOT-CAUSE ANALYSIS ├───────────────────┐
### Summary
The AuthProbe scan against the MCP OAuth server located at `http://localhost:8024/mcp` produced a **valid and justified failure** during step [3], specifically related to the **PRM fetch matrix** being unreachable or unusable, which resulted in **OAuth discovery being unavailable**. Additional findings regarding MCP initialization ordering and Origin validation were observed but noted as informational or low confidence issues.
---
### Detailed explanation and spec references
#### 1. **PRM Fetch Matrix Failure ([3])**
- **Outcome**: The Probe Resource Matrix (PRM), which serves as the OAuth discovery document, was unreachable or unusable. This led to failure in OAuth metadata discovery.
- **Relevant Specs**:
- **MCP 2025-11-25 §4.3 (OAuth Discovery and PRM)**: MCP mandates that OAuth-related endpoints must expose valid PRM information to enable discovery and token acquisition. The PRM provides metadata essential for clients to properly OAuth authenticate, including endpoints, supported grant types, scopes, etc.
- **RFC 8414 (OAuth 2.0 Authorization Server Metadata)**: Defines how OAuth AS metadata is exposed and must be discoverable for interoperability.
- **RFC 9728 (OAuth Discovery Best Practices, MCP 2025-11-25 references)**: Requires the PRM to be correctly reachable and in expected format, enabling clients to dynamically discover authorization server parameters.
- **Why failure is valid?**
The failure is justified because without valid PRM discovery, OAuth clients cannot determine essential authorization server endpoints or capabilities. This violates MCP mandatory requirements for interoperability and security.
- **Correct server behavior**:
- Serve a valid PRM response at the expected discovery URL.
- Ensure PRM endpoints are accessible over HTTP(S) whenever OAuth authentication is enabled.
- Respond with HTTP 200 and appropriate JSON-formatted metadata compliant with RFC 8414 and MCP 2025-11-25.
- Example PRM keys must include `issuer`, `authorization_endpoint`, `token_endpoint`, `jwks_uri`, and supported scopes/grants.
---
#### 2. **MCP Initialization Ordering Not Enforced**
- **Issue**: The server allowed `tools/list` command before completing `initialize`.
- **Spec Reference**:
- **MCP 2025-11-25 §3.1 (Initialization Ordering)**: MCP requires the client-server interaction starts with an `initialize` request to negotiate capabilities and versions before any other commands (e.g., `tools/list`).
- **Implication**:
Although this does not cause a functional failure, it violates MCP protocol ordering semantics and could lead to inconsistent client state.
- **Recommendation**:
Reject or defer requests other than `initialize` until the `initialize` handshake is complete, preferably responding with HTTP 409 Conflict or MCP error indicating the client must initialize first.
---
#### 3. **MCP Origin Not Validated**
- **Issue**: The server responded with HTTP 200 to an invalid `Origin` header probe, indicating no origin checking.
- **Spec Reference**:
- **MCP 2025-11-25 §5.2 (Origin Validation)**: Servers must validate the `Origin` header to prevent DNS rebinding and cross-site attacks, rejecting unsupported or unexpected origins with HTTP 403 Forbidden.
- **Implication**:
This is a low-severity security concern but recommended to be fixed to harden CSP and prevent malicious usage via injected origins.
- **Recommendation**:
Implement strict origin validation and reject requests from invalid or unexpected origins per MCP guidelines.
---
### Additional Notes on Skipped Steps
- Steps [1], [4], [5], and [6] were skipped because the server did not enforce OAuth authorization (`auth not required`), which is acceptable but makes OAuth-related discovery and registration steps irrelevant.
- The 405 response to the initial MCP probe ([1]) indicates the server may not fully implement authentication or expects configuration to be fetched from PRM, but since PRM was unreachable, authentication could not be validated further.
---
### Correct Server Behavior According to Specs
- **On MCP Initialization**:
- Accept and process `initialize` first.
- Reject non-initialization requests until initialization completes (MCP 2025-11-25 §3.1).
- **On OAuth Discovery**:
- Expose PRM at the well-known URL, responding with valid OAuth metadata compliant with RFC 8414, RFC 9728 requirements.
- Failures or unavailability of PRM should prevent OAuth clients from proceeding (per MCP 2025-11-25 OAuth discovery requirements).
- **On Origin Header Handling**:
- Validate `Origin` headers against allowed origins list.
- Respond with HTTP 403 for invalid or missing Origin (MCP 2025-11-25 §5.2).
- **On Authentication Requirement**:
- If auth is required, support OAuth token endpoints and dynamic client registration (RFC 7591).
- Otherwise, clearly document if auth is not enforced to help clients adjust safely.
---
### Conclusion
The failure during **PRM fetch matrix retrieval (step 3)** is **valid and justified**
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.