Skip to main content
Glama
Mohammed-Jameal-J

NewsBlog Composer MCP

NewsBlog Composer MCP

A research and audit tool for people who write. It finds corroborated stories, pulls out facts with their sources attached, mines keywords from that reporting, hands the writer a brief, reviews the draft they wrote, and builds the schema, banner prompt and publishing pack around it.

It does not write the prose, on purpose. A model writing the sentences is exactly what an AI detector catches, and no amount of cliché-removal changes that: detectors measure how predictable the wording is, not how many stock phrases it contains. More to the point, the byline claims a person wrote it.

So the split is: the server does search, verification, extraction, keywords, structure, schema and auditing. The person writes the sentences. draft_brief gives them everything to start with; review_draft tells them where the draft is weak without rewriting a word.

It runs with zero API keys. Every credential is an upgrade, not a requirement. See No keys? Start here.


Install

Windows:

git clone https://github.com/Mohammed-Jameal-J/newsblog-composer-mcp.git
cd newsblog-composer-mcp
py -m venv .venv
.venv\Scripts\activate
pip install -e .
copy .env.example .env      # optional: every value in it is optional too

macOS / Linux:

git clone https://github.com/Mohammed-Jameal-J/newsblog-composer-mcp.git
cd newsblog-composer-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env        # optional: every value in it is optional too

Check what it can do on your machine:

python -m newsblog_mcp.diagnose "your test headline here"

That prints which providers are configured, which will be tried, and the result of a live verify_news call. Run it before wiring the server into a client — if search is blocked by a corporate proxy or VPN, this is where you find out.

Offline test suite (no network needed):

python tests\smoke_test.py

Related MCP server: Publisher Content MCP Server

Connect it

Claude Desktop%APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "newsblog": {
      "command": "C:\\path\\to\\newsblog-composer-mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "newsblog_mcp.server"]
    }
  }
}

On macOS the file is ~/Library/Application Support/Claude/claude_desktop_config.json and the command is /path/to/newsblog-composer-mcp/.venv/bin/python.

Claude Code.mcp.json in your project:

{
  "mcpServers": {
    "newsblog": {
      "command": ".venv/Scripts/python.exe",
      "args": ["-m", "newsblog_mcp.server"]
    }
  }
}

Any other MCP client: launch python -m newsblog_mcp.server over stdio.


Publishing and connecting

Claude Desktop / Claude Code run it over stdio, which is what the install section above sets up.

ChatGPT cannot spawn a local process, so stdio will never reach it. Run the same server over HTTP and deploy it behind HTTPS:

newsblog-composer-mcp --http --host 0.0.0.0 --port 8000

Then in ChatGPT: Settings → Connectors → Advanced → Developer mode, then Add custom connector pointing at https://your-host/mcp. Custom connectors need a Pro, Team, Enterprise or Edu plan.

Publishing to the MCP Registry needs the package on PyPI first, then the mcp-publisher CLI with server.json in this repo. The name field must match your GitHub username: io.github.<username>/newsblog-composer.

How to test it

Three levels, cheapest first.

1. Offline, no network — proves the logic.

python tests\smoke_test.py

85 checks covering schema parity, the SEO audit, AI-word detection, publisher identity behind aggregator links, clustering, and the publishing pack. All should pass in about two seconds.

2. Network — proves search reaches you.

python -m newsblog_mcp.diagnose "a headline you saw in the news today"

One line per provider with timings, then the verdict. What you want to see is independent_publishers naming several real outlets and reference_candidates holding real publisher URLs.

3. A whole post, end to end.

python examples\build_today_example.py

Builds a complete package from a real story using facts already in the file, and prints the keywords, schema validation, AI-word check, human score and SEO score before writing the output folder. Use it as the reference for what a good run looks like. examples\build_mistral_example.py does the same for the hand-written reference post.

4. In Claude Desktop, after restarting it:

Use find_stories to get today's AI stories, pick the best corroborated one, and build the full blog package. Run find_ai_words until it comes back clean, then give me the publishing pack and the paste file.

The tools

Tool

What it does

Needs a key?

capabilities

Reports which providers are live and which fallbacks are in use

no

find_stories

Turns a topic into today's actual stories, grouped and ranked by corroboration and freshness

no

verify_news

Searches news providers, keeps matching results, counts independent publishers

no (keyless RSS)

fetch_article_facts

Downloads sources, extracts facts, short attributed quotes and figures

never

draft_brief

Hands the writer the structure, sourced facts, keywords and FAQ candidates

never

review_draft

Reads the writer's draft and says where it is weak. Rewrites nothing

never

humanize_text

Optional rewrite pass. Prefer review_draft

optional

find_ai_words

Finds every stock AI phrase with the sentence it sits in

never

score_ai_text

0–100 human-readability score

optional

generate_image

Concept banner, trademark filter applied first

no (watermarked)

seo_keywords

Mines keywords from the fetched sources; long-tail and FAQ queries from Google autocomplete

no

seo_audit

Scores the finished body against on-page rules, returns fixes

never

build_publishing_pack

Title, labels, permalink, alt text and a paste-ready Gemini image prompt

never

build_schema

Renders HTML body + both JSON-LD blocks, then validates them

never

save_and_present

Writes the package to output/, with canonical/OG/Twitter tags

never

Resources: newsblog://house-style (structure and sourcing rules for the drafting step) and newsblog://humanizer-rules (the rewrite rule set).

The flow

There are two entry points, depending on what you type.

A topic — "today's AI news", "electric vehicles", "Indian fintech". There is no claim to verify yet, so start by finding out what happened:

find_stories("AI", days=1)
  ↓  stories grouped by event, ranked by publisher count then freshness
     pick one from ready_to_write, check its age_hours
verify_news(story.headline)
  ↓  … and continue as below

A specific headline — start at verify_news directly. Note that an old headline correctly returns old sources; days limits how far back to look.

verify_news(title)
  ↓  stop here if is_legit is false
fetch_article_facts(result.fetchable_urls)   # or story.fetchable_urls
  ↓
seo_keywords(title, [fact.text for fact in facts])
  ↓  primary + secondary keywords, slug, meta title/description,
     and FAQ questions taken from real autocomplete data
draft_brief(headline, facts, keywords)
  ↓  the writer writes the draft themselves
review_draft(draft, facts)      → must_fix / worth_fixing / consider
  ↓  the writer revises; repeat until must_fix is empty
find_ai_words(draft)            → until `clean` is true
  ↓
build_publishing_pack(...)      → title, labels, permalink, Gemini image prompt
  paste the prompt into Gemini, upload the image, take the public URL
  ↓
