MCP tools reference

Teachable MCP tools

15 tools for Teachable on the Cotlet MCP server. Your agent picks them from tools/list.

MCP server
https://cotlet.dev/mcp/v1
Connects with
Your own Teachable school owner account
Integration page
Teachable
Teachable Endpoints
Endpoint Access Description
teachable_list_courses read Courses in your school with name, published state and URL.
teachable_get_curriculum read Sections and lessons of a course, in order, with published and public preview flags.
teachable_get_lesson read Lesson content as blocks: text as Markdown, plus the type of each video, PDF, audio, quiz and other block.
teachable_list_students read Students with name, email and join date, or the students of one course.
teachable_list_comments read Lesson comments across your school or one course, with author, lesson, status and unread flag.
teachable_list_coupons read School and product coupons with code, discount, uses, expiry and status.
teachable_create_lesson write New unpublished lesson at the end of a section, with text from Markdown.
teachable_update_lesson write Rename a lesson or replace the text of its Text & Image block. Other blocks stay as they are.
teachable_publish_lesson write Publish a lesson so enrolled students see it, or unpublish it.
teachable_create_coupon write Coupon code for all products, one product type or one pricing plan.
teachable_archive_coupon write Unpublish a coupon so the code stops working. Archived codes can be used again.
teachable_enroll_student write Enroll a student in a course for free, adding them to your school first if the email is new.
teachable_send_email write Send an email from your school to chosen users, the students of a course or all users, as on the Emails, Compose page.
teachable_reply_to_comment write Reply to a lesson comment as the school owner. The reply is public to the course.
teachable_moderate_comment write Approve or deny a comment held in Pending Approval.

MCP tool teachable_list_courses

Returns every course in your school, in the order the Courses page shows them. Use course_id from each item in the other tools. Set published to see only the courses students can enroll in.

Parameters

Parameters: list_courses
NameTypeDescription
published boolean Only published courses. Default: all.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_list_courses",
    "arguments": {}
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "courses": [
      {
        "course_id": "1204512",
        "name": "Python for Beginners",
        "published": true,
        "url": "https://yourschool.teachable.com/p/python-for-beginners"
      },
      {
        "course_id": "1260077",
        "name": "Team Onboarding",
        "published": false,
        "url": "https://yourschool.teachable.com/p/team-onboarding"
      }
    ]
  },
  "isError": false
}

MCP tool teachable_get_curriculum

Returns the Curriculum tab of one course: sections in order, and the lessons inside each section in order. Each lesson has a published flag and a public preview flag. Use lesson_id with get_lesson, update_lesson and publish_lesson.

Parameters

Parameters: get_curriculum
NameTypeDescription
course_id required string Course ID from list_courses.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_get_curriculum",
    "arguments": {
      "course_id": "course_8c41d2"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "course_id": "1204512",
    "sections": [
      {
        "section_id": "9120331",
        "name": "Basics",
        "lessons": [
          {
            "lesson_id": "35120871",
            "name": "Lesson 1: Welcome",
            "published": true,
            "public_preview": true
          },
          {
            "lesson_id": "35120874",
            "name": "Lesson 3: Functions",
            "published": true,
            "public_preview": false
          }
        ]
      }
    ]
  },
  "isError": false
}

Get lesson

read

MCP tool teachable_get_lesson

Returns the blocks of one lesson in the order the lesson editor shows them. Text & Image blocks come back as Markdown with a block_id. Other blocks (video, PDF viewer, audio, resource, quiz and so on) come back with their type and title only.

Parameters

Parameters: get_lesson
NameTypeDescription
course_id required string Course ID from list_courses.
lesson_id required string Lesson ID from get_curriculum.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_get_lesson",
    "arguments": {
      "course_id": "course_8c41d2",
      "lesson_id": "lesson_8c41d2"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "lesson_id": "35120874",
    "name": "Lesson 3: Functions",
    "published": true,
    "blocks": [
      {
        "block_id": "b_5521",
        "type": "text_and_image",
        "body_markdown": "# Functions\n\nA function groups steps you want to reuse."
      },
      {
        "block_id": "b_5522",
        "type": "video",
        "title": "Functions in 6 minutes"
      }
    ]
  },
  "isError": false
}

MCP tool teachable_list_students

Lists students of your school, newest first. Pass course_id to list only the students enrolled in one course. Pages hold up to 100 students; pass next_cursor back as cursor for the next page. Use the emails with send_email when you need part of a course.

Parameters

