LinkedIn Learning MCP server
Registry name: io.github.johnisanerd/linkedin-learning. Maintained by AlphaOSINT (Apify developer johnvc, GitHub johnisanerd).
What it does
Search LinkedIn Learning courses by keyword, level, length or software and get full course records with rating, review text, syllabus, instructors, skills and certificates.
Course catalog data for training and upskilling. Use it for learning-path recommendations, course comparison and skills research.
Paid service on Apify’s hosted endpoint
This server is not self-hosted. It runs on Apify’s hosted MCP endpoint (mcp.apify.com), which starts the Apify Actor johnvc/linkedin-learning-api for each tool call. You need an Apify account, and every call is billed to that account at the Actor’s prices below. Apify’s own pricing and terms apply to the account.
| Charge | Price (USD) | What it covers |
|---|---|---|
| Course found | $0.00001 | Charged once for each course returned by a search or topic page, with its title, instructors, length, level, thumbnail and link. Not charged for duplicates, for the popular-courses list LinkedIn shows when a query match… |
| Full course record | $0.00001 | Charged once for each full course record returned: rating, learner reviews, the complete syllabus with per-lesson descriptions, free-lesson flags, instructors, skills and certificate details. Replaces the search charge… |
Prices shown are Apify’s free-plan rates; paid Apify plans get lower per-event prices. Apify also bills a token amount per run start and per stored row ($0.00001, $0.00001). Prices change from time to time; the Actor’s page on Apify shows the current ones.
Data source and terms
LinkedIn Learning’s public course pages, collected by scraping. No login or cookies are used. The server returns the data as published at the time of the call. You are responsible for using it in line with the source’s terms and the laws that apply to you. AlphaOSINT is not affiliated with the source.
Endpoint
- Transport: Streamable HTTP
- URL:
https://mcp.apify.com/?tools=johnvc/linkedin-learning-api - Auth: Apify OAuth, or
Authorization: Bearer <APIFY_TOKEN>
Setup
Claude Code
claude mcp add --transport http linkedin-learning "https://mcp.apify.com/?tools=johnvc/linkedin-learning-api"
VS Code (.vscode/mcp.json)
{
"servers": {
"linkedin-learning": {
"type": "http",
"url": "https://mcp.apify.com/?tools=johnvc/linkedin-learning-api"
}
}
}
Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"linkedin-learning": {
"url": "https://mcp.apify.com/?tools=johnvc/linkedin-learning-api"
}
}
}
Claude Desktop (Settings → Connectors → Add custom connector, paste the URL). Older versions without remote connectors can bridge through mcp-remote in claude_desktop_config.json:
{
"mcpServers": {
"linkedin-learning": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.apify.com/?tools=johnvc/linkedin-learning-api"
]
}
}
}
Each client opens an Apify sign-in (OAuth) on first use. To use a token instead, send Authorization: Bearer <APIFY_TOKEN> as a header; create one under Apify Console → Settings → API & Integrations.
Tools
| Tool | What it does |
|---|---|
johnvc--linkedin-learning-api |
Runs the Actor with the parameters below and returns the result rows. |
get-actor-run |
Status of a run started by the tool, for long runs. |
get-dataset-items |
Pages through a run’s full output by datasetId when it is larger than the inline result. |
get-key-value-store-record |
Reads a record a run stored, such as a run report. |
abort-actor-run |
Stops a run. |
Apify’s endpoint adds the four helper tools automatically whenever an Actor tool is loaded.
Parameters of johnvc--linkedin-learning-api
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
mode |
string: search, details | yes | "search" |
Choose what to collect. Use ‘search’ to find courses by keyword with filters, or ‘details’ to pull the full record for course URLs you already have (ratings, reviews, syllabus, instructors, certificate). |
queries |
array | ["python"] |
Keywords to search, one per line. Each query is searched separately and its results are labelled with the query that found them. Used in ‘search’ mode only. Leave empty if you are browsing topic pages instead. | |
topics |
array | [] |
Optional LinkedIn Learning topic slugs or topic URLs to browse, such as ‘python’ or https://www.linkedin.com/learning/topics/python. Topic pages are an alternative to keyword search and return the same course fields. | |
sortBy |
string: RELEVANCE, POPULARITY, RECENCY | "RELEVANCE" |
Order the search results. ‘Most relevant’ is LinkedIn’s default ranking, ‘Most popular’ favours high view counts, and ‘Newest’ favours recent release dates. | |
difficultyLevel |
string: ANY, BEGINNER, INTERMEDIATE, ADVANCED | "ANY" |
Keep only courses at one skill level. Leave as ‘Any level’ to include all of them. | |
entityType |
string: ANY, COURSE, VIDEO, LEARNING_PATH | "ANY" |
Keep only one kind of content. Courses are full multi-lesson courses, videos are single lessons, and learning paths are curated multi-course tracks. | |
duration |
string: ANY, BETWEEN_0_TO_10_MIN, BETWEEN_10_TO_30_MIN, BETWEEN_30_TO_60_MIN, B… | "ANY" |
Keep only courses that fall in one length bracket. | |
softwareNames |
array | [] |
Keep only courses that teach this tool, using LinkedIn’s own label such as Python, Microsoft Excel, SQL, ChatGPT or Claude. The schema accepts up to 10, but LinkedIn applies only the first label it receives, so pass one… | |
maxItems |
integer | 50 |
How many courses to return for each query. LinkedIn serves at most 50 results per query and filter combination, so ask for more than 50 only with ‘Widen coverage’ turned on. Up to 1000 per query. Need larger batches? Co… | |
expandWithFilters |
boolean | false |
Run the same query again across LinkedIn’s own filter combinations (sort order, content type, difficulty, length) and merge the unique courses. This is the only way past the 50-per-query ceiling. It fetches more pages a… | |
enrichDetails |
boolean | false |
Open each course found by the search and return its full record, including rating, review text, syllabus and instructors. Enriched rows are billed at the course details rate instead of the search result rate, never both… | |
courseUrls |
array | [] |
LinkedIn Learning course, lesson or learning path URLs to collect in full, one per line. A course URL returns the full course record, a lesson URL returns that lesson linked to its parent course, and a learning path URL… | |
maxConcurrency |
integer | 5 |
How many course pages to read at once, in both ‘details’ mode and when ‘Include full course details’ is on. Raise it to finish a large run faster, lower it if you ever see rate limiting. | |
requestTimeoutSecs |
integer | 40 |
How long to wait for a single page before giving up and retrying it. |
Example arguments:
{
"helloWorld": 123
}
Output
The tool returns JSON rows with these fields.
| Field | Type | Description |
|---|---|---|
resultType |
string: search_result, course_detail, lesson, learning_path… | Which kind of row this is: a search result, a full course record, a lesson, a learning path, a no-match notice, or an error for one input. |
title |
string | Course, lesson, or learning path title as published on LinkedIn Learning. |
courseUrl |
string | Canonical LinkedIn Learning course link with tracking parameters removed. |
courseId |
string | Identifier for the COURSE, taken from the trailing number in its URL, or the URL slug when a course has no number. A lesson row carries its parent course’s id, so lessons can be joined to their course; use courseUrl or… |
sourceUrl |
string | The URL supplied as input or the page this row was read from. |
lessonUrl |
string | Direct link to a single lesson, when the row is a lesson. |
pathUrl |
string | Direct link to a learning path, when the row is a learning path. |
description |
string | Full course description as published on the course page. |
difficultyLevel |
string | Skill level LinkedIn assigns to the course. |
entityType |
string: COURSE, VIDEO, LEARNING PATH | Whether the search result is a course, a single video lesson, or a learning path. LinkedIn labels these COURSE, VIDEO and LEARNING PATH. |
instructors |
array | Everyone credited as an instructor. Search rows carry the name only; full course records add job title, LinkedIn profile link and photo. |
skills |
array | Skills and technologies the course covers, each linking to its LinkedIn Learning topic page. |
categoryPath |
array | Category hierarchy the course sits in, from broadest to narrowest. |
durationText |
string | Course length as published, in ISO 8601 form on detail rows and as displayed text on search rows. |
durationSeconds |
integer | Course length in whole seconds, parsed for sorting and filtering. |
enrollmentCount |
integer | How many people have taken the course to date. |
ratingValue |
number | Average learner rating out of 5. |
ratingCount |
integer | How many learners rated the course. |
reviews |
array | Written learner reviews with the rating, the review text, and the reviewer’s name, job title and profile link. |
tableOfContents |
array | Full syllabus: every section with its lessons, each carrying a title, a written description, its length, and whether it can be watched free. |
lessonCount |
integer | How many lessons the course contains. |
freeLessonCount |
integer | How many lessons can be watched without a subscription. |
hasCertificate |
boolean | Whether the course awards a certificate of completion. |
certificateName |
string | Name of the credential awarded. |
accessModel |
string | How the course is made available. LinkedIn Learning courses are subscription based and carry no individual price. |
language |
string | Language the course is taught in. |
provider |
string | Organization publishing the course. |
dateCreated |
string | When the course was created. |
datePublished |
string | When the course was published. |
thumbnailUrl |
string | Course artwork image link. The query string is part of the signed image URL and is preserved. |
isFree |
boolean | Whether this lesson can be watched without a subscription. |
requiresSubscription |
boolean | Whether this lesson needs a LinkedIn Learning subscription. |
courses |
array | Courses that make up a learning path, in order. |
courseCount |
integer | How many courses the learning path contains. |
searchQuery |
string | The query or topic that returned this row. |
searchType |
string: query, topic | Whether the row came from a keyword search or a topic page. |
searchPosition |
integer | Rank this course held in the search results that found it, on enriched rows. |
position |
integer | Rank of this result within its search page, starting at 1. |
appliedFilters |
object | Which LinkedIn filters were in force for the request that surfaced this row. |
approximateTotalResults |
integer | How many courses LinkedIn reports for this query. Approximate: the same query can report different totals across page variants, so treat it as a size signal rather than an exact count. |
viewersText |
string | Viewer count as displayed on the search card. |
releaseText |
string | Release date as displayed on the search card. |
parseSource |
string: jsonld, dom | Whether the record was read from the page’s structured data or from its markup. |
message |
string | Explanatory note, used on no-match rows. |
errorType |
string | Category of failure for an error row. |
errorMessage |
string | What went wrong, phrased for the person running the actor. |
httpStatus |
integer | Status code LinkedIn returned, when there was one. |
fetchedAt |
string | When this row was collected, in UTC. |
fromCache |
boolean | True when this course record was served from the shared result cache instead of a new page read; fetchedAt then holds the time it was originally read. Billed like a fresh record. Only full course records are cached; sea… |
Links
- Actor on Apify: johnvc/linkedin-learning-api
- Data source page on AlphaOSINT: /sources/linkedin-learning-api/
- All AlphaOSINT MCP servers: /mcp/