One news edition a day, ranked by a published rule, in our own words with links to the outlets.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
The whole brief as amended by one sentence of the reader's, compiled as set_brief does, with `changes` against the one they hold. save_brief with the new `confirm` keeps it.
The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http news https://stablenews.ai/mcp/news
The whole brief as amended by one sentence of the reader's, compiled as set_brief does, with `changes` against the one they hold. save_brief with the new `confirm` keeps it.
| Argument | Type | Description |
|---|---|---|
| brief* | string | The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved. |
| language | string |
{
"type": "object",
"required": [
"brief"
],
"properties": {
"brief": {
"type": "string",
"maxLength": 8000,
"minLength": 1,
"description": "The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved."
},
"language": {
"enum": [
"en",
"pl"
],
"type": "string",
"default": "en"
}
},
"additionalProperties": false
}The question set_brief asked, answered: the choice put in the record, which is compiled again.
| Argument | Type | Description |
|---|---|---|
| brief* | string | The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved. |
| choice* | string | One of its options' `choice` (a target). |
| language | string | |
| question* | string | The question's `id` (its pointer into the record). |
{
"type": "object",
"required": [
"brief",
"question",
"choice"
],
"properties": {
"brief": {
"type": "string",
"maxLength": 8000,
"minLength": 1,
"description": "The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved."
},
"choice": {
"type": "string",
"description": "One of its options' `choice` (a target)."
},
"language": {
"enum": [
"en",
"pl"
],
"type": "string",
"default": "en"
},
"question": {
"type": "string",
"description": "The question's `id` (its pointer into the record)."
}
},
"additionalProperties": false
}The reader's brief dropped, only when they asked for that in words: nothing draws their morning but the world's. Their history stays on the site.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}The day's edition: the briefing's lines by section, each with its countries, who it is about, its score (the story's main at the edition's home, 0-1) and `mains` (the main at home and at the world), our story page and the outlet, and what was read for it. With no `edition`, the reader's own (made each morning from their interests; its `own` note says whether it is ready), else the World edition. `edition` world, pl or us names a public edition; `date` YYYY-MM-DD (the latest when omitted); `audio` adds the edition read aloud.
| Argument | Type | Description |
|---|---|---|
| date | any | |
| audio | boolean | |
| edition | any |
{
"type": "object",
"properties": {
"date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"audio": {
"type": "boolean",
"default": false
},
"edition": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"additionalProperties": false
}The brief the reader holds, read back (say it in words), with the `confirm` an amendment saves on; or what stands in its place.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Every magnet that draws the reader's edition, theirs over the edition's, with the words they gave, and their credits.
| Argument | Type | Description |
|---|---|---|
| edition | string |
{
"type": "object",
"properties": {
"edition": {
"type": "string",
"default": "world"
}
},
"additionalProperties": false
}The mornings of the last days the brief would have given, lane by lane: each line a happening with our title and page and the main it was ranked by; a quiet lane says so. From the pool alone; nothing is saved.
| Argument | Type | Description |
|---|---|---|
| days | integer | The last mornings read back. |
| brief* | string | The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved. |
| language | string |
{
"type": "object",
"required": [
"brief"
],
"properties": {
"days": {
"type": "integer",
"default": 7,
"maximum": 14,
"minimum": 1,
"description": "The last mornings read back."
},
"brief": {
"type": "string",
"maxLength": 8000,
"minLength": 1,
"description": "The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved."
},
"language": {
"enum": [
"en",
"pl"
],
"type": "string",
"default": "en"
}
},
"additionalProperties": false
}The brief kept, on the reader's yes: their active record, its lanes drawing their own edition from the next morning. Refused when the record changed since its `confirm`.
| Argument | Type | Description |
|---|---|---|
| brief* | string | The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved. |
| confirm* | string | The `confirm` set_brief or amend_brief gave for this very record. |
{
"type": "object",
"required": [
"brief",
"confirm"
],
"properties": {
"brief": {
"type": "string",
"maxLength": 8000,
"minLength": 1,
"description": "The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved."
},
"confirm": {
"type": "string",
"description": "The `confirm` set_brief or amend_brief gave for this very record."
}
},
"additionalProperties": false
}Move one of the reader's magnets, what draws their own edition: a `target` and a step (away, low, normal, high) saves at once. For a subject no target names, a `draft` of their own words: without `preview` it answers what the draft would give a day, the pieces it finds, and a `confirm` digest; with preview=<confirm> it saves. Their own words are the cause. The same move again changes nothing.
| Argument | Type | Description |
|---|---|---|
| note | any | |
| cause* | string | The reader's own words, kept verbatim as the cause. |
| draft | any | |
| target | any | What to move: world, country:XX (ISO 3166-1), medtop:NNNNNNNN (an IPTC Media Topic), wd:Qnnn (a Wikidata item), word:<a few words> for a subject no code names, or def:<n> for a saved definition. |
| preview | any | The `confirm` digest a draft's preview answered, to save that very draft. |
| language | string | |
| amplitude* | string |
{
"type": "object",
"required": [
"amplitude",
"cause"
],
"properties": {
"note": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
],
"default": null
},
"cause": {
"type": "string",
"maxLength": 300,
"minLength": 1,
"description": "The reader's own words, kept verbatim as the cause."
},
"draft": {
"anyOf": [
{
"type": "object",
"required": [
"author",
"lang",
"said",
"interest",
"names",
"examples"
],
"properties": {
"lang": {
"type": "string",
"pattern": "^[a-z]{2}$",
"description": "The ISO 639-1 language of `said`."
},
"said": {
"type": "string",
"pattern": "\\S",
"maxLength": 1000,
"minLength": 1,
"description": "The reader's words, verbatim; Profile reads them back to that reader."
},
"names": {
"type": "object",
"description": "The names it goes by, per ISO 639-1 language: model-free recall. A name matches whole words, case aside, in a piece's title or teaser, whatever the piece's language; a space or hyphen in it matches a space, a hyphen or nothing, and `*` any letters (a truncation).",
"maxProperties": 12,
"minProperties": 1,
"patternProperties": {
"^[a-z]{2}$": {
"type": "array",
"items": {
"type": "string",
"pattern": "\\S",
"maxLength": 80,
"minLength": 2
},
"maxItems": 20,
"minItems": 1
}
},
"additionalProperties": false
},
"author": {
"enum": [
"reader",
"assistant",
"owner"
],
"type": "string",
"description": "Who wrote this version: the reader, an assistant in conversation, or the owner."
},
"anchors": {
"type": "array",
"items": {
"type": "object",
"required": [
"key",
"use"
],
"properties": {
"key": {
"type": "string",
"pattern": "^(?:country:[A-Z]{2}|medtop:[0-9]{8}|wd:Q[1-9][0-9]{0,9})$",
"description": "country:XX (ISO 3166-1), medtop:NNNNNNNN (an IPTC Media Topic code in the tree) or wd:Qnnn (a Wikidata item), normalised as a magnet's target is."
},
"use": {
"enum": [
"select",
"exclude",
"gate"
],
"type": "string",
"description": "An entity selects or excludes; a code or a country gates or excludes, never selects (0.00 to 0.02 precision as selectors)."
},
"release": {
"anyOf": [
{
"type": "string",
"pattern": "^\\d{4}-\\d\\d-\\d\\d$"
},
{
"type": "null"
}
],
"default": null,
"description": "A Media Topic code's IPTC release; null on a country or an entity."
}
},
"description": "A code, a country or an entity the definition leans on, and how.",
"additionalProperties": false
},
"maxItems": 20,
"description": "Codes, countries and entities, each with its use."
},
"breadth": {
"enum": [
"narrow",
"broad"
],
"type": "string",
"default": "narrow",
"description": "narrow (about it) by default; broad adds adjacent pieces."
},
"counter": {
"type": "array",
"items": {
"type": "object",
"required": [
"item",
"title",
"why"
],
"properties": {
"why": {
"type": "string",
"pattern": "\\S",
"maxLength": 120,
"minLength": 1,
"description": "Why it is in or out, in a few words (\"water\", \"a strike\")."
},
"item": {
"type": "integer",
"minimum": 1,
"description": "The piece's item id. Not checked against the pool, which prunes."
},
"title": {
"type": "string",
"pattern": "\\S",
"maxLength": 400,
"minLength": 1,
"description": "The piece's title as stored, so the definition outlives it."
}
},
"description": "A piece the definition should find (an example) or should not (a counter-example).",
"additionalProperties": false
},
"maxItems": 8,
"description": "Up to 8 pieces the reader does not want, the same shape."
},
"exclude": {
"type": "array",
"items": {
"type": "string",
"pattern": "\\S",
"maxLength": 120,
"minLength": 2
},
"maxItems": 12,
"description": "The wrong senses, named."
},
"include": {
"type": "array",
"items": {
"type": "string",
"pattern": "\\S",
"maxLength": 120,
"minLength": 2
},
"maxItems": 12,
"description": "Each line becomes a facet."
},
"examples": {
"type": "array",
"items": {
"type": "object",
"required": [
"item",
"title",
"why"
],
"properties": {
"why": {
"type": "string",
"pattern": "\\S",
"maxLength": 120,
"minLength": 1,
"description": "Why it is in or out, in a few words (\"water\", \"a strike\")."
},
"item": {
"type": "integer",
"minimum": 1,
"description": "The piece's item id. Not checked against the pool, which prunes."
},
"title": {
"type": "string",
"pattern": "\\S",
"maxLength": 400,
"minLength": 1,
"description": "The piece's title as stored, so the definition outlives it."
}
},
"description": "A piece the definition should find (an example) or should not (a counter-example).",
"additionalProperties": false
},
"maxItems": 8,
"minItems": 3,
"description": "3 to 8 pieces the reader wants, with their titles stored."
},
"interest": {
"type": "string",
"pattern": "\\S",
"maxLength": 600,
"minLength": 1,
"description": "One sentence of what the definition is about: what any future model reads, and a magnet's label."
}
},
"description": "A definition of a reader's own words, one saved version of it (docs/field/own-words.md).",
"additionalProperties": false
},
{
"type": "null"
}
],
"default": null
},
"target": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "What to move: world, country:XX (ISO 3166-1), medtop:NNNNNNNN (an IPTC Media Topic), wd:Qnnn (a Wikidata item), word:<a few words> for a subject no code names, or def:<n> for a saved definition."
},
"preview": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "The `confirm` digest a draft's preview answered, to save that very draft."
},
"language": {
"enum": [
"en",
"pl"
],
"type": "string",
"default": "en"
},
"amplitude": {
"enum": [
"away",
"low",
"normal",
"high"
],
"type": "string"
}
},
"additionalProperties": false
}The stories of the last `days` whose pieces name the query, one row a story, in our words with its lead piece's outlet and link, our story page, how many pieces it was found in, its outlets and days, its score and its place on today's list: today's list first, then by score, then the newest. Costs one credit (the balance comes back); the same search the same day is paid once. A row's `item_id` asks `why`, and with its title goes into a draft's examples for save_interest.
| Argument | Type | Description |
|---|---|---|
| days | integer | The last days searched. |
| limit | integer | Stories given. |
| query* | string | Names, OR between them (at most 5): whole words, `*` any letters after three of the name's own. |
{
"type": "object",
"required": [
"query"
],
"properties": {
"days": {
"type": "integer",
"default": 14,
"maximum": 14,
"minimum": 1,
"description": "The last days searched."
},
"limit": {
"type": "integer",
"default": 10,
"maximum": 50,
"minimum": 1,
"description": "Stories given."
},
"query": {
"type": "string",
"description": "Names, OR between them (at most 5): whole words, `*` any letters after three of the name's own."
}
},
"additionalProperties": false
}The reader's brief compiled from the record you wrote: who they are, their morning, and lanes, each standing on a target (world, country:XX, medtop:N, wd:Qn), an all_of or any_of of them, or what a piece says; a plain name in place of an id is resolved (one match taken; several: the first taken and one `question`). Answers the record, `resolved`, `read_back` (say it in words), `confirm` for save_brief; or `problem` with a pointer and a fix per error. Nothing is saved.
| Argument | Type | Description |
|---|---|---|
| brief* | string | The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved. |
| language | string |
{
"type": "object",
"required": [
"brief"
],
"properties": {
"brief": {
"type": "string",
"maxLength": 8000,
"minLength": 1,
"description": "The brief: the record in YAML or JSON (the schema at /start/brief.schema.json, the example at /start/brief.example.yaml); a plain name where no id is known is resolved."
},
"language": {
"enum": [
"en",
"pl"
],
"type": "string",
"default": "en"
}
},
"additionalProperties": false
}The stories of the last 24 hours in rank order, run again hourly (`as_of`, `window_hours`): each story's rank, our title, its score (0-1: the edition's perspective, its mains pulled by the edition's stakes), `mains` (the main at the edition's home and at the world, the honest pair), its outlets, our story page, and a piece to ask `why` about. With `country`, the stories about it, and a note when we read few of its outlets.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| country | any | ISO 3166-1 alpha-2, such as FI: only the stories about that country. |
| edition | string |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"default": 10
},
"country": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "ISO 3166-1 alpha-2, such as FI: only the stories about that country."
},
"edition": {
"type": "string",
"default": "world"
}
},
"additionalProperties": false
}Why a piece's story is where it is on the list: its rank and score, the mains at the edition's home and at the world, the pulls that lifted it (each stake the edition holds, its step, the main it read and its part of the score, with the arithmetic), the gates that cut a main (no outlet abroad told it, a routine notice), who carried it, who it is about, what is just above and below, and what near it was left out and why.
| Argument | Type | Description |
|---|---|---|
| date | any | |
| edition | string | |
| item_id* | integer |
{
"type": "object",
"required": [
"item_id"
],
"properties": {
"date": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null
},
"edition": {
"type": "string",
"default": "world"
},
"item_id": {
"type": "integer"
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 8, 2026.