Reference
MCP server
Connect any LLM, agent, or automation pipeline to CourseFoundry via its Model Context Protocol (MCP) server - a single JSON-RPC 2.0 endpoint.
Overview
CourseFoundry exposes a JSON-RPC 2.0 endpoint at:
POST https://www.coursefoundry.com/api/mcpAlways use
www.coursefoundry.com. The bare domain (coursefoundry.com) issues a 308 redirect that breaks POST requests in many clients (curl, Postman, GitHub Actionscurl).
Authentication uses a Bearer token created in Settings → MCP API Keys.
Tokens have the prefix cfry_. See the quick start to
create one.
Add to Claude Code
Register CourseFoundry as an MCP server in Claude Code:
claude mcp add --transport http coursefoundry https://www.coursefoundry.com/api/mcp \
--header "Authorization: Bearer cfry_YOUR_KEY"After adding, try these prompts in Claude Code:
- “List my CourseFoundry courses”
- “Create a new course called Intro to Python with 5 lessons”
- “Show me the content of lesson
module-1/intro.qmdin course [id]” - “Generate a course outline for a Rust programming module”
- “Run the assessment workflow on lesson [id] in course [id]”
GitHub Actions
Store your key as a repository secret named COURSEFOUNDRY_API_KEY (repo → Settings → Secrets and variables → Actions → New repository secret), then
call the endpoint from a workflow step:
- name: Update lesson via CourseFoundry MCP
run: |
curl -X POST https://www.coursefoundry.com/api/mcp \
-H "Authorization: Bearer ${{ secrets.COURSEFOUNDRY_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_lesson",
"arguments": {
"course_id": "YOUR_COURSE_ID",
"path": "module-1/intro.qmd",
"content": "# Updated content\n\nYour lesson body here."
}
},
"id": 1
}'Always store keys as encrypted repository secrets - never inline in workflow YAML.
Direct HTTP
The endpoint works from any language or tool. Discover the available tools:
curl -X POST https://www.coursefoundry.com/api/mcp \
-H "Authorization: Bearer cfry_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'Create a course:
curl -X POST https://www.coursefoundry.com/api/mcp \
-H "Authorization: Bearer cfry_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_course",
"arguments": {
"title": "Introduction to Rust",
"description": "A beginner-friendly course on the Rust programming language."
}
},
"id": 1
}'For the complete list of tools, resources, prompts, and AI workflows - with request shapes for each - see the API reference.
ChatGPT custom GPTs
Custom GPTs can call the MCP endpoint directly. Use tools/list in your action schema to
discover available tools. Only POST is supported - GET is not a valid
method for this endpoint.
Troubleshooting
308 redirect on POST
Symptom: curl or Postman gets a redirect and the body is lost. Fix: use https://www.coursefoundry.com/api/mcp - not the bare domain.
401 Unauthorized
{"error":"unauthorized"} usually means:
- The key was revoked in Settings.
- The key was pasted incorrectly (missing
cfry_prefix or trailing whitespace). - The
Authorization: Bearer cfry_...header is not set.
403 read_only_scope
The key was created with Read scope and you called a write, destructive, or AI tool. Create a Read + Write key, or switch your integration to one.
Credit limit errors
run_workflow consumes AI credits. Check your plan's monthly limit in Settings -
Creator (500) or Pro (2,000) if you need more.
Connection refused / timeout
- Verify your network can reach
www.coursefoundry.com. - If using a corporate proxy, ensure it does not strip the
Authorizationheader.
Per-course tutor server (no key)
Published, AI-readable courses also expose a read-only public MCP server at /mcp/<username>/<course-slug> - learners point their own Claude or ChatGPT at
it to study the course. It offers search and lesson-retrieval tools only, with assessment answers
fenced out, and needs no API key. Authors enable it from the course's publishing settings.
Security notes
- API keys are SHA-256 hashed at rest - a lost key cannot be recovered, only regenerated.
- Keys do not expire automatically. Rotate them periodically.
- Use read-only keys wherever write access is not required.
- Keys are tied to your account; closing your account invalidates them all.