RRM Academy Agent API
v1.0.0 · OpenAPI 3.1.0
Programmatic access to the RRM Academy research library and editorial guardrails, exposed via the Model Context Protocol (MCP). 4,050+ peer-reviewed articles on restorative reproductive medicine, NaProTechnology, fertility awareness-based methods, endometriosis, PCOS, and related women's health topics. Clinical content curated under the direction of Dr. Naomi Whittaker, MD.
Server
https://mcp.rrmacademy.org Authentication
Bearer API key. Self-service issuance at /account/mcp-keys. Send as an HTTP header on every authenticated request:
Authorization: Bearer YOUR_API_KEY The /health endpoint is unauthenticated. All other endpoints require a valid key.
Endpoints
/api/ask NLWeb capability metadata
Returns machine-readable capability JSON describing the /api/ask endpoint: supported methods, auth model, streaming transport, request/response shape, and guardrails. Unauthenticated. Cacheable for 1 hour.
Responses
-
200Capability descriptor
/api/ask Conversational AI over the RRM Research Library
Answers questions scoped to restorative reproductive medicine using the RRM Library corpus. Two auth paths: **Session-authenticated (20 req/day):** Include the `session` cookie from `/api/auth/login`. Supports both JSON and SSE response formats based on the `Accept` header. **Anonymous (2 req/day/IP):** No cookie required. Always returns `text/event-stream`. Rate-limited per IP. Set `Accept: text/event-stream` to receive a streaming SSE response regardless of auth state.
Responses
-
200Answer with citations. Content-Type is `application/json` for authenticated requests without SSE Accept header, or `text/event-stream` for anonymous requests and any SSE-accepting request. -
400 -
422 -
429Rate limit exceeded. Session path: 20/day reset at midnight UTC. Anonymous path: 2/day, 48h TTL. -
503Upstream service unavailable
/api/articles List published library articles
Returns a paginated list of published, non-retracted research articles from the RRM Academy library. Public, unauthenticated. Rate limited to 30 requests per minute per IP. Responses are edge-cached for 1 hour.
Responses
-
200Paginated article list. -
400Invalid pagination parameters or malformed `ids` query. -
429Rate limited (30 req/min per IP) -
503Upstream library service unavailable
/api/articles/bulk Bulk-fetch articles by ID
Returns up to 50 published library articles by ID in a single call. Comma-separated IDs in the `ids` query parameter. Missing IDs are returned in `not_found[]` instead of producing a 404. Shares the 30 req/min IP budget with /api/articles.
Responses
-
200Bulk article results. Missing IDs appear in not_found[]. -
400Missing or malformed ids parameter. -
429Rate limited (30 req/min per IP, shared with /api/articles) -
503Upstream library service unavailable
/api/bulk Bulk-fetch articles by ID (top-level alias)
Top-level alias for /api/articles/bulk. Identical behavior. Shares the 30 req/min IP budget. Exists so URL-pattern scanners recognize the batch endpoint at /api/bulk.
Responses
-
200Bulk-fetch results (BulkArticleResponse shape) -
400Malformed `ids` query (regex mismatch). -
429Rate limited (30 req/min per IP) -
503Upstream library service unavailable
/api/ask/sandbox Canned sandbox response for integration testing
Returns a canned response with no LLM invocation, no auth, and no rate limit. Accepts the same JSON shape as /api/ask but ignores the body. Use to validate that your client correctly parses the AskResponse-shaped reply before integrating with the live /api/ask endpoint.
Responses
-
200Canned sandbox response. Shape matches SandboxAskResponse.
/mcp Bearer Invoke an MCP tool
Model Context Protocol JSON-RPC 2.0 entry point. Dispatches to one of five tools: search, check_guardrails, check_facts, get_article, find_related. Use the MCP client libraries (@modelcontextprotocol/sdk) for idiomatic access rather than raw HTTP.
Responses
-
200JSON-RPC response envelope -
400 -
401Missing or invalid bearer token -
422 -
429Rate limited -
503Upstream unavailable
/health Health check
Returns 200 when the MCP server is reachable. Unauthenticated.
Responses
-
200OK
/api/contact/submit Submit a contact form message
Responses
-
200Success -
400 -
422 -
429Rate limit exceeded -
503Service unavailable
/api/newsletter/subscribe Subscribe an email address to the newsletter
Responses
-
200Success -
400 -
422 -
429Rate limit exceeded -
503Service unavailable
/api/community/posts Create a community post
Responses
-
200Success -
400 -
401Authentication required -
422 -
429Rate limit exceeded
/api/community/posts Edit a community post the caller authored
Responses
-
200Success -
400 -
401Authentication required -
403Caller does not own the post -
422
/api/community/posts Delete a community post the caller authored
Responses
-
200Success -
400 -
401Authentication required -
403Caller does not own the post -
422
/api/community/comments Create a comment on a community post
Responses
-
200Success -
400 -
401Authentication required -
422 -
429Rate limit exceeded
/api/community/comments Edit a comment the caller authored
Responses
-
200Success -
400 -
401Authentication required -
403Caller does not own the comment -
422
/api/community/comments Delete a comment the caller authored
Responses
-
200Success -
400 -
401Authentication required -
403Caller does not own the comment -
422
/api/community/reactions Add a reaction to a post or comment
Responses
-
200Success -
400 -
401Authentication required -
422 -
429Rate limit exceeded
/api/community/reactions Remove a reaction the caller added
Responses
-
200Success -
400 -
401Authentication required -
422
/api/saved Save a library article to the caller's collection
Responses
-
200Success -
400 -
401Authentication required -
422
/api/saved Remove a library article from the caller's collection
Responses
-
200Success -
400 -
401Authentication required -
422
Code samples
Discover the available tools, then call one. Replace YOUR_API_KEY with a key from /account/mcp-keys.
curl
# 1. Initialize the session
curl -X POST https://mcp.rrmacademy.org/mcp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": { "name": "my-app", "version": "0.1" }
}
}'
# 2. List the available tools
curl -X POST https://mcp.rrmacademy.org/mcp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }'
# 3. Call a tool (search the library)
curl -X POST https://mcp.rrmacademy.org/mcp \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search",
"arguments": { "query": "endometriosis excision outcomes" }
}
}' Python (official MCP SDK)
# pip install "mcp[cli]"
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
headers = {"Authorization": "Bearer YOUR_API_KEY"}
async with streamablehttp_client(
"https://mcp.rrmacademy.org/mcp",
headers=headers,
) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
result = await session.call_tool(
"search",
{"query": "endometriosis excision outcomes"},
)
print(result)
import asyncio; asyncio.run(main()) Node.js (official MCP SDK)
// npm install @modelcontextprotocol/sdk
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const transport = new StreamableHTTPClientTransport(
new URL("https://mcp.rrmacademy.org/mcp"),
{
requestInit: {
headers: { Authorization: "Bearer YOUR_API_KEY" },
},
},
);
const client = new Client({ name: "my-app", version: "0.1.0" });
await client.connect(transport);
const tools = await client.listTools();
const result = await client.callTool({
name: "search",
arguments: { query: "endometriosis excision outcomes" },
});
console.log(result); Errors
All authenticated endpoints share the same error envelope:
{
"error": "machine_readable_code",
"message": "Human-readable explanation"
} 401— missing or invalid bearer token429— rate limited; back off and retry503— upstream unavailable; transient
Schemas
Full request/response shapes (JSON Schema) for the MCP envelope and error type are in the raw spec. The MCP SDKs handle envelope serialization for you — most users never need to construct JSON-RPC envelopes by hand.
Discovery files
- mcp.json descriptor — server metadata for agent discovery
- server card — full tool list with schemas
- RFC 9728 protected-resource metadata
- RFC 9727 API catalog
- llms.txt · llms-full.txt