Koskamo

Stable News MCP

Provides a daily morning news edition ranked by published rules, written in the provider's own words with links to outlets. Users can sign in to receive personalized editions based on their work interests, access audio podcasts, and search recent news history.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Stable News MCP logo, by Stable NewsVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-08Operated by Stable News
You need:sign in with Google, GitHub, email or your passwordcomplete OAuth sign-inuse your own Stable News API token
MCP endpoint (Streamable HTTP)
https://stablenews.ai/mcp/news
Vendor documentation

What its tools do

13 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

13 of 13 have a description · 13 of 13 declare behavior hints · 2 of 11 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to stablenews.ai ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Receive a daily morning news edition
  • Search news from the last two weeks
  • Listen to audio versions of editions
  • Get personalized news based on work interests

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
Stable News 1
MCP protocol negotiated in check
2025-11-25
Tools
13 advertised
Resources
1 advertised
Resource templates
0 advertised
Prompts
1 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": false,
    "listChanged": true
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Stable News: one edition a day, ranked by a published rule, in our own words with links to the outlets. Use it for the news. 'Stable News morning', 'my morning', 'the morning edition', 'the news today' or 'what's new' is morning(): the reader's own edition, made each morning from their interests, else the World edition. 'Top stories', 'top ten', 'the last 24 hours' or 'what matters now' is top(); one country's is top(country='FI'); the Polish and US editions are edition='pl' and edition='us'. 'Why is this here' is why(item_id). A question about recent events ('anything on X this week', 'what happened with Y') can be search(query, days), the stories of our pool of the last 14 days; it costs one credit: say so the first time. When the reader says who they are or what they want each morning ('I live in Warsaw, I follow Polish tech and Blackstone's deals'), write their brief: my_brief() first; then the record in the brief's YAML (brief: 1; who; lanes, each standing on a target, an all_of, an any_of or what a piece says, with its lines owed or up_to; a plain name where you know no id, the tool resolves it) to set_brief(). Say its read_back in words, never the YAML; its one question: ask, or keep what was taken, answer_brief() changes it; show rehearse_brief() (the last mornings by lane); save with save_brief(confirm) only on the reader's yes. A change later is amend_brief(), then save_brief(). One passing interest from a reader with no brief ('more Y, less Z'): save_interest, their words as the cause: a target when one names it, else a draft, which answers a preview and a `confirm` digest; save again with preview=<confirm> unless it found nothing. Then say in one line what was saved and that their own edition is built from it each morning. morning, top and why draw a card the reader already sees: never list its lines again; say in one or two sentences what stands out for this reader and offer one next step. When you write stories yourself, keep each one's `page` or `url` link, show `countries` as flags, and say the list is as of its `as_of`. A story's `score` on top is the edition's perspective, 0-1: its mains pulled by the edition's stakes; a morning line's `score` is the main at the edition's home. `mains` carries the pair, the main at home and at the world: where they differ, say both (Poland .62, the world .04), never one as the truth; why's `pulls` say which stake lifted it and `gates` why a main is cut (no outlet abroad told it, a routine notice).

Tools

13 advertised

morning — Morning edition
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

morning input schema
{
  "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
}
morning annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
top — Top stories
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

top input schema
{
  "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
}
top annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
why — Why it is here
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

why input schema
{
  "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
}
why annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
search — Search the news
Advertised by the server during the last successful anonymous check.

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.

search input schema
{
  "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
}
search output schema
{
  "type": "object",
  "additionalProperties": true
}
search annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
save_interest — Save an interest
Advertised by the server during the last successful anonymous check.

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.

save_interest input schema
{
  "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
}
save_interest output schema
{
  "type": "object",
  "additionalProperties": true
}
save_interest annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
my_interests — My interests
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every magnet that draws the reader's edition, theirs over the edition's, with the words they gave, and their credits.

my_interests input schema
{
  "type": "object",
  "properties": {
    "edition": {
      "type": "string",
      "default": "world"
    }
  },
  "additionalProperties": false
}
my_interests output schema
{
  "type": "object",
  "additionalProperties": true
}
my_interests annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
set_brief — Set the brief
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

set_brief input schema
{
  "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
}
set_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
set_brief annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
answer_brief — Answer the brief's question
Advertised by the server during the last successful anonymous check.
Advertised read-only

The question set_brief asked, answered: the choice put in the record, which is compiled again.

answer_brief input schema
{
  "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
}
answer_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
answer_brief annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
rehearse_brief — Rehearse the brief
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

rehearse_brief input schema
{
  "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
}
rehearse_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
rehearse_brief annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
save_brief — Save the brief
Advertised by the server during the last successful anonymous check.

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

save_brief input schema
{
  "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
}
save_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
save_brief annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
my_brief — My brief
Advertised by the server during the last successful anonymous check.
Advertised read-only

The brief the reader holds, read back (say it in words), with the `confirm` an amendment saves on; or what stands in its place.

my_brief input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
my_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
my_brief annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
amend_brief — Amend the brief
Advertised by the server during the last successful anonymous check.
Advertised read-only

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.

amend_brief input schema
{
  "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
}
amend_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
amend_brief annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
forget_brief — Forget the brief
Advertised by the server during the last successful anonymous check.
Advertised destructive

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.

forget_brief input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
forget_brief output schema
{
  "type": "object",
  "additionalProperties": true
}
forget_brief annotations
{
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": true
}

Prompts

1 advertised

morning — Stable News morning

Advertised by the server during the last successful anonymous check.

Today's edition from Stable News.

edition
Provide a value matching the following JSON schema: {"anyOf":[{"type":"string"},{"type":"null"}]}. Encode non-string values as JSON.

Resources

1 advertised

morning_card — Stable News morning card

Advertised by the server during the last successful anonymous check.

The morning edition, a list of stories and why each is where it is, drawn as a card.

morning_card URI
ui://stable-news/morning-card.html

MIME type: text/html;profile=mcp-app

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1622 ms
95th percentile latency
1622 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1622 ms · metadata changed · 13 tool(s), 1 resource(s), 0 resource template(s), 1 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http stable-news-mcp https://stablenews.ai/mcp/news

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add stable-news-mcp --url https://stablenews.ai/mcp/news

Cursor

Merge this server into .cursor/mcp.json in your project, then enable stable-news-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "stable-news-mcp": {
      "url": "https://stablenews.ai/mcp/news"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "stable-news-mcp": {
      "type": "streamableHttp",
      "url": "https://stablenews.ai/mcp/news",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start stable-news-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "stable-news-mcp": {
      "type": "http",
      "url": "https://stablenews.ai/mcp/news"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http stable-news-mcp https://stablenews.ai/mcp/news

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://stablenews.ai/mcp/news

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "stable-news-mcp": {
      "serverUrl": "https://stablenews.ai/mcp/news"
    }
  }
}

Let your agent find its tools

Find servers like Stable News MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Stable News MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing