MCP tools reference
Medium MCP tools
13 tools for Medium on the Cotlet MCP server. Your agent picks them from tools/list.
- MCP server
- https://cotlet.dev/mcp/v1
- Connects with
- Your own Medium account (writer or editor role in a publication to submit or schedule there)
- Integration page
- Medium
| Endpoint | Access | Description |
|---|---|---|
| medium_list_stories | read | Your stories, newest first, with status, publication, tags and URL. |
| medium_get_story | read | Full story: title, subtitle, body as Markdown, tags, canonical link, paywall and dates. |
| medium_get_story_stats | read | Views, reads, member read ratio, claps, responses and earnings for paywalled stories. |
| medium_get_account_stats | read | The account-level figures Medium shows on your stats page, for one month. |
| medium_list_responses | read | Responses to a story, with author, text and whether you replied. |
| medium_list_publications | read | Publications you own, edit or write for, with your role. |
| medium_create_draft | write | New draft from Markdown. Nothing is public until you publish or schedule it. |
| medium_import_story | write | Medium's "Import a story": copies a post from a URL into a draft, backdated, with a canonical link. |
| medium_update_story | write | Change the title, subtitle, body, tags, canonical link or paywall of a draft or a published story. |
| medium_publish_story | write | Publish a draft now. |
| medium_schedule_story | write | Publish a draft at a set time. |
| medium_submit_to_publication | write | Send a draft to the editors of a publication you write for. |
| medium_reply_to_response | write | Reply as you under a response to your story. |
List stories
readMCP tool medium_list_stories
Lists your own stories, newest first. Filter by status to find drafts or scheduled stories. Each item has the story_id used by the other tools. Pages hold up to 50 stories; pass next_cursor back as cursor for the next page.
Parameters
| Name | Type | Description |
|---|---|---|
| status | enum | published, draft or scheduled. Default: published. |
| limit | integer | 1 to 50. Default: 20. |
| cursor | string | Next page cursor from the previous call. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_list_stories",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"stories": [
{
"story_id": "3f9a1c27b84e",
"title": "Shipping small",
"status": "published",
"publication": null,
"tags": [
"Python",
"Programming"
],
"published_at": "2026-10-02T09:00:00-04:00",
"url": "https://medium.com/@yourname/shipping-small-3f9a1c27b84e"
}
],
"next_cursor": null
},
"isError": false
} Get story
readMCP tool medium_get_story
Returns one story with its body as Markdown. Use it before update_story so your agent changes only the part you asked for. Works for drafts, scheduled and published stories.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_get_story",
"arguments": {
"story_id": "story_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"title": "Shipping small",
"subtitle": "Why small releases win",
"body_markdown": "Small releases beat big ones.\n\nHere is why.",
"tags": [
"Python",
"Programming"
],
"canonical_url": "https://yourname.dev/blog/shipping-small",
"paywalled": false,
"status": "published"
},
"isError": false
} Get story stats
readMCP tool medium_get_story_stats
Returns the numbers from the story's detailed stats page. Member read ratio is member reads divided by member views, the figure Medium uses to adjust earnings. Earnings appear only for stories behind the paywall.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_get_story_stats",
"arguments": {
"story_id": "story_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"views": 1840,
"reads": 912,
"member_read_ratio": 0.42,
"claps": 143,
"responses": 6,
"earnings": {
"amount": 18.4,
"currency": "USD"
}
},
"isError": false
} Get account stats
readMCP tool medium_get_account_stats
Returns the account-level figures Medium shows on your stats page for one month. Use list_stories and get_story_stats to find which stories drove them.
Parameters
| Name | Type | Description |
|---|---|---|
| month | string | YYYY-MM. Default: current month. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_get_account_stats",
"arguments": {
"month": "2026-09"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"month": "2026-09",
"views": 9420,
"reads": 4310
},
"isError": false
} List responses
readMCP tool medium_list_responses
Lists the responses under one story, with the author, text and whether you already replied. Hidden responses are not returned. Pass response_id to reply_to_response.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
| unanswered_only | boolean | Skip responses you already replied to. |
| cursor | string | Next page cursor from the previous call. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_list_responses",
"arguments": {
"story_id": "story_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"responses": [
{
"response_id": "r_41b9c2",
"author": "Dana Whitfield",
"body": "The third example has a typo.",
"created_at": "2026-10-03T11:20:00Z",
"replied": false
}
],
"next_cursor": null
},
"isError": false
} List publications
readMCP tool medium_list_publications
Returns every publication you belong to with your role. Use the publication_id with submit_to_publication. Each publication sets its own rules for what it accepts.
Parameters
No parameters.
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_list_publications",
"arguments": {}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"publications": [
{
"publication_id": "pub_7d21",
"name": "Better Programming",
"role": "writer"
}
]
},
"isError": false
} Create draft
writeMCP tool medium_create_draft
Creates a draft from Markdown and returns its story_id. The draft is private. It reaches no one and is deleted or edited in one call, so it asks for no confirmation.
Parameters
| Name | Type | Description |
|---|---|---|
| title required | string | Story title. |
| body_markdown required | string | Story body. Images by URL. |
| subtitle | string | Shown under the title and in previews. |
| tags | string[] | Up to 5 tags. |
| canonical_url | string | Original URL if the story was first published elsewhere. |
| paywalled | boolean | Member-only story (Partner Program). Default: false. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_create_draft",
"arguments": {
"title": "Shipping small",
"subtitle": "Why small releases win",
"body_markdown": "Small releases beat big ones.\n\n## Here is why",
"tags": [
"Python",
"Programming",
"Software Engineering"
],
"paywalled": true
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"status": "draft",
"url": "https://medium.com/p/3f9a1c27b84e/edit"
},
"isError": false
} Import story
writeMCP tool medium_import_story
Runs Medium's importer on a public URL. The draft keeps the original date and gets a canonical link to the source. If Medium cannot read the page, the call fails and create_draft is the fallback. The draft is private, so no confirmation.
Parameters
| Name | Type | Description |
|---|---|---|
| url required | string | Public URL of the original post. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_import_story",
"arguments": {
"url": "https://yourname.dev/blog/shipping-small"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"status": "draft",
"canonical_url": "https://yourname.dev/blog/shipping-small"
},
"isError": false
} MCP tool medium_update_story
Changes only the fields you send. On a published story the change is visible to readers at once. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
| fields required | object | Any of title, subtitle, body_markdown, tags, canonical_url, paywalled. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_update_story",
"arguments": {
"story_id": "3f9a1c27b84e",
"fields": {
"body_markdown": "Small releases beat big ones.\n\nMore on [yourname.dev](https://yourname.dev)."
}
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"status": "published",
"updated_fields": [
"tags"
]
},
"isError": false
} MCP tool medium_publish_story
Publishes a draft under your name, or in the publication it belongs to. Readers and followers can see it at once. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_publish_story",
"arguments": {
"story_id": "story_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"status": "published",
"url": "https://medium.com/@yourname/shipping-small-3f9a1c27b84e"
},
"isError": false
} MCP tool medium_schedule_story
Schedules a draft. Medium publishes it at the set time, and the story stays in your drafts until then. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
| publish_at required | datetime | ISO 8601 with time zone. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_schedule_story",
"arguments": {
"story_id": "3f9a1c27b84e",
"publish_at": "2026-10-15T09:00:00-04:00"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"status": "scheduled",
"publish_at": "2026-10-15T09:00:00-04:00"
},
"isError": false
} MCP tool medium_submit_to_publication
Submits a draft to a publication. Its editors review it and decide when to publish. A publication can accept only drafts, only published stories, or both. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| story_id required | string | Story ID from list_stories. |
| publication_id required | string | Publication ID from list_publications. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_submit_to_publication",
"arguments": {
"story_id": "story_8c41d2",
"publication_id": "publication_8c41d2"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"story_id": "3f9a1c27b84e",
"publication_id": "pub_7d21",
"status": "submitted"
},
"isError": false
} MCP tool medium_reply_to_response
Posts a reply under one response, under your name. By default you confirm each call; you can switch that off for this tool.
Parameters
| Name | Type | Description |
|---|---|---|
| response_id required | string | Response ID from list_responses. |
| body required | string | Reply text. |
tools/call
JSON-RPC
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "medium_reply_to_response",
"arguments": {
"response_id": "response_8c41d2",
"body": "body"
}
}
} Example response
{
"content": [
{
"type": "text",
"text": "{ ... same JSON as structuredContent ... }"
}
],
"structuredContent": {
"response_id": "r_41b9c2",
"reply_id": "r_41ba07",
"status": "published"
},
"isError": false
}