build_schema(article, faq, image, references, keywords)
  ↓  fix anything in validation.issues, then call again
seo_audit(html_body, primary_keyword, ...)
  ↓  fix everything in must_fix, then call again
save_and_present(..., meta=schema.meta, pack=pack)

Output lands in a timestamped folder under output/:

File

What it is

publish-pack.md

Title, labels, custom permalink, search description, alt text, Gemini image prompt

paste-into-blogger.html

Both JSON-LD blocks then the styled body — the file you paste

report.md

Verification verdict, human score, AI-word status, SEO score, references

index.html

Standalone preview with meta, canonical, OG and Twitter tags

body.html, *.jsonld, meta.json

The pieces, separately

Three guardrails are enforced in code, not left to the model:

  • verify_news returns is_legit: false unless at least two independent publishers match the headline, or one primary/official source does.

  • build_schema returns validation.issues listing every mismatch: an FAQ question that differs between the HTML and the FAQPage schema, an image URL that differs between the <img> tag and NewsArticle.image, a reference that is not a real fetched URL. A non-empty list means don't publish.

  • seo_audit returns must_fix for the things that actually cost rankings — a duplicate H1, a missing keyword in the opening, images with no alt text, a meta description of the wrong length, fewer than two external source links.

Everything fetch_article_facts returns carries a source_url, so any claim in the finished post can be traced back to the page it came from.


No keys? Start here

With an empty .env the pipeline still runs end to end. Here is what you get, and what each key would change.

Step

With no key

With a key

Search

GDELT DOC 2.0 — official, free, no signup, news-specific — then Bing/Google News RSS as backup

Tavily / Brave / Serper / Google CSE: cleaner snippets, higher limits

Article extraction

Full quality. trafilatura runs locally.

— no key exists

Keywords

Full quality. Mined from your fetched sources, plus keyless Google autocomplete.

— a paid keyword API would add search-volume data

Humanise

Returns the rule set and asks the calling model to rewrite. Works well in Claude; varies elsewhere.

Rewrite happens server-side, identical everywhere

Human score

Local heuristic, labelled is_real_detector: false

A real detector's score

Image

Pollinations anonymous: ~1 request/15s, and may watermark

Cloudflare/OpenAI/Stability: clean, fast

Schema, audit, files

Full quality.

— no key exists

Search: what changed in 2026

Brave is no longer the free recommendation. In February 2026 Brave removed its free tier and moved every plan to credit-based billing — a card is required, a $5 monthly credit covers roughly 1,000 requests, and you are billed past that.

Free options that still hold up, best first:

  • GDELT — no key, no signup, no limit to speak of. Already the default. It is a global news index, so it is genuinely good at "is anyone reporting this", which is exactly what verify_news asks. Start here and only add a key if snippet quality or freshness becomes a problem.

  • Tavily — 1,000 credits/month, renews monthly, no card. The best keyed option for this pipeline. Set TAVILY_API_KEY.

  • Google Custom Search — 100 queries/day, no card. Needs both GOOGLE_CSE_KEY and GOOGLE_CSE_ID from programmablesearchengine.google.com.

  • Serper — 2,500 credits, no card, but one-time only. Fine for evaluating, not for an ongoing blog.

  • NewsAPI — free tier is non-commercial only and delays recent articles, which is the wrong trade for breaking news.

Free tiers move around; check each provider's own pricing page before committing.

Images: what you actually need

generate_image runs with no key, but read this before publishing anything.

Pollinations still allows anonymous requests — about one every 15 seconds, basic models — but the free anonymous tier may watermark the image, which makes it unusable as a published banner. Three ways out, cheapest first:

  1. Free Pollinations token — register at auth.pollinations.ai, no card. This removes the watermark and raises the rate limit. Set POLLINATIONS_TOKEN. Smallest change, keeps the existing provider.

  2. Cloudflare Workers AI (recommended) — FLUX schnell, a free daily allowance, no watermark, and it is a real production API. Set IMAGE_PROVIDER=cloudflare, CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN. Note the model returns 1024x1024, so crop to your banner ratio.

  3. OpenAI Images or Stability — paid per image, best quality.

Whichever you use, the file lands locally. Upload it and pass the public https URL into build_schema, or NewsArticle.image points at a path no crawler can reach.

If you only add one key

Add Cloudflare (or the free Pollinations token) for images. Search already works properly with no key; images are the step where the keyless output is not publishable.

Honest limitations

  • The human score is not proof of anything. Public AI detectors have real false-positive and false-negative rates, especially on short text and on non-native English phrasing. The keyless fallback is not a detector at all — it measures the structural tells the rewrite rules target. Present it as a directional signal and say so wherever a reader sees the number.

  • The trademark filter is a safety net, not a legal opinion. It rewrites known brand terms into generic descriptors and strips logo requests before the prompt leaves your machine. Extend TRADEMARKS in src/newsblog_mcp/providers/imagegen.py as you hit new names, and still look at what comes back.

  • Freshness is yours to set. find_stories(days=1) is same-day; days=2 is the default. verify_news searches a 14-day window unless you pass days. Feeding it a three-week-old headline returns three-week-old sources, correctly.

  • GDELT is an index, not an editor. It indexes a very wide range of publishers, including low-quality ones, so two GDELT "publishers" agreeing is weaker evidence than two known outlets agreeing. Look at the domains in sources before trusting a medium confidence. The RSS backups are unofficial endpoints that can change shape without warning; diagnose tells you when one has stopped working.

  • The SEO tools cover on-page only. Keyword relevance, structure, meta lengths, alt text, internal consistency. They say nothing about search volume, competition, or backlinks — that needs a paid keyword API, and no free tier gives real volume data.

  • Generated images are local files. Upload the file and pass a public https URL into build_schema, or NewsArticle.image will point at a path no crawler can reach.

  • Corroboration is counted, not judged. The server counts independent publishers and flags date conflicts. Whether those publishers are all repeating one wire story is a judgement the calling model still has to make.

Layout

src/newsblog_mcp/
  server.py         MCP entrypoint: 10 tools, 2 resources
  diagnose.py       standalone connectivity check
  config.py         env loading, capability report
  textutil.py       tokenising, domains, sentence splitting, slugs
  providers/
    search.py       Tavily, Brave, Serper, Google CSE, NewsAPI, GDELT, RSS
    suggest.py      keyless Google autocomplete, for long-tail and FAQ queries
    llm.py          Anthropic / OpenAI, used only by humanize_text
    detector.py     GPTZero / Sapling
    imagegen.py     OpenAI / Stability / Cloudflare / Pollinations + trademark filter
  tools/            one module per MCP tool
  templates/        article.html.j2
  resources/        house_style.md, humanizer_patterns.md
