Skip to content

Remote Study Hub MCP

Study Hub exposes a guarded Model Context Protocol endpoint for compatible remote AI clients. It lets a signed-in learner search canonical course material, inspect their synchronized AI history and progress, continue the same Tutor session used by the native app, and explicitly save personal notes or source-grounded flashcards. The connector is disabled by default and never grants owner, publication, plugin-administration, filesystem, or provider-credential access.

Endpoint and authentication

The production resource URL is https://tuestudyhub.xyz/mcp; isolated acceptance uses https://test.tuestudyhub.xyz/mcp. A client that receives 401 discovers OAuth through /.well-known/oauth-protected-resource/mcp, whose authorization server is the configured Supabase Auth origin. The endpoint uses stateless Streamable HTTP and accepts bearer tokens in the Authorization header.

Before enabling the route, configure the hosted Supabase project as an OAuth 2.1 authorization server and set its application authorization path to /oauth/consent. Supabase combines this path with the project's production Site URL, so the consent UI remains https://tuestudyhub.xyz/oauth/consent during isolated acceptance while only the test MCP resource is enabled. Do not change the shared project's Site URL to the test origin: that would disrupt production authentication. Register each client's exact redirect URI, or enable dynamic client registration only for clients and redirect policies that have been reviewed. Keep Google as the Study Hub identity provider. The issued access token must contain the configured Supabase issuer, the authenticated audience, an unexpired session, and an OAuth client_id. An ordinary Study Hub browser session token has no OAuth client_id and is deliberately rejected. The server validates the token and its current user through Supabase on every request, then derives the account identity from verified claims; account IDs supplied in tool arguments are never accepted.

The connector requires these runtime values:

NEXT_PUBLIC_SUPABASE_URL=https://PROJECT_REF.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=...
STUDYHUB_MCP_ENABLED=1

The isolated test app keeps ACCOUNT_SYNC_ENABLED=0 and NEXT_PUBLIC_ACCOUNT_SYNC_ENABLED=0; the MCP server uses the verified bearer token directly and does not enable browser sync in a second environment. Production account sync can therefore remain available while MCP acceptance runs on the test resource. The production consent UI uses the already-enabled production browser configuration.

Do not add Claude, OpenAI, or other client credentials to Study Hub. OAuth grants access only to the learner's Study Hub account. Settings → Account & sync → Connected AI clients lists active grants and revokes the selected client's OAuth sessions and refresh tokens. Signing out of the Study Hub browser alone is not a substitute for revoking a separate remote grant. Test revocation before production enablement.

Capabilities

Read tools are studyhub_search, studyhub_get_source, studyhub_list_courses, studyhub_get_course, studyhub_get_topic, studyhub_export_topic_markdown, studyhub_get_course_graph, studyhub_list_conversations, studyhub_get_conversation, studyhub_get_tutor_state, studyhub_get_progress, studyhub_list_personal_records, studyhub_get_personal_record, and studyhub_list_due_reviews. Equivalent resource templates are available at studyhub://course/{id}, studyhub://source/{id}, studyhub://conversation/{id}, and studyhub://tutor/{id}. Course and source reads use published canonical material. Conversation, Tutor, progress, personal-record, and review reads are restricted to the authenticated account.

Tutor mutations are studyhub_start_tutor, studyhub_answer_tutor, studyhub_request_hint, studyhub_request_explanation, studyhub_pause_tutor, and studyhub_resume_tutor. They call the same application service as the native Study Hub UI. Every continuation carries both the exact Tutor revision and canonical cloud version. If either is stale, read studyhub_get_tutor_state again and retry from the returned versions; never guess or increment versions in the client.

Personal mutations are studyhub_create_note, studyhub_update_note, studyhub_delete_note, studyhub_save_flashcards, studyhub_write_annotation, studyhub_grade_review, and studyhub_record_progress_event. Update and delete operations require the current cloud version: read it from studyhub_get_personal_record or studyhub_list_personal_records, which return cloudVersion for exactly this purpose. Never guess or increment a version in the client.

Notes and highlights share the annotation domain and differ only by anchor: studyhub_create_note writes a block anchor, while studyhub_write_annotation writes a text anchor. Both must point to a canonical internal block. studyhub_delete_note therefore deletes either one and remains the only destructive tool. Flashcard decks use a strict versioned schema, bounded text and card counts, and validated Study Hub source IDs. Progress events are immutable: the server owns their IDs and timestamps and accepts only canonical course scopes.

