Developer · API Reference

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

Base URL https://mcp.rrmacademy.org
Description Apex MCP server (high-level RAG, semantic search, editorial guardrails). Bearer auth, self-service keys at https://rrmacademy.org/account/mcp-keys.

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

GET /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

  • 200 Capability descriptor
POST /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

  • 200 Answer 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
  • 429 Rate limit exceeded. Session path: 20/day reset at midnight UTC. Anonymous path: 2/day, 48h TTL.
  • 503 Upstream service unavailable
GET /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

  • 200 Paginated article list.
  • 400 Invalid pagination parameters or malformed `ids` query.
  • 429 Rate limited (30 req/min per IP)
  • 503 Upstream library service unavailable
GET /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

  • 200 Bulk article results. Missing IDs appear in not_found[].
  • 400 Missing or malformed ids parameter.
  • 429 Rate limited (30 req/min per IP, shared with /api/articles)
  • 503 Upstream library service unavailable
GET /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

  • 200 Bulk-fetch results (BulkArticleResponse shape)
  • 400 Malformed `ids` query (regex mismatch).
  • 429 Rate limited (30 req/min per IP)
  • 503 Upstream library service unavailable
POST /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

  • 200 Canned sandbox response. Shape matches SandboxAskResponse.
POST /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

  • 200 JSON-RPC response envelope
  • 400
  • 401 Missing or invalid bearer token
  • 422
  • 429 Rate limited
  • 503 Upstream unavailable
GET /health

Health check

Returns 200 when the MCP server is reachable. Unauthenticated.

Responses

  • 200 OK
POST /api/contact/submit

Submit a contact form message

Responses

  • 200 Success
  • 400
  • 422
  • 429 Rate limit exceeded
  • 503 Service unavailable
POST /api/newsletter/subscribe

Subscribe an email address to the newsletter

Responses

  • 200 Success
  • 400
  • 422
  • 429 Rate limit exceeded
  • 503 Service unavailable
POST /api/community/posts

Create a community post

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 422
  • 429 Rate limit exceeded
PATCH /api/community/posts

Edit a community post the caller authored

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 403 Caller does not own the post
  • 422
DELETE /api/community/posts

Delete a community post the caller authored

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 403 Caller does not own the post
  • 422
POST /api/community/comments

Create a comment on a community post

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 422
  • 429 Rate limit exceeded
PATCH /api/community/comments

Edit a comment the caller authored

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 403 Caller does not own the comment
  • 422
DELETE /api/community/comments

Delete a comment the caller authored

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 403 Caller does not own the comment
  • 422
POST /api/community/reactions

Add a reaction to a post or comment

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 422
  • 429 Rate limit exceeded
DELETE /api/community/reactions

Remove a reaction the caller added

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 422
POST /api/saved

Save a library article to the caller's collection

Responses

  • 200 Success
  • 400
  • 401 Authentication required
  • 422
DELETE /api/saved

Remove a library article from the caller's collection

Responses

  • 200 Success
  • 400
  • 401 Authentication 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 token
  • 429 — rate limited; back off and retry
  • 503 — 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