tests/smoke_test.py offline test suite
output/             generated packages land here

Available Tools

18 tools
build_publishing_packA

Final step. Everything needed to publish, in one block.

Returns the title, the Blogger labels line, the custom permalink slug, the search description, the image alt text, and gemini_image_prompt - a paste-ready prompt for Gemini with brand names already stripped, so the banner cannot reproduce a real trademark.

image_concepts: describe what the banner should show in plain words (the objects and ideas, not the company names). Leave it empty and the headline is used. image_style is editorial, photographic or abstract.

Pass the result to save_and_present as pack and it is written to publish-pack.md alongside the post.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugNo
entitiesNo
headlineYes
keywordsNo
descriptionNo
image_styleNoeditorial
canonical_urlNo
image_conceptsNo

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose meaningful behavior: the returned field set, and a non-obvious side effect of the prompt generation (brand names stripped 'so the banner cannot reproduce a real trademark'). It also clarifies that this tool only builds and that the file write occurs later via save_and_present. It does not state error behavior or what happens with missing/empty optional inputs.

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 core purpose and final-step positioning are front-loaded, and the output list plus the two parameter notes follow in short paragraphs. Slightly verbose with backstory ('so the banner cannot reproduce a real trademark'), but nothing is redundant.

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?

There is no output schema, so describing the returned fields is valuable and largely covers the return contract. However, for a tool with 8 parameters at 0% schema coverage, over half the inputs remain unexplained, which leaves the agent guessing what to pass for slug, entities, keywords, description, and canonical_url.

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 0% across 8 parameters, so the description is the only source of meaning. It explains image_concepts (plain-word content, empty falls back to headline) and image_style (editorial/photographic/abstract), covering 2 of 8. slug, entities, keywords, description, and canonical_url are left entirely undocumented.

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 concrete verb+resource ('build ... publishing pack' / 'Final step. Everything needed to publish, in one block') and enumerates the exact artifacts it assembles: title, labels line, permalink slug, search description, alt text, and a Gemini image prompt. It distinguishes itself from siblings by naming save_and_present as the consumer, though it does not contrast against other SEO/image siblings.

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?

Usage is clearly positioned as the 'Final step' and the downstream action is explicit: 'Pass the result to save_and_present as `pack`'. It also states the fallback for image_concepts ('Leave it empty and the headline is used') and the acceptable image_style values. It gives no explicit when-not or prerequisites (e.g. whether a draft must exist first).

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

build_schemaA

Step 9. Render the HTML body and both JSON-LD blocks, then check them.

article: {headline, description (110-160 chars, used as the meta description), intro:[str,str] (exactly two), sections:[{heading, paragraphs:[str], bullets?:[str]}] (4-6), cta (one closing sentence that must contain CTA_LINK_TEXT verbatim so it renders as a link), date_published?, author?, slug?, url?, meta_title?, section?, language?, include_h1?} faq: [{question, answer}] - 4 to 8 entries image: {url, alt, title?, caption?} - url must be the public https URL references: [{title, url, publisher?}] - real fetched URLs only keywords: the primary and secondary keywords from seo_keywords; they go into NewsArticle.keywords and come back in meta for save_and_present

Pure templating, no model call. Renders the house body format: 720px container, inline styles, banner, byline, hr-separated H2 sections, FAQ as H3/P pairs, references as an ordered list. By default the body carries NO H1 because Blogger renders the post title itself - set BODY_INCLUDES_H1=true if your platform does not.

Returns paste_block, which is both JSON-LD scripts followed by the body, ready to paste into the post editor, and meta - pass that straight to save_and_present so the head, the schema and the body cannot drift apart. Returns validation.issues listing every mismatch found: FAQ questions that differ between the HTML and the FAQPage schema, an image URL that differs between the tag and NewsArticle.image, references missing from the body. Fix the issues and call again rather than publishing output with a non-empty issues list.

ParametersJSON Schema
NameRequiredDescriptionDefault
faqYes
imageYes
articleYes
keywordsNo
referencesYes

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full behavioral burden and does so well: it discloses that it is pure templating with no model call, that the body carries no H1 by default unless BODY_INCLUDES_H1=true, the exact output shape (`paste_block`, `meta`), and the concrete conditions that populate `validation.issues`. It also explains the coupling guarantee (head, schema, and body cannot drift apart).

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 procedural directive is front-loaded and the dense bullet-style field spec is justified given five complex parameters at 0% schema coverage. It is long, but nearly every line conveys a constraint an agent needs, with minimal redundancy.

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?

There is no output schema, so the description must describe returns, and it does: `paste_block` (JSON-LD scripts plus body), `meta` for save_and_present, and `validation.issues` with named mismatch types. Given the nested-object complexity and required-parameter count, the definition is complete enough to call correctly.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate and it does: it documents each field of `article` (headline, a 110-160 char description, exactly-two intro, 4-6 sections, a cta that must contain CTA_LINK_TEXT verbatim, plus optional fields), `faq` (4-8 entries), `image` (url/alt/title/caption with a public-https URL requirement), `references` (real fetched URLs only), and `keywords`. This adds far more meaning than the bare nested schemas provide.

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 action (render the HTML body and both JSON-LD blocks, then validate them) on a specific artifact. It explicitly positions itself in the pipeline as 'Step 9' and distinguishes its output from the sibling save_and_present, which consumes its `meta`. An agent can tell what this produces without opening the schema.

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?

Clearly establishes when this runs (step 9, after drafting) and what to do with the results: pass `meta` to save_and_present, and re-call after fixing a non-empty `validation.issues` list. It does not name an explicit alternative tool for a different platform, so it stops short of full when/when-not guidance.

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

capabilitiesA

Report which providers are configured and which keyless fallbacks are in use.

Call this first when something behaves unexpectedly - it shows whether verify_news has a real search key, whether humanize_text can rewrite server-side, and whether score_ai_text is using a real detector or the local heuristic.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

With no annotations and no output schema, the description carries the full behavioral burden. It discloses the content of the report (provider config plus fallback status) and implies a non-mutating diagnostic, but never states that it has no side effects, whether it requires credentials, or how the result is structured beyond three examples.

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?

