Skip to documentation

Documentation

ginny

ginny MCP server

Connect an MCP client to ginny with Streamable HTTP, OAuth, scoped access, and explicit approval for every write.

Endpoint and transport

ginny exposes a single MCP endpoint using Streamable HTTP. Requests are JSON-RPC 2.0 messages over HTTP POST. Clients must also accept text/event-stream because the server may select an SSE response for a successful request.

  • Use HTTPS and send JSON-RPC 2.0 request IDs on calls that expect a response.
  • Send both application/json and text/event-stream in Accept.
  • Do not open a legacy standalone SSE endpoint; Streamable HTTP uses the MCP URL above.
  • Browser clients must send their real Origin. Unexpected origins are rejected.

OAuth

The MCP endpoint is an OAuth-protected resource. Start without credentials, follow the 401 Unauthorized challenge and protected-resource metadata, then use the advertised authorization server. Public clients should use an authorization-code flow with PKCE.

  1. Discover protected-resource metadata from the challenge.
  2. Request only the scopes needed for the current workflow.
  3. Complete user authorization and obtain an audience-bound access token.
  4. Send the token only as Authorization: Bearer <token>.
  5. On 401, refresh or reauthorize once; never loop indefinitely.

Store refresh tokens in platform-secure storage. Never put an OAuth token in a JSON-RPC parameter, MCP tool argument, URL, log, or model-visible prompt.

Initialize a session

Send initialize first. The example proposes protocol version 2025-06-18; the server response determines the negotiated version. Capture the MCP-Session-Id response header when present.

Initialize
export facoolta_mcp_token='oauth-access-token'

curl --include --request POST https://mcp.facoolta.com/mcp \
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --header 'Origin: https://client.example.com' \
  --header "Authorization: Bearer $facoolta_mcp_token" \
  --data '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": {},
      "clientInfo": { "name": "campus-client", "version": "1.0.0" }
    }
  }'

After accepting the server response, send notifications/initialized with the negotiated protocol version and session ID.

Initialization complete
curl --request POST https://mcp.facoolta.com/mcp \
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --header 'Origin: https://client.example.com' \
  --header 'MCP-Protocol-Version: 2025-06-18' \
  --header "MCP-Session-Id: $facoolta_mcp_session_id" \
  --header "Authorization: Bearer $facoolta_mcp_token" \
  --data '{"jsonrpc":"2.0","method":"notifications/initialized"}'

Required headers

HeaderWhenValue
AuthorizationEvery protected requestBearer <OAuth access token>
Content-TypePOST requestsapplication/json
AcceptPOST and stream-capable requestsapplication/json, text/event-stream
OriginBrowser requestsThe client’s real, approved HTTPS origin
MCP-Protocol-VersionAfter initializationThe negotiated protocol version
MCP-Session-IdWhen issued by the serverThe exact opaque response-header value

Scopes

courses:read
Search and read course context visible to the user.
files:read
Search, inspect, and summarize files the user can access.
calendar:read
Read deadlines and calendar context.
reminders:write
Create, change, or remove reminders after approval.
tasks:write
Create, change, or complete tasks after approval.
messages:write
Post an approved message to facultalk.
doctor:write
Run approved doctor scans and analysis that may persist results.

A granted scope is permission to request an operation, not blanket consent to perform it. Resource-level authorization and write approval are evaluated for every tool call.

Tool surface

Discover exact tool names and input schemas at runtime with tools/list. Do not hard-code names from screenshots or earlier sessions.

Discover tools
curl --request POST https://mcp.facoolta.com/mcp \
  --header 'Accept: application/json, text/event-stream' \
  --header 'Content-Type: application/json' \
  --header 'Origin: https://client.example.com' \
  --header 'MCP-Protocol-Version: 2025-06-18' \
  --header "MCP-Session-Id: $facoolta_mcp_session_id" \
  --header "Authorization: Bearer $facoolta_mcp_token" \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
CapabilityTypical scopeMode
Course searchcourses:readRead
File search and summariesfiles:read, sometimes courses:readRead
Deadlinescalendar:readRead
Reminder managementreminders:writeWrite + approval
Task managementtasks:writeWrite + approval
doctor scanning and analysisdoctor:writeWrite + approval
facultalk postingmessages:writeWrite + approval

Human approval for writes

An approval UI should expose:

  • the action and destination;
  • the exact content, due date, recipients, or affected records;
  • whether the action is reversible;
  • a clear confirm control and an equally available cancel control.

Approval is single-use. If arguments change, the tool retries after a timeout, or the target is resolved differently, ask again. Never auto-approve a write because a previous, similar action was accepted.

Session lifecycle

  • Treat the session ID as opaque and keep it out of model context and logs.
  • On an unknown-session response, discard the ID and initialize a new session.
  • Reconnect streams with bounded backoff and preserve the negotiated version.
  • If the server supports session termination, send HTTP DELETE with the same OAuth, version, and session headers.
  • On sign-out or OAuth revocation, close active streams and clear the local session ID.