studyhub_grade_review schedules through the same SM-2 function as the native review session, with one difference: exam-date compression reads browser storage and is unavailable server-side, so an item graded over MCP is scheduled without the exam-date pullback it would receive in the app. All MCP writes enter the ordinary account sync stream, so native browser repositories see them on their next pull without an import step.

The persistent per-account limits are 120 read operations, 30 Tutor operations, and 30 personal writes per minute. Families and accounts are isolated. Tool results expose safe application data, not Supabase rows, access tokens, provider errors, or hidden model reasoning.

Connecting a client

Add https://tuestudyhub.xyz/mcp as a remote MCP server in the client. The client calls /mcp, receives 401, and discovers OAuth through /.well-known/oauth-protected-resource/mcp, so no server-side registration is required. A browser then opens to Supabase, asks for Google sign-in into the learner's Study Hub account, and shows the Study Hub consent screen at /oauth/consent. Review the listed capabilities and choose Allow connection; the client receives an access token and connects. The grant is per-account, not a shared credential.

  • Claude Desktop: Settings → Connectors (or Developer → MCP servers) → add a remote MCP server and paste the URL.
  • Claude Code: claude mcp add --transport http studyhub https://tuestudyhub.xyz/mcp.
  • ChatGPT desktop app: Settings → Connected apps (or Connectors) → MCP → connect to a remote MCP server and paste the URL.

Revoke a grant later from Settings → Account & sync → Connected AI clients; signing out of the browser alone does not revoke the client's OAuth grant. Custom remote MCP and OAuth availability varies by client and plan, so a client that cannot run the OAuth flow cannot connect.

Client differences

Clients differ in whether custom remote MCP, OAuth, resource templates, and write tools are available on a particular account plan. A client that cannot invoke writes can still use the read-only tools. Claude or ChatGPT supplies the model that decides when to call MCP; its conversation is not copied into Study Hub automatically. Only explicit tool calls create or change Study Hub records. Do not describe subscription-backed usage as unlimited or as provider API access.

Record exact client names, versions, plan restrictions, OAuth behavior, resource support, and tool approval behavior during isolated acceptance. These observations are deployment evidence, not a portable server contract.

Guarded rollout and rollback

As of 2026-08-28 the hosted project runs its OAuth 2.1 authorization server with the authorization path /oauth/consent and dynamic client registration enabled, the MCP migrations are applied, and both the isolated test resource https://test.tuestudyhub.xyz/mcp and the production resource https://tuestudyhub.xyz/mcp are enabled. Each returns 401 with OAuth discovery metadata until a verified bearer token is presented. Dynamic registration lets a remote client register itself, so the acceptance evidence below must include the exact client name and redirect URI observed on the consent screen.

Apply the reviewed Supabase migrations and run database tests before enabling any environment. Keep production off while setting STUDYHUB_MCP_ENABLED=1 only in the isolated test environment, rebuild the container, and verify with one supported Claude client and one supported ChatGPT client:

  1. OAuth discovery, login, disconnect, and revocation.
  2. Search, source, conversation, Tutor-state, and progress reads.
  3. Native Tutor start, MCP continuation, then native continuation with one coherent revision chain.
  4. Note and flashcard writes becoming visible through ordinary browser sync.
  5. Stale Tutor and cloud-version rejection, cross-account isolation, rate-limit isolation, and the disabled route returning 404.

If any check fails, set STUDYHUB_MCP_ENABLED=0 in that environment and recreate the app container. This removes endpoint discovery without deleting synchronized records already created by accepted tool calls.

Production MCP was enabled on 2026-08-28 after the isolated test acceptance above passed, so the production environment now also carries STUDYHUB_MCP_ENABLED=1. To disable it, set STUDYHUB_MCP_ENABLED=0 in the production environment file and rebuild the production container; the same flag governs the test resource in its own environment file. Disabling one environment does not disable the other.

Verification

npm exec vitest run src/mcp src/ai/application src/app/mcp src/app/api/ai
npm run test:db
npm run check

The database command needs the local Supabase Docker stack. A unit-test pass is not a substitute for the pgTAP authorization, compare-and-swap, and rate-limit checks.