API & MCP · MCP setup
MCP server setup
EMPO Academy speaks Model Context Protocol so any MCP-compatible AI client — Claude Desktop, Cursor, the Claude API SDK, OpenAI Agents SDK — can drive the platform with the same 14 tools.
Two transports
- Hosted Streamable HTTP— you point the client at
https://academy.empomm.com/api/mcpwith a bearer token. Zero install. Each tool call goes over the network. Subject to the same per-key (60/min) and per-IP (120/min) rate limits as the REST API, plus a 500 KB body capper request (413 on overflow — split big tool inputs across multiple calls). - Local stdio — you install the
@empo-academy/mcp-serverpackage once and your client spawns it as a subprocess. The tool calls still hit the hosted REST API under the hood, so the same rate limits apply.
Both end up calling the same REST API. Pick whichever your client supports best.
Claude Desktop (hosted)
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"empo-academy": {
"url": "https://academy.empomm.com/api/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer empo_xxxxxxxxxxxxxxxxxxxx"
}
}
}
}Restart Claude Desktop. New conversations get an EMPO tool list.
Claude Desktop (stdio)
- Clone the repo and build the package:
cd packages/empo-mcp && npm install && npm run build - Point Claude Desktop at the built binary:
{
"mcpServers": {
"empo-academy": {
"command": "node",
"args": ["/absolute/path/to/packages/empo-mcp/dist/index.js"],
"env": {
"EMPO_API_KEY": "empo_xxxxxxxxxxxxxxxxxxxx",
"EMPO_BASE_URL": "https://academy.empomm.com"
}
}
}
}Cursor
Open Cursor settings → MCP → Add server. The Cursor MCP UI accepts the same JSON shape as Claude Desktop. Use the hosted URL for the simplest setup.
Claude API SDK / OpenAI Agents SDK
Both SDKs ship an MCP client. Point them at the hosted endpoint with the bearer token and you’re done — same 14 tools, same permissions.
Tool reference
All tools (and their MCP Tool Annotations) follow the REST API one-to-one. Annotations are hints clients use to decide whether to prompt for confirmation; the server still enforces everything via scope + role checks regardless.
empo_me,empo_list_courses,empo_get_course,empo_list_notification_templates—readOnlyHint: trueempo_create_course,empo_update_course,empo_create_module,empo_create_lesson,empo_issue_training_certificate,empo_issue_training_certificate_batch,empo_resend_certificate_email,empo_update_notification_template— standard mutationsempo_set_course_status,empo_revoke_certificate—destructiveHint: true(Claude prompts before running)
Troubleshooting
- 401 from MCP endpoint: bearer token missing, malformed, expired, or revoked. Check /dashboard/api-keys.
- 403 MISSING_SCOPE: the key doesn’t include the scope the tool needs. Mint a new key with the right scope or add it.
- 403 FORBIDDEN: the underlying record (course, cert) isn’t owned by your user. Instructor keys can only act on their own courses (or courses where they’re a collaborator).
- 413 PAYLOAD_TOO_LARGE: request body exceeded the 500 KB cap. Common cause: pasting an entire markdown course into
empo_scaffold_course. Split the work — one course-shell call, then per-lessonempo_blocks_from_markdowncalls. - 429 RATE_LIMITED: you’ve hit the per-key (60/min) or per-IP (120/min) bucket. Back off on
Retry-Afterseconds; don’t loop blindly. If a legitimate integration needs more headroom, email academy@empomm.com. - Diagnose any of the above: open the offending key’s usage at
/dashboard/api-keys/<id>/usage— the last 25 calls show method/path/status/duration with the last error highlighted.