# Gravity auth.md

How an AI agent gets access to a person's Gravity notes. Gravity is a notes app; the API agents use is the Gravity MCP server.

## Audience

Agents and AI apps acting for one person who uses Gravity with Gravity Sync turned on. There is no service account and no anonymous access: every token belongs to one person's library, and that person approves the agent first.

## Resource

- MCP endpoint (Streamable HTTP): https://mcp.gravitynotes.app/mcp
- Protected resource metadata (RFC 9728): https://mcp.gravitynotes.app/.well-known/oauth-protected-resource/mcp
- Authorization server metadata (RFC 8414): https://mcp.gravitynotes.app/.well-known/oauth-authorization-server
- Issuer: https://mcp.gravitynotes.app
- MCP Server Card: https://mcp.gravitynotes.app/mcp/server-card

An unauthenticated request to the MCP endpoint returns `401` with `WWW-Authenticate: Bearer resource_metadata="..."` pointing at the protected resource metadata.

## Register

Registration is self-serve. Use either method; no API key, review or sales contact is needed.

1. **Client ID metadata document (preferred).** Host a JSON client metadata document at an HTTPS URL and use that URL as your `client_id`. The server fetches it when you authorize (`client_id_metadata_document_supported: true`).
2. **Dynamic client registration (RFC 7591).** `POST https://mcp.gravitynotes.app/oauth/register` with `redirect_uris`, `client_name`, `grant_types: ["authorization_code", "refresh_token"]`, `response_types: ["code"]` and `token_endpoint_auth_method` (`none` for public clients). The response carries your `client_id`.

## Authorize

OAuth 2.1 authorization code flow:

1. Send the person to `https://mcp.gravitynotes.app/authorize` with `response_type=code`, `client_id`, `redirect_uri`, `state`, a PKCE `code_challenge` with `code_challenge_method=S256`, `scope` and `resource=https://mcp.gravitynotes.app/mcp` (RFC 8707).
2. Gravity shows a consent page naming your agent. The person chooses read-only or read and write, then signs in with Apple, Google or an email code.
3. Gravity redirects to your `redirect_uri` with `code`, `state` and `iss` (RFC 9207). Check that `iss` is `https://mcp.gravitynotes.app`.
4. Exchange the code at `https://mcp.gravitynotes.app/oauth/token` with your `code_verifier` and the same `resource`.

## Scopes

- `notes:read`: search, list and read notes and tags.
- `notes:write`: add, append, edit, rescue, archive, restore and trash notes. There is no permanent delete.
- `offline_access`: a refresh token.

A write with a read-only token gets a step-up challenge (`insufficient_scope`) naming `notes:write`.

## Use the credential

Send `Authorization: Bearer <access_token>` on every request to https://mcp.gravitynotes.app/mcp. Tokens are bound to that resource and are refused anywhere else.

- Access tokens last one hour.
- Refresh tokens rotate on every use and expire after 60 days without use.
- Revoke a token at `https://mcp.gravitynotes.app/oauth/token` (RFC 7009).
- The person can disconnect your agent in Gravity under Settings → Gravity Sync → AI apps. Its next call fails, and refreshing returns `invalid_grant`. Ask them to connect again.

## Not supported

ID-JAG identity assertions, verified-email registration and anonymous registration are not offered: an agent can only reach notes that their owner has shared with it through the flow above.

## Docs

- Developer docs: https://www.gravitynotes.app/developers
- MCP server reference: https://www.gravitynotes.app/mcp
- API catalog (RFC 9727): https://www.gravitynotes.app/.well-known/api-catalog
- Contact: tristan@crowlabs.co
