Skip to main content
Glama
wkbaran

Medium Reader MCP

by wkbaran

Medium Reader MCP

Ask Claude what's new in your Medium feed, and have it read member-only stories for you.

Node 20+ TypeScript MCP Tools Jev License: MIT

Quick start · Tools · Daily digest · Headline ranking with Jev · Logging in · Troubleshooting

An MCP server for your own Medium account:

  • Read: your Following and For you feeds, full member-only posts, search, reading lists, follows and history.

  • Act, when you ask: follow and unfollow, mute, save to lists, clap.

  • Daily digest: with Hermes Agent, a scheduled morning digest. Jev can rank every headline against your interests before an LLM reads anything.

  • No API keys for Medium: you log in once in a browser window.

What it uses

What

Needed?

Your Medium account

Yes. A membership is needed to read member-only stories in full

Node.js 20+

Yes

Chrome or Edge

Only for the browser login (you can paste cookies instead)

A Jev-style decision model

Optional. Ranks digest headlines against your interests in about 2 s per 100. Any provider with the same decisions API works, set by URL, key and model like an OpenAI-compatible client. The default is TypeSafe's Jev on OpenRouter, about $0.03 per 1,000 headlines

An MCP client

Claude Code, Claude Desktop, Cursor, VS Code, Hermes Agent…

How it talks to Medium:

  • Medium's own web endpoint: Medium has no reading API, so the server calls the GraphQL endpoint medium.com uses, with your session. It sees only what you see logged in.

  • HTTP/1.1 through undici: Medium's Cloudflare blocks Node's HTTP/2 fetch, which Node 26 uses by default.

Related MCP server: cronometer-core

Quick start

git clone https://github.com/wkbaran/medium-reader-mcp.git
cd medium-reader-mcp
npm install && npm run build

node dist/cli.js login     # a browser window opens; sign in to Medium as usual
node dist/cli.js install   # registers the server with Claude Code

Restart Claude Code, then try:

  • "What's new in my Medium feed today?"

  • "Summarize that Towards AI post about schema drift."

  • "Which authors I follow post the most but I never read?"

  • "Propose an interests.md from my Medium activity."

  • "Save this post to my AI list." (Claude asks before every change)

Point the client at dist/cli.js with an absolute path, after running login:

{ "mcpServers": { "medium-reader": { "command": "node", "args": ["/absolute/path/to/medium-reader-mcp/dist/cli.js"] } } }
  • Claude Desktop: claude_desktop_config.json (Settings → Developer → Edit Config)

  • Cursor: ~/.cursor/mcp.json

  • VS Code: .vscode/mcp.json, using "servers" instead of "mcpServers" and adding "type": "stdio"

  • Claude Code, manually: claude mcp add --scope user medium-reader -- node /absolute/path/to/dist/cli.js

Tools

How to name things:

  • Authors: @username or a profile URL.

  • Publications: a name, slug or URL, including custom domains.

  • Posts: any Medium link, or the post's hex id.

Reading (all read-only)

Tool

What it returns

get_feed

Your Following feed (default) or For you, newest first. since takes "7d", "48h" or a date

read_post

A full post as Markdown. Member-only stories you can't access are flagged as previews

get_recent_posts · search_posts

One author's or publication's latest posts · keyword search across Medium

list_following · list_reading_lists · get_list

Who you follow · your lists · the posts in one list

get_reading_history

Posts you've read, most recent first (Medium gives no read dates)

rate_headings

Rates headlines against conditions you define, using your MCP client's own model (sampling)

interests_evidence

What your activity says about your taste, for drafting an interests.md

auth_status

Who you're logged in as, and whether you're a member

Account changes (clients ask first; the server re-checks with Medium afterwards)

Tool

What it does

follow / unfollow

Follow or unfollow an author or publication. An ambiguous name lists the matches instead of guessing

mute / unmute

Hide an author's or publication's posts, including an author's posts in publications you follow. Private

save_to_list / remove_from_list

Add a post to, or remove it from, a list

clap / undo_clap

