MCP server
Selah's Model Context Protocol server — endpoint, OAuth, and the tools an assistant can call on your account.
This is the technical reference for Selah's MCP server: the endpoint agents connect to, how they authenticate, and what they can call. If you just want to use Selah from an assistant, Connectors is the page you want.
Endpoint
POST https://selah.so/api/mcp
Model Context Protocol over Streamable HTTP, JSON-RPC 2.0. There is no SSE transport and no session affinity — every request stands alone, so any client that speaks Streamable HTTP works.
Protocol version: 2025-06-18. Server name: selah.
Authentication
OAuth 2.1 authorization code with PKCE. Selah does not issue its own tokens — Clerk is the authorization server. An unauthenticated call is answered with a 401 and the discovery pointer:
WWW-Authenticate: Bearer error="invalid_token",
error_description="No authorization provided",
resource_metadata="https://selah.so/.well-known/oauth-protected-resource/mcp"
From there the flow is the standard one:
- Protected resource metadata —
https://selah.so/.well-known/oauth-protected-resource/mcpnames the authorization server. - Authorization server metadata —
https://clerk.selah.so/.well-known/oauth-authorization-servercarries the authorize, token and registration endpoints. - Client identity — either register dynamically (RFC 7591) at
https://clerk.selah.so/oauth/register, or use a Client ID Metadata Document: an HTTPS URL as yourclient_id, no pre-registration. Both are advertised; pick whichever your client prefers. - Authorize and exchange — PKCE with
S256is required. Scopes areopenid profile email.
Access tokens are JWTs. A user who has never used Selah gets an account during this flow, so "connect" and "sign up" are the same action.
Limits and errors
- Rate limit — 120 tool calls per minute per user. Over it, a JSON-RPC
error with HTTP 429 and
Retry-After. - Transient failures — if Selah cannot verify a token because of an
upstream outage, the answer is 503 with
Retry-After, never a 401. A 401 always means the token is genuinely no longer valid and re-authorization is the right response. - Tool errors — returned as an MCP result with
isError: trueand a stable code instructuredContent.code:invalid_input,licensed_translation,not_found,conflict,entitlement,refused_needs_approval,rate_limited,unavailable,internal. The text alongside it names the next step. - Retry safety — an identical write repeated within two minutes returns the first result instead of applying twice, and a retry that arrives while the first call is still running joins it. Writes return the id of what they created.
Tools
Twenty tools, all scoped to the connected account. Required inputs are listed;
every tool takes more optional ones, and the served JSON Schema in
tools/list is the contract.
Reading scripture
| Tool | Required | Notes |
|---|---|---|
read_passage | reference | Berean Standard Bible, World English Bible or King James Version. Other translations are licensed and are not served here. |
get_cross_refs | book, chapter | Cross-references for a verse or chapter. |
lookup_lexicon | strong_id | Strong's entry for a Greek or Hebrew word. |
The person's own material
| Tool | Required | Notes |
|---|---|---|
search_notes | query | Meaning and text search across their notes. |
find_notes | — | Find notes by title fragment, kind or folder. |
read_note | — | Full text of one note, by id or title. |
read_prayers | — | Their prayer list, filterable by status. |
recall_beliefs | topic | What they have written about a topic. |
sharpen_belief | belief | Material for pressure-testing a belief they hold. |
Writing
| Tool | Required | Notes |
|---|---|---|
save_capture | content | A quick thought into their stream. |
save_prayer | title, content | A prayer request. |
update_prayer_status | prayer_id, status | Active, waiting, answered or ongoing. |
create_note | title, content | A new note. |
edit_note | operations | Additions only: append, prepend, or insert after a heading. |
undo_note_edit | note_id | Undo an edit made through the connector. |
Reading plans
| Tool | Required | Notes |
|---|---|---|
list_reading_plans | — | Curated plans plus any generated for this person. |
start_reading_plan | plan_id | Resumes a paused plan, or starts at day 1. |
get_today_reading | — | Plan name, day number, passages, whether today is done. |
mark_reading_done | — | Marks today; marking twice is a no-op. |
create_reading_plan | goal, day_count | Generates a 30, 60 or 90 day plan. Takes up to a minute and reports progress. |
What the connector cannot do
Rewriting or deleting existing note text, and changing profile or
notification settings, are refused with refused_needs_approval and a message
pointing back to Selah. There is no approval prompt to pause into over MCP, so
those stay in the app where the person can see what they are agreeing to.
No tool can reach another person's data. Licensed translations are never served. Tasks are not exposed.
Privacy
Analytics record the tool name, the client name, how long the call took, and whether it failed. Arguments and responses are never recorded, and neither is note, prayer or capture content. Anything written through the connector is labelled in Selah as coming from an assistant.
Questions
Write to hello@selah.so.