Parameters: list_students
NameTypeDescription
course_id string Only students enrolled in this course.
limit integer 1 to 100. Default: 50.
cursor string Next page cursor from the previous call.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_list_students",
    "arguments": {}
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "students": [
      {
        "user_id": "70418822",
        "name": "Maria Kowal",
        "email": "maria.kowal@example.com",
        "joined_at": "2026-09-28T10:14:00Z"
      }
    ],
    "next_cursor": null
  },
  "isError": false
}

MCP tool teachable_list_comments

Lists comments the way Site, Comments does, newest first. Status pending returns the Pending Approval queue, which exists only when Comment moderation is on; denied returns comments you denied, which stay in your admin. Use comment_id with moderate_comment and reply_to_comment.

Parameters

Parameters: list_comments
NameTypeDescription
course_id string Only comments in this course. Default: all courses.
status enum all, pending or denied. Default: all.
unread_only boolean Only comments you have not marked as read.
limit integer 1 to 100. Default: 50.
cursor string Next page cursor from the previous call.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_list_comments",
    "arguments": {}
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "comments": [
      {
        "comment_id": "88120431",
        "course_id": "1204512",
        "lesson": "Lesson 3: Functions",
        "author": "Maria Kowal",
        "body": "Can a function return two values?",
        "status": "pending",
        "unread": true,
        "created_at": "2026-10-09T14:32:00Z"
      }
    ],
    "next_cursor": null
  },
  "isError": false
}

MCP tool teachable_list_coupons

Returns the coupons from the Coupons page: school coupons (all products or one product type) and product coupons (one pricing plan). Archived coupons are left out unless you ask for them. Check the list before create_coupon so a code is not used twice.

Parameters

Parameters: list_coupons
NameTypeDescription
include_archived boolean Also list archived coupons. Default: false.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_list_coupons",
    "arguments": {}
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "coupons": [
      {
        "coupon_id": "3917702",
        "name": "Summer sale",
        "code": "SUMMER20",
        "discount": "20%",
        "applies_to": "all_products",
        "expires_at": "2026-09-01",
        "quantity": 500,
        "used": 212,
        "status": "archived"
      }
    ]
  },
  "isError": false
}

MCP tool teachable_create_lesson

Adds a lesson to a section, like New lesson in the Curriculum tab. New lessons start unpublished, so no student sees it until publish_lesson runs. That is why create_lesson runs without asking first.

Parameters

Parameters: create_lesson
NameTypeDescription
course_id required string Course ID from list_courses.
section_id required string Section ID from get_curriculum.
title required string Lesson name.
body_markdown string Text for a Text & Image block. Images by URL.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_create_lesson",
    "arguments": {
      "course_id": "course_8c41d2",
      "section_id": "section_8c41d2",
      "title": "title"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "lesson_id": "35120990",
    "name": "Lesson 4: Loops",
    "section_id": "9120331",
    "published": false
  },
  "isError": false
}

Update lesson

write Confirm

MCP tool teachable_update_lesson

Renames a lesson and replaces the text of one Text & Image block; video, PDF, audio and quiz blocks are not touched. Teachable saves edits to a published lesson live at once, so students see the change right away. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: update_lesson
NameTypeDescription
course_id required string Course ID from list_courses.
lesson_id required string Lesson ID from get_curriculum.
title string New lesson name.
body_markdown string New text for the Text & Image block.
block_id string Text & Image block ID from get_lesson. Default: the first one.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_update_lesson",
    "arguments": {
      "course_id": "1204512",
      "lesson_id": "35120874",
      "title": "Lesson 3: Functions",
      "body_markdown": "# Functions\n\nA function groups steps you want to reuse."
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "lesson_id": "35120874",
    "name": "Lesson 3: Functions",
    "updated_block_id": "b_5521",
    "published": true,
    "updated_at": "2026-10-11T09:20:00+02:00"
  },
  "isError": false
}

Publish lesson

write Confirm

MCP tool teachable_publish_lesson

Does what Publish and Unpublish do in the lesson editor. Unpublished lessons are hidden from students, and a section whose lessons are all unpublished is hidden too. The course itself must be published and enrollable on its Information tab. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: publish_lesson
NameTypeDescription
course_id required string Course ID from list_courses.
lesson_id required string Lesson ID from get_curriculum.
published boolean false unpublishes. Default: true.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_publish_lesson",
    "arguments": {
      "course_id": "course_8c41d2",
      "lesson_id": "lesson_8c41d2"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "lesson_id": "35120874",
    "published": true
  },
  "isError": false
}

Create coupon

write Confirm

MCP tool teachable_create_coupon