Clap (up to Medium's 50 per post), or take your claps back

Follows and claps are visible to the author, and named lists are public.

Digest (only when MEDIUM_READER_DIGEST_DIR is set; plain-text output for agent harnesses)

Tool

What it does

digest_begin

Collects what's new, ranks and filters it, and returns a work list with refs (F3, T1, Y12)

digest_finish

Takes the picks by ref, renders the message and saves state. Safe to repeat

digest_status · mark_reported

Inspect the state · repair it

save_interests_proposal

Saves a drafted interests.md as interests.proposed.md, never over the real one

A worked example of a whole run, with each tool's arguments and output: docs/digest-tools.md.

Daily digest with Hermes Agent

Hermes Agent runs skills on a schedule and delivers to Discord and other chats. hermes/SKILL.md turns this server into a morning digest:

  • What it covers: new posts from Following, Medium's top picks, and your personal "For you" positions 25–100.

  • How it's chosen: Jev ranks and filters the headlines, then subagents read the best 20–25 in full.

  • What you get: one message, with ⭐ "Read in full" picks that each have a summary and a reason.

  • What the model does: only the judging. Fetching, state and layout are code, which took a Sonnet run from about $2.50 to $0.40.

Setup

  1. Build (npm ci && npm run build) and copy dist/, package.json and package-lock.json to where Hermes can see them, e.g. /opt/data/mcp/medium-reader-mcp. Then run npm ci --omit=dev --omit=optional there.

  2. Log in on a machine with a browser (node dist/cli.js login), then copy ~/.config/medium-reader/auth.json to the Hermes host, e.g. /opt/data/mcp/medium-reader-home/.

  3. Create the digest directory, e.g. /opt/data/sandbox/medium_digest, with an interests.md (start from hermes/interests.example.md, or draft one from your activity).

  4. Register the server in Hermes's config.yaml:

    mcp_servers:
      medium-reader:
        command: node
        args: ["/opt/data/mcp/medium-reader-mcp/dist/cli.js"]
        env:
          MEDIUM_READER_HOME: /opt/data/mcp/medium-reader-home
          MEDIUM_READER_DIGEST_DIR: /opt/data/sandbox/medium_digest
          MEDIUM_READER_DIGEST_TZ: America/Denver
          MEDIUM_READER_CLASSIFIER: jev                          # rank with Jev (default: sampling)
          MEDIUM_READER_JEV_API_KEY: ${JEV_OPENROUTER_API_KEY}   # from Hermes's .env
          # MEDIUM_READER_JEV_URL: https://openrouter.ai/api/alpha/decisions   # the default; any decisions-API endpoint
  5. Install the skill: copy hermes/SKILL.md to skills/productivity/medium-digest/ and hermes/medium_digest_start.sh to scripts/. Then edit the skill's Settings block.

  6. Schedule it (run as the hermes user). The job needs only the delegation and medium-reader toolsets:

    hermes cron create "0 7 * * *" "Run the medium-digest skill and deliver the digest." \
      --name medium-digest --skill medium-digest --script medium_digest_start.sh --deliver discord:<channel-id>

More detail is in docs/digest.md: why the server has harness-specific tools, customizing, state and repairs, and limits.

Headline ranking with Jev

The digest's first step is deciding which of a day's 100–200 headlines matter to you, before anything is read. That's the classifier (src/classifier/), kept separate from summarizing and presenting.

  • Jev is a "decision model" from TypeSafe. It returns typed answers with probabilities, not text. For every headline it gives:

    • a rank (how much you'd want it, judged against interests.md)

    • a skip probability (whether it matches your Skip list)

  • In the work list: each section is sorted best first with a rank column. Confident skips are dropped. Low ranks sink, so the agent starts from the top, and on a big day the bottom is what gets cut.

  • Measured on real labels:

    • Against a local 27B model: Jev's top 10 were all posts the reader wanted, against 7 of 10, and it took 3 s instead of 178 s for 160 headlines.

    • Details.

  • Backends (MEDIUM_READER_CLASSIFIER):

    • jev: ranks and skips. The server calls the decisions API itself over HTTPS, not through sampling.

    • sampling (default): skips only. The server asks your MCP client's own model to rate each headline, which is what MCP sampling means: the server borrows the client's LLM rather than having its own (in Hermes, auxiliary.mcp or mcp_servers.<name>.sampling.model). It doesn't rank, so the order of posts is left to the agent's model when it shortlists.

    • off.

  • Any Jev-style provider: the jev backend speaks the decisions API (POST model, state, questions → answers), and you point it at a provider the way you'd point an OpenAI-compatible client at a local model:

    • MEDIUM_READER_JEV_URL: the endpoint. Default: OpenRouter's https://openrouter.ai/api/alpha/decisions. TypeSafe's System One API (…/v1/systemone) and compatible or self-hosted servers work too.

    • MEDIUM_READER_JEV_API_KEY: the bearer token (falls back to OPENROUTER_API_KEY). It can be empty for a server without auth.

    • MEDIUM_READER_JEV_MODEL: the model id. Default typesafe/jev-1.13; TypeSafe's own API uses jev-1.13.

  • Tune it to you: label your own headlines with one keypress each, and the tools recommend thresholds and edits to interests.md. They can also draft an interests.md from your reading lists, follows and history.

Everything about it is in docs/classifier.md: settings, the tuning loop, drafting from activity, evidence, and adding a backend.

Logging in

  • Browser (default): login opens Chrome or Edge on Medium's sign-in page. The session is saved as soon as you're in and lasts about a year. Re-running login usually needs no typing.

  • Paste: login --paste (or --stdin) takes the sid and uid cookies in any format: a Cookie: header, a Cookie-Editor export, or cookies.txt.

  • No restart needed: the server re-reads the session on every call.

  • Tips:

    • If Medium emails you a sign-in link, paste it into the login window.

    • The window must be visible, because Cloudflare blocks headless browsers.

Command

What it does

node dist/cli.js login

Log in (--paste / --stdin to paste cookies)

node dist/cli.js status

The logged-in account, membership, and whether the session works

node dist/cli.js logout

Delete the session (--all also deletes the login browser profile)

node dist/cli.js install

Register with Claude Code (--scope user|project|local)

Variable

Purpose

MEDIUM_SID, MEDIUM_UID, MEDIUM_COOKIE

Session cookies, overriding the saved session (containers, CI)

MEDIUM_READER_HOME

Config directory (default ~/.config/medium-reader)

MEDIUM_BROWSER_PATH

A Chromium-based browser for login

MEDIUM_READER_DIGEST_DIR

Digest directory; setting it turns on the digest tools

MEDIUM_READER_DIGEST_TZ

Time zone for digest dates (default TZ, then UTC)

MEDIUM_READER_DIGEST_KEEP

Reported post ids to keep (default 3000)

MEDIUM_READER_DIGEST_STYLE

discord (default) or markdown

MEDIUM_READER_CLASSIFIER

jev, sampling (default) or off

MEDIUM_READER_JEV_URL

Decisions-API endpoint for jev (default OpenRouter's)

MEDIUM_READER_JEV_API_KEY

Bearer token for that endpoint (default OPENROUTER_API_KEY)

MEDIUM_READER_JEV_MODEL

Model id (default typesafe/jev-1.13)

MEDIUM_READER_DIGEST_SKIP_THRESHOLD

Skip probability at which a headline is dropped (default 0.7)

MEDIUM_READER_DIGEST_RANK_FLOOR

Rank below which posts are collapsed to one line (default off)

MEDIUM_READER_DIGEST_RANK_FLOOR_MODE

exclude: leave posts below the floor out entirely and only count them (default compact)

Privacy and security

  • Your session goes only to medium.com. Custom-domain posts are fetched from medium.com by id.

  • It's stored in ~/.config/medium-reader/auth.json, mode 600. Nothing is stored in the repo.

  • No telemetry. Requests go only to Medium, and to your Jev provider if it's on (headlines and your interests only).

  • Reading through this server doesn't add posts to your Medium reading history.

  • package-lock.json pins every dependency; install with npm ci.

How Medium's feeds behave

The digest's design rests on a few findings, written up in docs/feeds.md:

  • "For you" is a fixed list of about 1,000 posts. Paging to its end makes Medium rebuild your homepage list.

  • Positions 0–25 are popular posts for everyone; positions 25–250 are the most personal part of the list.

  • Muting an author is the only way to hide their posts in publications you still follow.

Troubleshooting

Symptom

Fix

"Not logged in" / "session was rejected"

node dist/cli.js login

"Only a preview was returned"

Not a member, or the session expired; status shows which

"Cloudflare protection blocked the request"

Usually temporary. If it persists, Medium changed its bot rules; please open an issue

The server doesn't appear in /mcp

Restart Claude Code

login can't find a browser

Install Chrome, set MEDIUM_BROWSER_PATH, or use --paste

The digest says Classifier … unavailable

For jev, check MEDIUM_READER_JEV_URL and the key; for sampling, the client's sampling setup

Development

npm ci && npm test     # vitest against a fake GraphQL endpoint; no network needed
npm run typecheck && npm run build
  • src/medium/: the GraphQL client and queries.

  • src/digest/: the digest tools.

  • src/classifier/: the headline classifier, shared with substack-reader-mcp.

  • tools/classifier/: label, score, analyze, propose.

  • experiments/jev/: the trials behind the classifier.

  • CLAUDE.md: how Medium's API actually behaves. Read it before changing src/medium/.

Disclaimer

An independent project, not affiliated with or endorsed by Medium or TypeSafe. It uses Medium's undocumented web endpoints, which can change without notice. Use it with your own account, within Medium's Terms of Service.

License

MIT © 2026 Bill Baran.

Available Tools

14 tools
auth_statusMedium auth statusA
Read-only

Check whether a Medium session is configured and still valid, which account it belongs to, and whether it has a Medium membership (needed for member-only posts).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds behavioral context by stating it checks whether the session is 'still valid' and which account it belongs to, implying session expiry and account association. It does not contradict annotations and adds detail about the membership check, which is useful beyond the read-only flag.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the verb 'Check' and packs all relevant checks into a compact list with a parenthetical clarification ('needed for member-only posts'). Every phrase adds value, with no redundant or filler words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter status tool, the description covers the essential decision factors: configuration, validity, account identity, and membership. It does not specify the return format, but the absence of an output schema and the simple status-check nature make this acceptable; the agent can infer the result from the described checks.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and schema description coverage is trivially 100%. With no parameters to document, the baseline is 4; the description appropriately focuses on the tool's outcome rather than inputs, and there is nothing further it needs to clarify about parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Check' and names the exact resource (Medium session/account) and the four things it verifies: configuration, validity, account identity, and membership. This clearly distinguishes it from sibling tools like read_post or follow, which perform actions rather than report status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by explaining that membership is needed for member-only posts, implicitly telling the agent when this check is useful. It does not explicitly name when-not scenarios or alternative tools, but no sibling tool competes with this status check, so the guidance is adequate though not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

clapClap for a postA

Clap for a post (visible to its author). Medium allows 50 claps per reader per post in total; this refuses to go past that. Only use when the user asks. undo_clap takes them back.

ParametersJSON Schema
NameRequiredDescriptionDefault
postYesPost URL (any Medium or custom-domain link) or the post's hex id.
countNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a mutating, non-idempotent operation. The description adds genuinely useful behavioral context beyond the annotations: the 50-clap per-reader limit and that the tool 'refuses to go past that.' This helps set expectations for side effects and edge cases without contradicting any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core action is front-loaded, the key behavioral constraint (50 claps) is stated succinctly, and the alternative tool is mentioned in one short phrase. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with no output schema, the description covers the essential action, a behavioral limitation, and the reverse operation. It doesn't discuss error cases or authentication, but annotations and the schema already provide the safety profile and parameter constraints. It is complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50% (only 'post' is described in the schema), so the description should compensate for the undocumented 'count' parameter. It mentions the 50-clap ceiling, which relates to count's maximum, but it doesn't explicitly state that 'count' is the number of claps to give. The description adds partial value but doesn't fully clarify parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Clap for a post') and the resource (a post), plus a notable consequence (visible to its author). It also explicitly distinguishes itself from the sibling undo_clap, making the tool's purpose and scope immediately unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit activation condition ('Only use when the user asks') and names the alternative for reversing the action ('undo_clap takes them back'). This is direct, practical guidance that tells an agent exactly when to invoke this tool versus the sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

followFollowA
Idempotent

Follow an author or publication. Does nothing if already following. Only use when the user explicitly asks. If the name is ambiguous the candidates are returned; ask the user which one they mean.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYesAn author ("@username" or profile URL) or publication (name, slug like "javarevisited", or URL like "https://pub.towardsai.net").

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true, so 'Does nothing if already following' reinforces but adds specific side-effect behavior. The description also discloses that ambiguous names return candidates, which is valuable because no output schema exists. It adds context beyond the structured hints without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, each earning its place: the core action, idempotence, usage restriction, and ambiguity handling. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, low-complexity tool, the description covers the key agent needs: what to do, when to do it, and how to handle ambiguity. It does not state the success response format, but the absence of an output schema makes this a minor gap rather than a blocking one.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides 100% description coverage for the target parameter, including formats for authors and publications. The tool description itself adds no additional parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Follow an author or publication.' This clearly distinguishes the tool from siblings like unfollow and save_to_list, and clarifies what 'follow' means.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance: 'Only use when the user explicitly asks' — a clear when-to-use condition. It also explains what to do in the ambiguous-name case. It does not name alternatives, but the restriction to explicit user intent effectively excludes auto-following.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_feedGet Medium feedA
Read-only

The user's home feed. "following" (default) is posts from the authors and publications they follow; "for_you" is Medium's recommendations. Pass nextCursor back as cursor for more.

ParametersJSON Schema
NameRequiredDescriptionDefault
feedNofollowing
limitNo
sinceNoOnly posts after this point: an ISO date ("2026-09-01") or relative ("7d", "48h").
cursorNonextCursor from a previous call.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The readOnlyHint and openWorldHint annotations already cover the safety and dynamic nature of the operation. The description adds value beyond those by explaining the two feed modes and the pagination contract ('Pass nextCursor back as cursor'), which are behavioral details an agent needs to use the tool correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler: the first defines the resource, the second explains the input variants and pagination. It is front-loaded with the main concept and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core purpose, feed variants, and pagination, but with no output schema it does not describe the shape of feed items or how to identify a post for subsequent operations. The resource and parameters are clear enough for invocation, but an agent may need more context about the response.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50% (since and cursor are documented). The description adds meaning to the 'feed' enum and restates cursor usage, which is helpful. However, it does not add anything for 'limit' or expand on the 'since' format, leaving the agent to rely solely on the schema for those.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states this returns the user's home feed and defines the two feed variants, which makes the resource specific. It does not explicitly contrast with siblings like get_recent_posts or search_posts, so it stops short of full differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that 'following' returns posts from followed authors/publications and 'for_you' returns recommendations, which implies how to choose between them. However, it gives no guidance on when to use get_feed versus sibling tools such as get_recent_posts or search_posts, so the tool-selection guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_listGet list postsA
Read-only

Posts saved in the reading list or one of the user's named lists, most recently added first.

ParametersJSON Schema
NameRequiredDescriptionDefault
listNo"reading-list" (default) or the name / id of one of the user's lists, as shown by list_reading_lists.reading-list
limitNo
cursorNonextCursor from a previous call.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description doesn't need to cover those. It does add the ordering (most recently added first), which is useful, but it omits details like pagination behavior via cursor or error handling when a list is not found. The added context is minimal but not contradictory.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that states the primary action and ordering. It's efficient with no redundancy and front-loads the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list retrieval tool with open-world semantics and no output schema, the description is minimally sufficient but lacks usage guidance and pagination details. The schema covers parameters well, so the main gap is absence of when-to-use context, which would round out completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67% (list and cursor have descriptions, limit does not). The description adds no parameter-specific information beyond what's already in the schema. Since coverage is above 50%, the baseline of 3 is appropriate; the description doesn't compensate for the undocumented limit parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves posts from a reading list or named lists, ordered by most recent first. This distinguishes it from siblings like get_feed, get_recent_posts, and search_posts by identifying the specific resource (lists) and the ordering behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to choose this tool over alternatives. It doesn't compare with get_feed or get_recent_posts, nor does it mention prerequisites like needing a list name from list_reading_lists. Usage context is entirely implied, not explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recent_postsGet recent postsA
Read-only

Latest posts from one author or publication. Pass nextCursor back as cursor to page back.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNonextCursor from a previous call.
sourceYesAn author ("@username" or profile URL) or publication (name, slug like "javarevisited", or URL like "https://pub.towardsai.net").

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, covering safety and world-scope. The description adds useful behavioral context beyond annotations: it establishes the 'latest posts' ordering and discloses pagination behavior via 'Pass nextCursor back as `cursor` to page back.' This meaningfully enriches the agent's understanding of call behavior without repeating annotation data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences carry all essential information: the first declares the tool's purpose, the second gives the pagination contract. There is zero filler or redundancy. The most important information is front-loaded, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter, read-only list tool with no output schema, the description covers the core invocation requirements: source scope and pagination. It doesn't describe the shape of returned posts, but the name and title 'Get recent posts' make that implicit. Given annotations cover the safety profile and schema covers parameter details, the description is sufficiently complete for correct calling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 67%: `source` and `cursor` already have detailed descriptions, while `limit` has none. The description adds only marginal value to parameter meaning—mostly restating cursor and pagination semantics. It does not clarify the `limit` parameter, which remains undocumented beyond its type/default/max/min, so a baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource: 'Latest posts from one author or publication.' This clearly identifies what the tool does and narrows scope to a single source, which helps distinguish it from broader tools like get_feed or search_posts. However, it doesn't explicitly name sibling tools or contrast its behavior, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'from one author or publication' provides clear context for when to use this tool – when you need posts from a known, specific source. It does not explicitly mention alternatives or exclusions, but the scope is unambiguous. The pagination instruction adds a clear usage note about handling result sets, so the intended use case is well implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_followingList who you followA
Read-only

Authors (default) or publications the logged-in user follows, with the total count.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNousers
limitNo
cursorNonextCursor from a previous call.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the description's job is lighter. It adds useful behavioral context by scoping results to the logged-in user and mentioning the total count in the response. It does not contradict the annotations, though it does not disclose pagination behavior beyond what the schema's cursor description already provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that front-loads the primary choice (authors vs publications), states the scope (logged-in user), and includes the notable response detail (total count). There is no filler or redundant wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list endpoint with no required parameters, the description plus annotations and schema-provided cursor/limit constraints are largely sufficient. The lack of an output schema is partly mitigated by mentioning the total count, though item-level response fields are not described.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description clarifies the key enum parameter by mapping 'users' to 'Authors' and noting the default. However, schema description coverage is only 33%, and the description does not add meaning for limit or further explain cursor beyond the schema's 'nextCursor from a previous call' note, so compensation is only partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('list') and a precise resource scope: authors or publications followed by the logged-in user. It also adds the total-count detail, making the tool's purpose unmistakable and distinguishing it from siblings like get_feed or list_reading_lists.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance or mention of alternatives such as get_feed or get_list. Usage is implied by the description's phrasing but not spelled out, so an agent must infer when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reading_listsList reading listsA
Read-only

The user's reading list (saved posts) and their named lists, with item counts.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safe read-only nature is covered. The description adds useful context by specifying both the default reading list and named lists, plus item counts, which helps set expectations for the output. It does not mention ordering, pagination, or whether empty lists are included, but for a simple read-only listing this is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, focused sentence that conveys the scope and key output detail without wasted words. It is front-loaded with the main object ('the user's reading list') and ends with the distinguishing count detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool with no output schema, the description adequately explains what the agent will receive: the saved-posts reading list and named lists with item counts. It could be more explicit about the exact return shape or whether the default list is included separately, but the essential information is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and schema coverage is 100%, so there is no parameter information burden on the description. The description appropriately avoids inventing parameter details and instead communicates what the result contains, which is the relevant semantic information here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the resource—the user's reading list and named lists—and specifies that item counts are included. It stops short of an explicit verb like 'returns' or 'lists', but the meaning is unambiguous. It also implicitly distinguishes itself from get_list by focusing on list overviews with counts rather than list contents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus alternatives such as get_list or get_feed. The description implies it is for viewing a summary of saved posts and named lists, but it provides no exclusions, prerequisites, or explicit routing to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_postRead a postA
Read-only

Read a Medium post as Markdown. Member-only posts are returned in full when the logged-in account is a Medium member. Works for posts on custom domains too. Long posts are paged: pass start from the previous response to continue.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesPost URL (any Medium or custom-domain link) or the post's hex id.
startNoCharacter offset into the body, for paging.
formatNomarkdown
max_charsNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only/open-world behavior; the description adds meaningful behavioral context: member-only posts are fully returned only for members, custom domains work, and long posts are paged with start. It does not cover non-member behavior or max_chars effects, but the provided disclosures go beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise, front-loaded sentences: the core purpose comes first, then membership and domain caveats, then the paging mechanism. Every sentence contributes without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Without an output schema, the description does explain the return form (Markdown) and paging contract, which is helpful. But it omits the behavior of max_chars and the text format option, leaving important gaps for a four-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%, and the description adds meaning for start by explaining pagination and notes Markdown as the output format. However, max_chars is left completely unexplained and the format='text' option is not mentioned, so the description does not fully compensate for the schema gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read a Medium post') and output format ('as Markdown'), which distinguishes it from feed/list tools like get_feed or get_recent_posts. The additional scope notes about custom domains and member-only posts sharpen the purpose further.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by URL and adds useful context about custom domains and membership, but it never names alternatives or says when not to use this tool versus siblings like search_posts or get_recent_posts. No explicit when/when-not routing is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_from_listRemove from listA
DestructiveIdempotent

Remove a post from the reading list (default) or one of the user's named lists. Only use when the user asks.

ParametersJSON Schema
NameRequiredDescriptionDefault
listNo"reading-list" (default) or the name / id of one of the user's lists, as shown by list_reading_lists.reading-list
postYesPost URL (any Medium or custom-domain link) or the post's hex id.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the description doesn't need to restate those. It adds context about the default list and named lists, plus the user-intent condition. However, it doesn't describe side effects like behavior on missing posts or idempotency details, which are partially covered by annotations. With annotations present, this is moderate value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero fluff. The core action is front-loaded ('Remove a post...'), and the usage condition is a separate concise sentence. Every word contributes to understanding when and how to use the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple mutation tool with only two parameters and no output schema, the description covers the essential action, default scope, and user-intent condition. Annotations handle the destructive and idempotent profile, and the schema references list_reading_lists for list names. It doesn't explain edge cases, but nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% – both parameters have detailed descriptions (post URL/hex id, list default and reference to list_reading_lists). The tool description adds no additional meaning to the parameters beyond what the schema already provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear, specific action: 'Remove a post from the reading list (default) or one of the user's named lists.' It distinguishes from sibling tools like save_to_list (opposite) and list_reading_lists (list names) by focusing on removal and specifying the default list. No ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Only use when the user asks,' which sets a clear usage boundary. It does not explicitly name alternatives or when-not to use, but the schema references list_reading_lists for list names, and the purpose itself implies when it's appropriate. This is clear context but lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_to_listSave to listA
Idempotent

Save a post to the reading list (default) or one of the user's named lists. Does nothing if it's already there. Only use when the user asks.

ParametersJSON Schema
NameRequiredDescriptionDefault
listNo"reading-list" (default) or the name / id of one of the user's lists, as shown by list_reading_lists.reading-list
postYesPost URL (any Medium or custom-domain link) or the post's hex id.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate the tool is mutating and idempotent. The description adds concrete behavioral detail with 'Does nothing if it's already there' and the default-list behavior, which helps the agent predict outcomes without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three short sentences with no filler. The key action, default behavior, idempotency, and usage guardrail are all front-loaded and each sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with annotations and full schema coverage, the description is adequately complete. It covers the action, default, duplicate behavior, and the condition to invoke it; no critical operational details are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters. The description mainly restates the default list behavior and does not add material parameter-level detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Save') and a clearly defined resource (a post to a list). It also distinguishes itself from sibling tools like remove_from_list and list_reading_lists by explicitly stating the default reading list and named-list behavior.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool ('Only use when the user asks') and explains the default and named-list targets. It does not explicitly name alternatives or when-not-to-use conditions, but the purpose is distinct enough among siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_postsSearch MediumA
Read-only

Search all of Medium for posts by keyword. Pass nextCursor back as page for more results.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNo
limitNo
queryYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only and open-world behavior. The description adds a non-obvious pagination contract: nextCursor must be passed back as page for subsequent results. This is useful behavioral context not present in the annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose and followed by actionable pagination guidance. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Invocation-critical details are covered: read-only scope, keyword search, and pagination. Since there is no output schema, the description could say a bit more about what the response contains beyond nextCursor, but for a search tool this is largely sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It adds meaning for query (keyword) and page (pagination via nextCursor), but limit is never mentioned. The parameter names and defaults are somewhat self-explanatory, but coverage is only partial.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Search all of Medium for posts by keyword.' This clearly distinguishes it from sibling tools like get_feed and get_recent_posts, which are scoped or personalized rather than a global keyword search.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context for when to use the tool: when the user wants a global Medium keyword search. It does not explicitly name alternatives or exclusions, but the 'all of Medium' scope makes the intended use distinct from feed/list/reading-list tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

undo_clapUndo clapsB
DestructiveIdempotent

Remove all of the user's claps from a post. Only use when the user asks.

ParametersJSON Schema
NameRequiredDescriptionDefault
postYesPost URL (any Medium or custom-domain link) or the post's hex id.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already indicate destructiveHint and readOnlyHint=false, so the description's 'Remove all' is consistent with those. It adds context that it affects the user's claps, which is useful, but it doesn't mention any side effects like irreversibility or permission requirements beyond what annotations imply. It adds some value but does not go beyond the annotation's baseline significantly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, one sentence long, and front-loads the action. Every word is meaningful. It loses a point because it lacks any structural organization, but for its brevity it is well-formed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one parameter, no output schema, and annotations cover safety (destructive hint). The description tells the agent when to use it. It is adequate but could mention that it only removes claps made by the current user and any potential need for authentication, though that is likely implied by 'the user's claps'.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers the parameter 'post' with a clear description (URL or hex id), so the description adds no additional parameter semantics. With 100% schema coverage, the baseline is 3, and the description does not enhance it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (remove claps) and the resource (a post), and specifies it applies to 'the user's claps'. It is distinct from its sibling 'clap', which adds claps, and from other read/list tools. However, it does not explicitly name the sibling it contrasts with, so it misses the top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It says 'Only use when the user asks', which gives a clear trigger condition. However, it does not specify when NOT to use it or mention any alternatives, such as 'clap' for adding claps. The instruction is useful but lacks exclusionary guidance, making it adequate but not comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unfollowUnfollowA
DestructiveIdempotent

Unfollow an author or publication. Only use when the user explicitly asks. If the name is ambiguous the candidates are returned; ask the user which one they mean.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetYesAn author ("@username" or profile URL) or publication (name, slug like "javarevisited", or URL like "https://pub.towardsai.net").

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, covering the mutation and destructive nature. The description adds valuable context: the ambiguity handling (candidates returned) and the explicit user request requirement. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences with zero redundancy. The core action is front-loaded, followed by critical usage and ambiguity guidance. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter tool with no output schema and annotations covering the safety profile, the description is complete. It covers what, when, and how to handle ambiguity, leaving no critical gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameter is fully documented. The description adds behavioral meaning beyond the schema by explaining that ambiguous names return candidates for user disambiguation, which enriches the parameter's semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Unfollow an author or publication') and clearly distinguishes the action from siblings like 'follow' and 'list_following'. The scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('Only use when the user explicitly asks') and handles ambiguity by instructing to ask the user. It does not explicitly list alternatives or exclusion criteria, but the condition is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 14 tool updatesv0.1.0
    • First observedauth_status
    • First observedclap
    • First observedfollow
    • First observedget_feed
    • First observedget_list
    • First observedget_recent_posts
    • First observedlist_following
    • First observedlist_reading_lists
    • First observedread_post
    • First observedremove_from_list
    • First observedsave_to_list
    • First observedsearch_posts
    • First observedundo_clap
    • First observedunfollow

TDQS

A3.9/5.0

Scored across 14 tools

Disambiguation4/5

Most tools target distinct actions and resources, but get_list and list_reading_lists overlap somewhat since both involve reading lists, and get_feed vs get_recent_posts could be confused by name alone. Descriptions generally resolve the boundaries.

Naming Consistency4/5

Most names follow a clear verb_noun pattern like get_feed, search_posts, save_to_list, and remove_from_list. Minor deviations exist with auth_status lacking a verb and read_post/clap/undo_clap using different verb styles, but the pattern is still predictable.

Tool Count5/5

14 tools is well-scoped for a Medium reader/engagement server, covering reading, searching, following, list management, and clapping without unnecessary redundancy. Each tool earns its place.

Completeness4/5

The surface covers core reading workflows: feeds, posts, search, author/publication posts, following, reading lists, and clapping. Minor gaps exist such as no named-list creation/deletion and no direct user/publication profile lookup, but these are not critical for the stated reader-oriented purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients like Codex and Claude Code to securely read and manage a personal Cronometer account, including food logs, nutrient summaries with missing-data awareness, food search, biometrics, and export analysis.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables MCP clients like Claude to securely read your own Cronometer nutrition and biometric data using your account credentials, with read-only access and optional human-readable output.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables MCP-compatible clients to read LinkedIn profiles, companies, and jobs, and to send connection requests after explicit confirmation, using interactive browser-based authentication instead of stored credentials.
    8
    MIT