Front-loaded with the core action in the first sentence and the usage trigger immediately after; every clause carries information. The hard line breaks inside sentences are slightly awkward but waste no 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, output-schema-less diagnostic, the description gives enough to call it confidently and interpret the headline results. It stops short of describing the full shape of the response, which an agent would otherwise have to discover by calling it.

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 takes zero parameters, so there is no parameter semantics to document; the baseline for an empty schema is 4. The description correctly implies the call is unconditional with no required input.

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: reports which providers are configured and which keyless fallbacks are active. It further anchors the purpose by naming three concrete sibling tools whose behavior it explains, so an agent can distinguish it from every other diagnostic in the list.

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?

Gives an explicit trigger condition ('Call this first when something behaves unexpectedly') and enumerates the specific uncertainties it resolves: verify_news's search key, humanize_text server-side rewriting, and score_ai_text's detector mode. This is exactly the when-to-use guidance an agent needs.

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

draft_briefA

Step 5. Hand the writer everything they need, then get out of the way.

Takes the verified facts and the keywords and returns a brief: the structure to follow, the facts grouped by source with the numbers and quotes separated out, the keywords and where to place them, FAQ candidates, and a list of the things only this writer can add.

It does not write prose, and it should not be asked to. The person writes the sentences; that is the part a byline claims, and it is the part a detector catches when a model does it instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
factsNo
headlineYes
keywordsNo
referencesNo
faq_candidatesNo

TDQS

A3.5/5.0
Behavior4/5

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

With no annotations present, the description carries the full burden and does disclose meaningful behavior: what the brief contains and, importantly, that the tool deliberately does not produce prose. It does not state whether the call is read-only, whether it mutates or persists state, or any auth/rate constraints, so the safety profile remains unstated.

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

Conciseness3/5

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

The opening ("Hand the writer everything they need, then get out of the way") is stylistic rather than informative and delays the concrete statement of purpose. The middle sentence is dense and informative, but the closing prose-justification sentence reads as argument for the tool's design rather than an operational instruction.

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?

There is no output schema, so the description usefully explains what the brief returned contains, which is the strongest part of the definition. Given 5 parameters at 0% schema coverage, no annotations, and a required input left unmentioned, the definition is still not complete enough for an agent to invoke it confidently with correct arguments.

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

Parameters2/5

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

Schema description coverage is 0% across 5 parameters, so the description must compensate and largely does not. It maps only loosely to two inputs ("verified facts and the keywords"); the required "headline" parameter, plus "references" and "faq_candidates," are never mentioned, leaving the mandatory input undocumented.

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 clear verb and artifact: it takes verified facts and keywords and returns a brief, enumerating the brief's contents (structure, facts grouped by source, keyword placement, FAQ candidates, writer-only additions). This distinguishes it from writing/prose tools in the sibling set. It stops short of naming a specific sibling like review_draft or humanize_text to route against, so it is clear but not sharply differentiated.

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?

"Step 5" places the tool in a clear workflow sequence, implicitly after fact verification and before drafting, and the exclusion "It does not write prose, and it should not be asked to" states a when-not condition. No alternative tool is named, so the routing guidance is contextual rather than explicit.

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

fetch_article_factsA

Step 3. Download the verified sources and extract usable material.

Returns facts, short attributed quotes (<=15 words) and figures, each tagged with the source_url it came from. URLs that fail to fetch or extract are reported in per_url with the reason - they are never filled in with guesses.

Everything you write in the article must trace back to an entry returned here. If a claim is not in this output, it does not go in the post.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlsYes
max_facts_per_urlNo

TDQS

A3.9/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full behavioral burden and does well on failure semantics: failed fetches are reported per_url with a reason and never fabricated. It also bounds quote length (<=15 words). Missing: net/HTTP behavior, rate limits, or whether it makes network calls that could be slow/blocked.

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?

Front-loaded with the step and core action, then return shape, then failure handling, then the usage contract. Four short paragraphs, each earning its place. No redundant restatement of the name.

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?

No output schema exists, so the description must describe returns and it does: facts, quotes, figures, tagged by source_url, plus a per_url failure report. For a two-parameter tool with no annotations, this covers the critical contract. The untouched max_facts_per_url is the main gap.

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 0% for two parameters (urls, max_facts_per_url), so the description should compensate. It obliquely defines what comes back per URL and the per_url failure structure, which hints at the urls list semantics, but says nothing about max_facts_per_url or batching. Partial compensation only.

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?

States a specific verb and resource pair: download verified sources and extract usable material, then names the exact output (facts, quotes, figures). The 'Step 3' marker situates it in a pipeline, but the name alone could be read as purely a fetch operation; the description clarifies the extraction role. It does not differentiate from siblings like verify_news, which produces the 'verified sources' this tool presumably consumes.

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?

Gives explicit downstream constraint: everything written must trace back to this output, and out-of-output claims are excluded. This tells the agent when the output is authoritative. However, it never names or excludes sibling tools (verify_news, draft_brief) or states prerequisites for input URLs, so alternative selection remains implicit.

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

find_ai_wordsA

Check a draft for stock AI phrasing and report exactly where it appears.

Returns clean (boolean), a count, and every occurrence with the sentence it sits in. Run it after humanize_text and rewrite each flagged sentence, keeping every fact, figure, name and link. Repeat until clean is true - the house standard is zero, not "fewer".

Cheaper and more precise than score_ai_text for this one job; score_ai_text also measures rhythm and gives you the number.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the return shape (clean boolean, count, every occurrence with its sentence) and a comparative cost/precision trait versus score_ai_text. It stops short of stating any auth, rate-limit, or side-effect behavior, but the tool is an analysis read so the gap is minor.

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?

Front-loaded with the core action in the first sentence, then value-add detail about return values, workflow, and sibling comparison. Every sentence earns its place; the trailing clause is compressed and informative rather than filler.

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?

No output schema and no annotations, yet the description covers the return payload, the workflow loop, and the stopping criterion. An agent has everything needed to invoke it and act on the result.

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 0% for the single required 'text' parameter, so the description must compensate. It implies the input is a draft and gives post-processing instructions about 'every fact, figure, name and link', but never states the format, size limits, or whether text is plain or markdown.

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 ('Check') and resource ('a draft for stock AI phrasing') plus the output scope ('report exactly where it appears'). It explicitly distinguishes itself from the sibling score_ai_text, so an agent can tell the two apart without opening either schema.

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?

Gives explicit sequencing ('Run it after humanize_text'), the follow-up action ('rewrite each flagged sentence'), and a stopping condition ('Repeat until clean is true'). It also names the alternative and the condition that selects this tool over score_ai_text.

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

find_storiesA

Step 1 when the input is a TOPIC rather than a specific headline.