Creates a coupon on the Coupons page. The code holds letters and numbers only. Quantity is the number available, up to 10,000. Teachable does not sell a paid product below $1.00 USD. The code takes money off your sales. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: create_coupon
NameTypeDescription
name required string Internal name, for your own list.
code required string Letters and numbers only.
discount_type required enum percent or amount.
discount required integer Percent off, or the fixed amount off.
applies_to enum all_products, courses, coaching, digital_downloads, memberships, bundles or pricing_plan. Default: all_products.
pricing_plan_id string Required when applies_to is pricing_plan.
expires_at date Last day the code works.
quantity integer Number available, 1 to 10000.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_create_coupon",
    "arguments": {
      "name": "Black Friday 2026",
      "code": "BLACKFRIDAY",
      "discount_type": "percent",
      "discount": 30,
      "applies_to": "courses",
      "expires_at": "2026-12-01",
      "quantity": 100
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "coupon_id": "3918274",
    "name": "Black Friday 2026",
    "code": "BLACKFRIDAY",
    "discount": "30%",
    "applies_to": "courses",
    "expires_at": "2026-12-01",
    "quantity": 100,
    "used": 0,
    "status": "active"
  },
  "isError": false
}

Archive coupon

write Confirm

MCP tool teachable_archive_coupon

Archives a coupon, which is how Teachable unpublishes one. Buyers who have the code can no longer use it. An archived code can be used for a new coupon later. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: archive_coupon
NameTypeDescription
coupon_id required string Coupon ID from list_coupons.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_archive_coupon",
    "arguments": {
      "coupon_id": "coupon_8c41d2"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "coupon_id": "3917702",
    "code": "SUMMER20",
    "status": "archived"
  },
  "isError": false
}

Enroll student

write Confirm

MCP tool teachable_enroll_student

Does what manual enrollment does in the Users menu: the student gets access to the course with no payment. A new email is added to your school first, because adding a student does not enroll them. Teachable sends no confirmation email for manual enrollments, and plan limits such as access duration or enrollment caps do not apply. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: enroll_student
NameTypeDescription
email required string Student email.
course_id required string Course ID from list_courses.
name string Full name, used when the student is new.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_enroll_student",
    "arguments": {
      "email": "jane@example.com",
      "course_id": "course_8c41d2"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "user_id": "70418901",
    "email": "maria.kowal@example.com",
    "course_id": "1204512",
    "status": "enrolled",
    "user_created": true,
    "confirmation_email_sent": false
  },
  "isError": false
}

Send email

write Confirm

MCP tool teachable_send_email

Sends a custom email from your school. Students who opted out of instructional and promotional emails in their profile do not receive it. To reach part of a course, take the emails from list_students and pass them in user_emails. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_email
NameTypeDescription
to required enum users, course or all_users.
user_emails string[] Recipients when to is users.
course_id string Recipients when to is course.
subject required string Email subject.
body_markdown required string Email body.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_send_email",
    "arguments": {
      "to": "users",
      "subject": "subject",
      "body_markdown": "body markdown"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "email_id": "em_4471",
    "to": "course",
    "course_id": "1204512",
    "subject": "Live Q&A moved to Thursday",
    "status": "sent",
    "sent_at": "2026-10-11T09:30:00+02:00"
  },
  "isError": false
}

Reply to comment

write Confirm

MCP tool teachable_reply_to_comment

Posts a reply under one comment, as the Reply button does in your comment admin. Comments are public and cannot be made private, so the whole course sees the reply. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: reply_to_comment
NameTypeDescription
comment_id required string Comment ID from list_comments.
body required string Reply text.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_reply_to_comment",
    "arguments": {
      "comment_id": "comment_8c41d2",
      "body": "body"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "reply_id": "88120502",
    "comment_id": "88120431",
    "status": "published"
  },
  "isError": false
}

Moderate comment

write Confirm

MCP tool teachable_moderate_comment

Does what Approve and Deny do on a pending comment. An approved comment appears on the lesson. A denied comment stays in your comment admin with a Denied tag and is hidden from students. Pending Approval exists only when Comment moderation is on. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: moderate_comment
NameTypeDescription
comment_id required string Comment ID from list_comments.
decision required enum approve or deny.

tools/call

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "teachable_moderate_comment",
    "arguments": {
      "comment_id": "88120431",
      "decision": "approve"
    }
  }
}

Example response

{
  "content": [
    {
      "type": "text",
      "text": "{ ... same JSON as structuredContent ... }"
    }
  ],
  "structuredContent": {
    "comment_id": "88120431",
    "status": "approved"
  },
  "isError": false
}