Authentication
Bearer tokens, capabilities, and folder scope. How requests are authorized.
The MCP server and the REST API use the same authentication primitive: a per-user bearer token. One token works on either surface.
Minting a token
Go to graniite.co/settings/integrations and click + Create token. The dialog uses a two-axis picker:
- Name: for your reference. Pick something that identifies the client (for example,
claude-desktop,cursor, orn8n-twilio-sync). - Capabilities:
readis always implicit. Checkwriteif the integration needs to add or modify content. - Access: choose between Whole library and Specific folders. Selecting specific folders opens a multi-select.
- KB items only: recommended for agents. When checked,
list_recentandget_itemskip items the user flagged as not-in-KB. Search is always KB-only. - Auto-revoke after: defaults to 1 year. Shorter windows reduce the blast radius of a leak.
Using a token
REST API
curl https://graniite.co/api/v1/folders \
-H "Authorization: Bearer lev_…"MCP
Most MCP clients (Claude Desktop, Cursor, ChatGPT, claude.ai) speak HTTP MCP natively and handle the OAuth flow for you. Paste https://graniite.co/api/mcp into the client's integrations UI. For older clients that only speak stdio, bridge via mcp-remote.
For programmatic JSON-RPC use:
curl https://graniite.co/api/mcp \
-X POST \
-H "Authorization: Bearer lev_…" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_recent","arguments":{"limit":5}}}'Capabilities
| Capability | What it unlocks |
|---|---|
read | MCP read tools (search_knowledge_base, get_item, list_recent) and all REST GET endpoints |
write | MCP add_to_knowledge and REST POST / DELETE (ingest, uploads, delete, organize) |
If a token is missing the required capability, the response is 403 capability_denied:
{
"error": "capability_denied",
"required": "write",
"have": ["read"]
}Folder scope
A token sees either the whole library or a specific list of folders.
Whole library (is_unscoped: true)
- Sees every folder the user owns
- Can create folders (
POST /api/v1/folders) - Can delete folders (
DELETE /api/v1/folders/{id}) - New items are not auto-filed (see the scope-size-1 rule below)
Specific folders (list of UUIDs)
- Sees only the listed folders, for both read and write
- Cannot create or delete folders. Scope is fixed at mint time and a scoped token cannot grow its own access.
- Cannot delete a folder that is in its own scope (self-destruct guard)
- For single-folder tokens, new items auto-file into the one folder
- For multi-folder tokens, items can be added or removed across the listed folders via
POST /items/{id}/foldersandDELETE /items/{id}/folders/{folderId}
Scope-size-1 rule (auto-file)
When the scope is exactly one folder, MCP add_to_knowledge and REST POST /ingest auto-file new items into that folder. This supports the common "one client, one folder, one agent" pattern.
Tokens with multi-folder or whole-library scope leave new items unfiled. File them explicitly via POST /api/v1/items/{id}/folders.
Token lifecycle
- Active: usable
- Revoked:
revoked_at IS NOT NULL. Any subsequent request is rejected with 401. - Expired:
expires_at < now(). Any subsequent request is rejected with 401.
Tokens auto-revoke in three cases:
- The user clicks Revoke in the UI
- The user changes their account password (all tokens are revoked at once)
- A scoped token's last in-scope folder is deleted (otherwise the token would silently return empty results from every endpoint)
Security
- Do not paste tokens into public repos. GitHub's secret scanner catches the
lev_prefix and we get notified, but the token is already compromised by then. If it happens, revoke immediately at/settings/integrations. - Do not share tokens between clients. Use one token per integration so you can revoke individually.
- Use shorter expiry for sensitive integrations. The default is 1 year. Drop to 30 or 90 days for third-party integrations.
- Use
kb_onlyfor any client that does not need to see the user's not-in-KB items.
Activity log
Every request through MCP or REST writes an entry to mcp_query_log, visible at /settings/integrations under Agent activity. The entry includes the timestamp, surface (MCP or REST), method, source IP, user agent, result count, and latency.
Use this log to audit what an integration actually did. If a token becomes behaviorally suspicious, you have a forensic trail.