"AI today", "electric vehicles", "Indian fintech" are topics: there is no claim to verify yet, you first have to find out what actually happened. This searches recent coverage, groups articles reporting the same event into stories, and ranks them by independent publisher count and freshness.

Use ready_to_write - those stories already clear the two-publisher bar and have fetchable URLs. Check age_hours to pick something current. Then pass the chosen story's headline to verify_news and its fetchable_urls to fetch_article_facts.

days is the recency window and defaults to 2. Widen it if nothing comes back; narrow it to 1 for same-day news only.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo
limitNo
topicYes

TDQS

A4.3/5.0
Behavior4/5

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

No annotations exist, so the description carries the burden and does meaningfully disclose behavior: articles are deduplicated into events, ranking is by independent publisher count and freshness, and output fields like ready_to_write, age_hours and fetchable_urls are surfaced. It omits auth/permission or rate-limit context, keeping it short of a 5.

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?

Front-loaded with the routing condition and the core behavior, then usage detail and the parameter note. A few lines (the topic examples) are illustrative rather than essential, but overall the structure earns its length.

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-param tool with no output schema and no annotations, the description supplies the workflow position, the returned field names, and the key parameter guidance. Only `limit` lacks any explanation, which is a minor gap.

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 documents `days` well (default 2, widen if empty, narrow to 1 for same-day), but gives no meaning for `limit` and only contextualizes `topic`. Partial compensation for the undocumented 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?

States a specific verb chain (searches coverage, groups articles into stories, ranks by publisher count and freshness) and clearly scopes itself: 'Step 1 when the input is a TOPIC rather than a specific headline.' This distinguishes it from verify_news, which handles the headline case.

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?

Explicit when-to-use (topic input, no claim to verify yet) versus what comes next (verify_news for the headline, fetch_article_facts for URLs), plus guidance to prefer ready_to_write stories and check age_hours. Effectively a routing instruction for the whole workflow.

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

generate_imageA

Step 8. Generate a banner image for the article and save it locally.

Build the prompt from the article's visual concepts, not its brand names. A trademark filter runs anyway and rewrites brand terms into generic descriptors before the prompt leaves this machine; check terms_removed to see what it changed.

The returned path is local. Upload the file and pass a public https URL to build_schema, or NewsArticle.image will point somewhere no crawler can reach.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugNo
styleNobanner
promptYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses a hidden trademark filter that rewrites brand terms before the prompt leaves the machine, points at the terms_removed field to audit that rewrite, and warns that the returned path is local-only so an unuploaded file leaves NewsArticle.image unreachable by crawlers. It omits cost, latency (image generation is typically slow/paid), and any auth requirements.

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?

Three short paragraphs, front-loaded with the action, then the prompt-authoring rule, then the output-handling caveat. Every sentence carries a distinct instruction; no filler.

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 3-param tool with no annotations, no output schema, and 0% schema coverage, the description does cover the highest-risk behaviors (prompt content, filter side effect, local-path gotcha). But two of three parameters remain opaque and nothing is said about cost, timeout, or failure modes, so an agent still has to guess on invocation details.

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 gives real semantic guidance for 'prompt' (build from visual concepts, not brand names), but 'slug' and 'style' go entirely unexplained in both places, including which of banner/square to pick and what slug controls. Partial compensation only.

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 ('Generate a banner image for the article') plus the side effect ('save it locally'), and the 'Step 8' framing places it unambiguously in the workflow. No sibling tool could be mistaken for it.

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 step numbering situates it in the pipeline, and the description explicitly routes the agent forward: 'Upload the file and pass a public https URL to build_schema.' It stops short of stating when not to use it or what alternative exists if image generation is undesired.

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

get_profileA

Check whether this server has been set up, and with what.

CALL THIS FIRST, before anything else. If configured is false, ask the user the returned questions in the chat, wait for their answers, then call set_profile. Every content tool refuses to run until then.

The answers decide the byline, the voice, the schema publisher, where the call to action links, and the canonical URL for every post. Nothing here is inferred from the environment.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries full behavioral burden and does so: it discloses the gating behavior ('every content tool refuses to run until then'), the no-inference policy ('nothing here is inferred from the environment'), and the downstream consequences of the answers (byline, voice, schema publisher, CTA links, canonical URL). This is rich context beyond what a bare read tool would suggest.

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?

Front-loaded with the imperative 'CALL THIS FIRST' and well-structured into purpose, sequencing, and consequences. Slightly verbose in the detail about answers deciding byline/voice/etc., but every sentence conveys actionable information.

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 zero-parameter gating tool with no output schema and no annotations, the description is complete: it explains what it checks, what it returns (configured flag and questions), what to do in each branch, and how its results cascade into other tools. No material gap remains.

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?

Zero parameters, so baseline is 4. The description adds value by explaining that the tool returns a configured boolean and, when false, a set of questions to present to the user, which is meaningful return-shape context even absent a formal output 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?

States a specific verb (check) and resource (server setup/profile) with clear scope: whether set up and with what. Distinguishes itself from siblings like set_profile and reset_profile by describing a read/status check, and its 'CALL THIS FIRST' directive makes its role unmistakable.

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?

Explicitly says to call this first before anything else, explains the conditional branch (if configured is false, ask returned questions then call set_profile), and states that every content tool refuses to run until then. Alternatives and sequencing are fully specified.

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

humanize_textA

Optional. Rewrite a draft to strip AI writing tells, keeping facts intact.

Prefer review_draft. This rewrites the text for the writer, which produces machine-written prose again; a detector will read it as such, because detectors measure how predictable the wording is rather than how many stock phrases it contains. Use this only to edit text the writer already wrote, and tell them it was used.

With an LLM key configured, the rewrite happens server-side and comes back in rewritten_text. Without one, mode='delegated_to_caller' and you must apply the returned instructions to text_to_rewrite yourself, preserving every fact, figure, name, date, quote and URL exactly.

Optionally pass voice_sample to match a specific writer's rhythm. The sample governs style only and never contributes facts.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
voice_sampleNo

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does: it discloses the two execution modes (server-side vs. mode='delegated_to_caller'), the return fields (rewritten_text, instructions), the caller's obligation to apply instructions preserving facts/figures/names/dates/quotes/URLs, and that voice_sample governs style only. This is unusually complete behavioral disclosure.

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?

Front-loaded with 'Optional' then the core action, and every sentence carries information. The detector-explanation sentence is slightly digressive but justifies the 'prefer review_draft' guidance, so it largely 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?

