From b8c22773cdf967bcf0855694e9dca13351d26b3e Mon Sep 17 00:00:00 2001 From: zer0stars <74260741+zer0stars@users.noreply.github.com> Date: Wed, 10 Jun 2026 17:08:38 -0400 Subject: [PATCH] docs: OAuth 2.1 remote MCP design draft; telemetry daily-activity issue draft --- .../2026-06-10-oauth-remote-mcp-design.md | 75 +++++++++++++++++++ ...26-06-10-telemetry-daily-activity-issue.md | 32 ++++++++ 2 files changed, 107 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-10-oauth-remote-mcp-design.md create mode 100644 docs/superpowers/specs/2026-06-10-telemetry-daily-activity-issue.md diff --git a/docs/superpowers/specs/2026-06-10-oauth-remote-mcp-design.md b/docs/superpowers/specs/2026-06-10-oauth-remote-mcp-design.md new file mode 100644 index 0000000..46256a5 --- /dev/null +++ b/docs/superpowers/specs/2026-06-10-oauth-remote-mcp-design.md @@ -0,0 +1,75 @@ +# Design: OAuth 2.1 on hosted DIMO MCP endpoints (Phase 2) + +**Date:** 2026-06-10 +**Status:** Draft — future track, not scheduled +**Repos:** `telemetry-api` (or a gateway in front of it), DIMO auth stack +(`auth.dimo.zone` / login portal), `dimo-plugin`, DIMO mobile app + +## Problem + +The current plugin (v0.2.x) reduced onboarding to one credential paste, but a +paste step still exists, the private key lives on the user's laptop, and +distribution is limited to Claude Code (claude.ai and Claude Desktop +connectors expect a remote MCP server with OAuth). The hosted MCP endpoints +already exist (`telemetry-api.dimo.zone/mcp`, identity equivalent); the only +missing piece is standards-based authorization on them. + +## Goal + +A user adds the DIMO connector in any MCP client (claude.ai, Claude Desktop, +Claude Code), clicks Connect, approves in the DIMO mobile app, and asks +"where's my car?". Zero credentials handled, zero local install. The +in-app developer-license feature becomes the approval surface instead of a +copy-paste source. + +## Approach + +Implement the MCP authorization spec (OAuth 2.1) on the hosted MCP endpoints: + +1. **Authorization server.** Extend the existing DIMO auth stack + (`auth.dimo.zone`) with the OAuth 2.1 endpoints the MCP spec requires: + `/.well-known/oauth-authorization-server` metadata, authorization code + + PKCE flow, token + refresh endpoints, and dynamic client registration + (MCP clients self-register; this is what removes the developer-console + step entirely for end users). +2. **Resource server.** `telemetry-api /mcp` validates OAuth access tokens + as an alternative to today's Vehicle JWT bearer. Token claims carry the + DIMO user; per-call vehicle authorization happens server-side against + SACD grants for the user's connected license (the token-exchange logic + moves behind the endpoint, where rev 2 of the onboarding design already + wanted it). +3. **Login + approval UX.** The authorization page is login.dimo.org; the + approval step pushes to the DIMO mobile app (deep link or push + notification → approve). For users without the app, web login works as + today. +4. **Scopes.** Map MCP scopes to SACD privilege sets — e.g. + `vehicle:data:read` → privileges 1,3,4,5,6,8; `vehicle:commands` → + privilege 2 (consent-gated separately; commands should never ride along + silently with a data connection). +5. **dimo-plugin v0.3.** `.mcp.json` declares the remote server; the auth + helper script, credentials file, and paste flow are deleted. The skill + shrinks to usage guidance (tool selection, signal reference, data-age + honesty). Claude Code's native OAuth handling does the rest. + +## Why this beats extending v0.2 + +- Kills the last onboarding friction (paste) and the laptop-resident key. +- Unlocks claude.ai / Desktop connector distribution — the audiences that + never install a CLI. +- One authorization implementation serves every MCP client, ChatGPT + connectors included, not just Claude. + +## Open questions (resolve before scheduling) + +- Where the resource-server change lives: inside telemetry-api (Go) or a + thin MCP gateway fronting telemetry + identity + commands. +- Whether existing dev-license JWTs should also be accepted at `/mcp` for + fleet/B2B callers, or stay on the data-API surface only. +- Refresh-token lifetime vs. SACD expiry semantics (a revoked share must cut + off an otherwise-valid token). +- Rate limiting / DCX metering for connector traffic. + +## Migration + +v0.2 (local auth script) keeps working unchanged; v0.3 ships when the +endpoints land. `~/.dimo` cleanup happens on first v0.3 run. diff --git a/docs/superpowers/specs/2026-06-10-telemetry-daily-activity-issue.md b/docs/superpowers/specs/2026-06-10-telemetry-daily-activity-issue.md new file mode 100644 index 0000000..7234ef3 --- /dev/null +++ b/docs/superpowers/specs/2026-06-10-telemetry-daily-activity-issue.md @@ -0,0 +1,32 @@ +# Drafted issue for DIMO-Network/telemetry-api (not yet filed) + +File with: + +```sh +gh issue create --repo DIMO-Network/telemetry-api \ + --title "MCP: telemetry_get_daily_activity hangs / returns empty body with valid params" \ + --body-file docs/superpowers/specs/2026-06-10-telemetry-daily-activity-issue.md +``` + +(strip this header first, or paste the body below into GitHub) + +--- + +## Repro + +Against production `https://telemetry-api.dimo.zone/mcp` with a valid Vehicle JWT (vehicle 107505, actively reporting): + +``` +POST /mcp +{"jsonrpc":"2.0","method":"tools/call","params":{"name":"telemetry_get_daily_activity","arguments":{"tokenId":107505,"from":"2026-06-08T00:00:00Z","to":"2026-06-10T00:00:00Z","mechanism":"ignitionDetection"}},"id":1} +``` + +- Param validation passes (an invalid `mechanism` correctly returns `-32602` with the enum list, so the request shape is right). +- With valid params the connection returns an empty body / hangs past 60s (`curl --max-time 60` exits with no output). Reproduced twice, including a 2-day range. +- Other tools on the same endpoint and JWT respond fine (`telemetry_get_signals_snapshot`, `telemetry_get_available_signals`, `telemetry_get_latest_signals`). + +Observed 2026-06-10 while testing the Claude plugin (DIMO-Network/dimo-plugin). `telemetry_get_trip_segments` shares the mechanism/config input shape and may be affected too — untested. + +## Expected + +Either a result within a reasonable timeout or a JSON-RPC error.