Skip to main content
Glama
Mohammed-Jameal-J

NewsBlog Composer MCP

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GOOGLE_CSE_IDNoGoogle Custom Search Engine ID. Needs both GOOGLE_CSE_KEY and GOOGLE_CSE_ID from programmablesearchengine.google.com.
GOOGLE_CSE_KEYNoGoogle Custom Search API key. Needs both GOOGLE_CSE_KEY and GOOGLE_CSE_ID from programmablesearchengine.google.com. 100 queries/day, no card.
IMAGE_PROVIDERNoSet IMAGE_PROVIDER=cloudflare to use Cloudflare Workers AI (FLUX schnell) for images. Recommended: a free daily allowance, no watermark, and it is a real production API.
TAVILY_API_KEYNoTavily API key. 1,000 credits/month, renews monthly, no card. The best keyed option for this pipeline; set TAVILY_API_KEY.
POLLINATIONS_TOKENNoFree Pollinations token — register at auth.pollinations.ai, no card. This removes the watermark and raises the rate limit. Set POLLINATIONS_TOKEN.
CLOUDFLARE_API_TOKENNoCloudflare API token. Set CLOUDFLARE_API_TOKEN along with CLOUDFLARE_ACCOUNT_ID when IMAGE_PROVIDER=cloudflare.
CLOUDFLARE_ACCOUNT_IDNoCloudflare account ID. Set CLOUDFLARE_ACCOUNT_ID along with CLOUDFLARE_API_TOKEN when IMAGE_PROVIDER=cloudflare.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
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.

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.

reset_profileA

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
house_styleStructure, sourcing and voice rules the drafting step must follow.
humanizer_rulesThe AI-writing-tell rules used by humanize_text.

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