No output schema and no annotations, yet the description covers modes, return values, constraints on fact preservation, and parameter behavior. An agent has everything needed to call and correctly handle this tool.

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 coverage is 0%, so the description must compensate. It fully explains voice_sample (optional, matches writer rhythm, style only, never contributes facts) with a default-behavior note. The 'text' parameter is only implicitly documented via the delegated-mode reference to text_to_rewrite, so one gap remains.

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+resource ('Rewrite a draft to strip AI writing tells, keeping facts intact') and names the sibling it is not ('Prefer review_draft'). An agent can separate this from review_draft and score_ai_text without opening the schema.

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?

Explicitly gives when-not ('Prefer review_draft', 'Use this only to edit text the writer already wrote'), why-not (rewrites produce machine-written prose again), and a disclosure obligation ('tell them it was used'). This is a textbook routing instruction.

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

reset_profileA

Forget the byline and voice, so the setup questions are asked again.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses the fields that are destroyed (byline, voice) and the resulting state (setup asks again), but says nothing about reversibility, whether other profile data survives, or any confirmation behavior.

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, front-loaded sentence with the destructive verb first and the practical consequence second. No filler.

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 zero-parameter, no-output-schema tool the description covers the essentials, but with no annotations it leaves key questions open: whether the reset is irreversible, what else is cleared from the profile, and whether prior data can be recovered.

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?

Zero parameters, so there is no schema semantics to add; the baseline of 4 applies. The description correctly implies the tool takes no arguments.

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?

Names the action ('forget') and the specific state cleared ('the byline and voice'), which distinguishes it clearly from set_profile and get_profile among the siblings. It stops short of saying it resets persisted profile data, but the effect 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 Guidelines3/5

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

The stated consequence ('so the setup questions are asked again') implies when an agent would call it, i.e. to force re-onboarding. There is no explicit when-not guidance and no alternative tool named for the adjacent case of merely editing the profile.

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

review_draftA

Step 6. Read the writer's draft and say where it is weak. Never rewrite it.

Pass the human-written draft and the facts from fetch_article_facts. Returns must_fix / worth_fixing / consider, each note naming the sentence and what to do about it, plus what the draft already does well.

Checks claims against the researched facts and flags figures or quotes nothing supports, quotes over 15 words or missing attribution, stock AI phrasing, weak openings, hedging stacks, passive density, and flat sentence rhythm.

Returning a rewritten draft defeats the purpose. Give the writer the notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
draftYes
factsNo

TDQS

A4.3/5.0
Behavior5/5

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

No annotations exist, so the description carries the full burden and does so richly: it describes the output structure (must_fix / worth_fixing / consider with sentence-level notes plus positives) and enumerates the concrete checks performed (unsupported figures/quotes, quotes over 15 words, missing attribution, stock AI phrasing, weak openings, hedging stacks, passive density, flat rhythm). This is well beyond what the schema provides.

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?

