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
Medium Endpoints
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.

MCP 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

Parameters: list_stories
NameTypeDescription
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

read

MCP 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

Parameters: get_story
NameTypeDescription
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
}

MCP 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

Parameters: get_story_stats
NameTypeDescription
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
}

MCP 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

Parameters: get_account_stats
NameTypeDescription
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
}

MCP 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

Parameters: list_responses
NameTypeDescription
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
}

MCP 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

write

MCP 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

Parameters: create_draft
NameTypeDescription
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

write

MCP 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

Parameters: import_story
NameTypeDescription
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
}

Update story

write Confirm

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

Parameters: update_story
NameTypeDescription
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
}

Publish story

write Confirm

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

Parameters: publish_story
NameTypeDescription
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
}

Schedule story

write Confirm

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

Parameters: schedule_story
NameTypeDescription
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
}

Submit to publication

write Confirm

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

Parameters: submit_to_publication
NameTypeDescription
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
}

Reply to response

write Confirm

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

Parameters: reply_to_response
NameTypeDescription
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
}