Front-loads the purpose and the critical constraint ('Never rewrite it') before elaborating the check list. The final line ('Returning a rewritten draft defeats the purpose') is a mild repetition of the earlier prohibition, costing a little efficiency.

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 two-parameter, no-annotation, no-output-schema tool, the description covers purpose, inputs, output categories, and the full review rubric. The only shortfall is the unclear handling of the optional `facts` parameter and what happens when it is null.

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 0%, so the description must compensate, and it partially does by explaining that `draft` is the human-written text and `facts` comes from fetch_article_facts. It does not clarify that `facts` is optional/defaults to null or the expected fact object shape, leaving a gap given the zero coverage.

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+resource ('Read the writer's draft and say where it is weak') and immediately distinguishes itself from the sibling humanize_text by forbidding rewriting. The 'Step 6' marker and reference to fetch_article_facts position it precisely in the workflow.

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?

Clearly says to pass the human-written draft and the facts from fetch_article_facts, and explicitly warns 'Never rewrite it' / 'Returning a rewritten draft defeats the purpose.' It doesn't name an alternative tool to use instead when a rewrite is actually wanted (e.g. humanize_text), but the boundary with the rewrite siblings is strongly implied.

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

save_and_presentA

Step 11. Write the finished package to disk and return the paths.

Produces a timestamped folder containing paste-into-blogger.html (both JSON-LD blocks plus the styled body - the file to paste into the post editor), index.html (a standalone preview page with meta, canonical, Open Graph and Twitter tags in the head), body.html, newsarticle.jsonld, faqpage.jsonld, a copy of the image, meta.json, report.md, and - when pack from build_publishing_pack is supplied - publish-pack.md with the title, labels, permalink and Gemini image prompt.

report.md is the human-readable summary: verification verdict and publishers, human score before and after humanising, SEO score with any must-fix items, and the reference list. Populate meta with keys verification, human_score ({before, after, detector_used, is_real_detector}), seo and references and they all appear in it.

Pass the meta dict that build_schema returned - canonical_url, image_url and the rest are read from it when not given explicitly. Put the verification result, both human scores, the SEO audit and the reference list in meta so the post stays auditable later.

ParametersJSON Schema
NameRequiredDescriptionDefault
metaNo
packNo
slugYes
titleNo
languageNo
html_bodyYes
image_urlNo
image_pathNo
descriptionNo
json_ld_faqNo
canonical_urlNo
json_ld_articleNo

TDQS

A4.1/5.0
Behavior4/5

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

No annotations, so the description carries the full burden. It discloses that files are written to a timestamped folder, that a file is only produced conditionally ('when pack from build_publishing_pack is supplied'), and that outputs include human-readable report.md. It doesn't address overwrite behavior or permissions, but the write scope is well conveyed.

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?

Front-loaded with the core action, then structured into artifact list and meta guidance. It is fairly long but each section (outputs, report.md, meta keys) adds distinct information, with little redundancy.

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 12-param, no-annotation, no-output-schema tool, the description documents the files produced and the meta structure well. The main gap is that half the input parameters receive no explanation, but the critical ones and the meta/pack objects are covered.

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 does explain that meta should be the dict from build_schema and that canonical_url/image_url are read from it, and it specifies the required meta keys. However, only 2 of 12 parameters (slug, html_body) are implied by the artifact list, and most others (title, language, json_ld_article, json_ld_faq, etc.) are never explained.

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: 'Write the finished package to disk and return the paths.' It also enumerates the exact artifacts produced, so an agent can distinguish it from siblings like build_schema or build_publishing_pack, which produce inputs rather than write to disk.

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?

Frames itself as 'Step 11', clearly placing it at the end of the pipeline after build_publishing_pack and build_schema. It explains that meta comes from build_schema's return, giving clear sequencing context, but doesn't explicitly state exclusions or alternatives to this tool.

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

score_ai_textA

Step 7. Score how human the text reads, 0-100 (higher = more human).

Uses a real detector API if one is configured, otherwise a local heuristic that measures structural tells (sentence-length burstiness, stock phrases, em dash density, lexical variety). Check is_real_detector before presenting the number, and always surface the caveat: no detector score proves authorship. Run it before and after humanize_text to show the improvement.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes

TDQS

A4.4/5.0
Behavior5/5

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

No annotations exist, so the description carries the full behavioral burden and does so well: it discloses the dual execution path (real detector API vs local heuristic) and enumerates what the heuristic measures (burstiness, stock phrases, em dash density, lexical variety). It also flags an important interpretive caveat (no score proves authorship).

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?

Purpose and scale are front-loaded in the first sentence, followed by mechanism and usage notes. The 'Step 7.' prefix is workflow scaffolding rather than tool definition, and the mid-sentence line break adds slight noise, but overall it is tight and earns its sentences.

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?

With one required parameter, no output schema, and no annotations, the description covers everything an agent needs: what it returns (0-100 score), the mechanism and its fallback, the reporting caveat, and the recommended call sequence relative to humanize_text.

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 0% for the single 'text' parameter, but the parameter is trivially inferrable from the description's subject ('how human the text reads'). The description adds scale semantics but no input format details, so it partially compensates for the coverage gap.

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?

States a specific verb (score), resource (text), and output scale (0-100, higher = more human), and ties itself to the humanize_text workflow. It does not explicitly distinguish itself from near-siblings like find_ai_words, so it is clear but not fully sibling-differentiated.

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?

Explicit sequencing guidance: check is_real_detector before presenting the number, always surface the authorship caveat, and run before and after humanize_text to show improvement. This tells the agent both when to call it and how to report it, with no inference required.

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

seo_auditA

Step 10. Score the finished body against on-page SEO rules before publishing.

Checks H1 uniqueness and keyword placement, keyword density, H2 structure, word count, meta title and description lengths, slug shape, image alt text, and external source links. Returns a score plus must_fix / should_fix / nice_to_have lists.

Pass headline when the body has no H1 because the blog platform renders the title itself - the H1 checks then run against that headline instead of failing a correctly-built post.

Fix everything in must_fix and call again. On-page structure only - it says nothing about search volume, competition or backlinks.

ParametersJSON Schema
NameRequiredDescriptionDefault
slugNo
headlineNo
html_bodyYes
meta_titleNo
primary_keywordYes
meta_descriptionNo
secondary_keywordsNo

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the return structure (score plus must_fix/should_fix/nice_to_have lists), the iterative fix-and-recheck pattern, and the scope ceiling. It does not state side effects (does it persist anything?) or failure behavior, but for a read-only scoring operation those are low-stakes gaps.

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?

Well structured and front-loaded: step context first, then the checklist, then return shape, then the parameter caveat, then the scope boundary. Every block earns its place, though the enumerated check list is somewhat long and could be tightened into a single clause.

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?

No output schema exists, but the description compensates by describing the score and the three fix-tier lists. No annotations exist, and the description supplies workflow, scope, and the primary return contract. It is complete enough to invoke correctly, missing only side-effect/failure detail that matters little for a scoring tool.

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 0%, so the description must compensate, and it does for the key ambiguity: it explains that `headline` substitutes for a missing H1. It also implicitly ties `primary_keyword` and `meta_title`/`meta_description` to specific checks. However, five of seven parameters (slug, secondary_keywords, and format expectations for html_body/meta fields) receive no added meaning beyond their names.

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 (Score) and resource (finished body against on-page SEO rules), enumerates the exact checks performed, and explicitly scopes itself: 'On-page structure only - it says nothing about search volume, competition or backlinks.' This cleanly distinguishes it from siblings like seo_keywords and build_schema.

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?

Provides explicit workflow context ('Step 10... before publishing'), a retry loop ('Fix everything in must_fix and call again'), and a clear exclusion boundary that names what the tool does not cover. The `headline` guidance explains exactly when to pass that parameter versus letting H1 checks fail.

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

seo_keywordsA

Step 4. Mine the keywords this post should target, before drafting.

Pass the headline plus the text of the facts returned by fetch_article_facts. Keywords come out of the source material you actually fetched, so they reflect the reporting rather than a guess.

Returns primary_keyword, secondary_keywords, entities, and - from real Google autocomplete data - long_tail_queries and faq_query_candidates. Draft the FAQ from faq_query_candidates wherever your facts can answer them: those are questions people actually type. Also returns a suggested slug, meta title and meta description to feed into build_schema and seo_audit.

No search-volume or competition data; that needs a paid keyword API.

ParametersJSON Schema
NameRequiredDescriptionDefault
textsNo
titleYes
include_suggestionsNo

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it names the returned fields, reveals the data source ('real Google autocomplete data'), and discloses a hard limitation ('No search-volume or competition data; that needs a paid keyword API'). It does not cover auth or rate/token behavior, so not a full 5.

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?

Front-loaded with the step number and purpose, then structured around inputs and outputs. It is longer than average but nearly every sentence adds usable detail; a small amount of the 'Draft the FAQ...' advice borders on downstream workflow guidance rather than tool selection.

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?

There is no output schema and no annotations, yet the description enumerates the return fields and the tool's limitations, which is exactly the gap it needs to fill. The only real omission is any explanation of the 'include_suggestions' parameter.

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 usefully clarifies the required 'title' (headline) and the 'texts' array (facts text from fetch_article_facts), but never explains 'include_suggestions', even though that flag governs whether the autocomplete-derived data is returned.

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 ('Mine the keywords this post should target') and places it in a workflow ('Step 4 ... before drafting'). It is clearly distinct from sibling tools like seo_audit and build_schema, which it feeds rather than replaces.

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?

Gives clear sequencing ('before drafting') and precise inputs ('Pass the headline plus the text of the facts returned by fetch_article_facts'), plus the downstream routing to build_schema and seo_audit. There is no explicit when-not-to-use or named alternative, so it stops short of a 5.

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

set_profileA

Record who is publishing, where, and in what voice. Run once, after asking.

author_name: the person's real name. Prints as "By " and goes into the NewsArticle author field. tone: neutral | witty | upbeat | heartfelt | sombre. Shapes how posts are written; it never changes a fact, a figure, a quote or a link. company_name: the publisher. Becomes the schema publisher and the linked text in the closing call to action. site_url: the domain where posts are published. Canonical URLs, image paths and the call-to-action link are all built from it. A main domain or a subdomain both work. company_url: only when the blog is on a subdomain and the call to action should point at a different company site. Defaults to site_url. logo_url: defaults to /logo.png.

Only pass values the user actually typed. Ask the name, company and domain as free-text questions - do not offer guessed options, do not take a name from the account or folder path, do not pick a tone for them, and do not carry over a company or domain from an earlier post or example.

ParametersJSON Schema
NameRequiredDescriptionDefault
toneYes
logo_urlNo
site_urlNo
author_nameYes
company_urlNo
company_nameNo

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations the description carries the full burden, and it does well: it discloses side effects ('Prints as By <name>', drives canonical URLs and CTA links) and defaults (company_url defaults to site_url, logo_url defaults to <company_url>/logo.png). It does not mention permissions, whether it overwrites an existing profile, or what a repeat call does, so there is residual ambiguity.

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?

Front-loads the purpose sentence, then uses a clean one-block-per-parameter layout that is easy to scan. It is somewhat verbose, but nearly every sentence conveys a behavioral rule or a parameter meaning rather than 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?

For a six-parameter mutation tool with no annotations and no output schema, the description covers parameter meaning, defaults, enum values and anti-guessing rules. The remaining gap is lifecycle behavior (overwrite semantics, interaction with reset_profile/get_profile), which an agent would still have to infer.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate fully, and it does: every one of the six parameters gets meaning, plus the tone enum values (neutral | witty | upbeat | heartfelt | sombre) and default chains for company_url and logo_url. This is well above what the bare schema provides.

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 opening line states a specific verb and resource: it records the publisher identity, location and voice. It is clearly distinguishable from siblings like get_profile and reset_profile, which read or clear the same config.

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?

Gives concrete usage timing ('Run once, after asking') and hard constraints on sourcing values (only user-typed, no guesses, no carry-over from earlier posts). It stops short of naming the sibling tools (get_profile, reset_profile) that are the real alternatives, so it is strong but not exhaustive.

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

verify_newsA

Step 2 - confirm a SPECIFIC headline is real and corroborated. Check that a headline describes a real, corroborated story.

Searches every configured news provider, keeps only results that actually match the headline, and counts how many INDEPENDENT publishers are carrying it. Returns is_legit=false unless at least two independent publishers match, or a single primary/official source does.

This verifies a headline; it does not find one. If the user gave you a topic ("today's AI news") rather than a headline, call find_stories first. Note that an old headline will correctly return old sources - days limits how far back to look.

Do not draft anything if is_legit is false. Feed fetchable_urls to fetch_article_facts, and use reference_candidates as the reference list - those are real publisher URLs. Some providers return aggregator redirects that still name the outlet; they count toward corroboration but are not usable as links, and build_schema rejects them.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo
limitNo
titleYes

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses the search-across-providers behavior, the two-publisher corroboration threshold (or one primary/official source), the is_legit=false default, and the aggregator-redirect edge case that counts for corroboration but is rejected by build_schema. This is unusually rich behavioral context.

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?

Front-loaded with the 'Step 2' role and the core verification rule, then the alternative and downstream feeding. Every sentence earns its place, though it is dense enough that a couple of clauses could be tightened.

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?

Despite no output schema, the description names the key return fields (is_legit, fetchable_urls, reference_candidates) and explains the pass/fail rule, which is what an agent needs. Minor gap: the effect of the `limit` parameter is left unexplained.

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 explains `days` ('limits how far back to look') and implies `title` is the headline under test, but `limit` is never mentioned and the title format/expectations remain unspecified. Partial compensation only.

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+resource ('confirm a SPECIFIC headline is real and corroborated') with an explicit scope distinction: 'This verifies a headline; it does not find one.' This contrast against find_stories lets an agent route correctly without opening sibling schemas.

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?

Explicit when-to-use routing: 'If the user gave you a topic ... call find_stories first,' plus a hard gate ('Do not draft anything if is_legit is false'). It also names downstream consumers (fetch_article_facts, build_schema) with the exact fields to pass, so usage is fully specified.

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. 18 tool updatesv0.2.0
    • First observedbuild_publishing_pack
    • First observedbuild_schema
    • First observedcapabilities
    • First observeddraft_brief
    • First observedfetch_article_facts
    • First observedfind_ai_words
    • First observedfind_stories
    • First observedgenerate_image
    • First observedget_profile
    • First observedhumanize_text
    • First observedreset_profile
    • First observedreview_draft
    • First observedsave_and_present
    • First observedscore_ai_text
    • First observedseo_audit
    • First observedseo_keywords
    • First observedset_profile
    • First observedverify_news

TDQS

A4.1/5.0

Scored across 18 tools

Disambiguation4/5

Most tools have clearly distinct roles in a stepwise pipeline, and descriptions explicitly differentiate overlapping tools (e.g., score_ai_text vs find_ai_words, review_draft vs humanize_text). A few pairs—like the AI-detection tools and the profile-management tools—could still be momentarily confused, but the guidance resolves the boundary. Overall, an agent can reliably select the right tool.

Naming Consistency4/5

Tool names are consistently snake_case and mostly follow a verb_noun or action-oriented pattern. Minor deviations like `capabilities`, `seo_keywords`, and `seo_audit` are noun phrases without explicit verbs, but they remain readable and predicable. The set is not chaotic.

Tool Count4/5

18 tools is slightly above the ideal 3–15 range, but each tool corresponds to a distinct step in a complete news-blog composition pipeline. Given the end-to-end workflow (verification, fact extraction, SEO, drafting, publishing pack), the count is justified. Nothing feels redundant or padded.

Completeness5/5

The surface covers the full lifecycle from profile setup and story discovery through verification, fact extraction, SEO, drafting, review, image generation, schema building, and final packaging. There are no obvious dead ends for composing and saving a news blog post. Optional tools like humanize_text are clearly marked, and every major operation has a corresponding tool.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Aggregates news from 7 APIs and unlimited RSS feeds with AI-powered bias removal and synthesis. Provides over 7,300 free daily requests with conversation-aware caching and 25 comprehensive news analysis tools.
    1
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Exposes publisher journalism to LLMs and agent frameworks via search, retrieval, source grounding, and consistent citation, enabling accurate content retrieval with attribution and policy enforcement.
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    A writing tool your agent calls: it finds timely sources across news, social, and the web, ranks them by relevance, and writes human-sounding posts worth publishing.
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables editorial content QA over the Model Context Protocol with four local tools that analyze readability, AI-sounding language, SEO on-page factors, and produce full reports where every finding includes an actionable fix.
    4
    1
    MIT