# Spoken

> Podcast transcripts as clean Markdown with real speaker names — via the Spoken API.

- name: io.github.spokenmd/spoken
- version: 0.4.3
- connection class: R0 (autonomous)
- trust: 97/100
- quality: 90/100 (strong)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.spokenmd%2Fspoken
- tools: https://api.protogrid.dev/v1/servers/io.github.spokenmd%2Fspoken/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "spoken": {
      "type": "http",
      "url": "https://spoken.md/mcp",
      "headers": {
        "Authorization": "Bearer ${SPOKEN_TOKEN}"
      }
    }
  }
}
```

Placeholders to fill: `${SPOKEN_TOKEN}`.

## Trust

- hygiene: 100
- liveness: 100
- freshness: 100
- provenance: 90
- drivers: +repository +namespace-matches-repo +website +reachable +uptime-100% +updated-14d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 90/100 (strong)

### protocol: 88 (weight 25)

- pass `protocol.modern`: supports 2026-07-28 (server/discover)
- pass `protocol.stateless`: answers without a session
- pass `protocol.transport`: streamable HTTP
- warn `protocol.list_ttl`: tools/list declares ttlMs 0, so clients re-fetch it on every use

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 100 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 8 of 8 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- pass `tools.token_cost`: about 1,238 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 75 (weight 15)

- warn `stability.changes`: 8 tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: deps.dev does not know spoken-mcp@0.4.3

- tools: 8, about 1,238 tokens to load them all
- tool set hash: 70d3487c56d0930cb4eb61976cc52d26
- tools last changed: 2026-10-06T18:51:40.133Z
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.spokenmd/spoken.svg)](https://protogrid.dev/servers/io.github.spokenmd/spoken)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-10-06 `list_new_episodes` changed (inputSchema, outputSchema, annotations)
- 2026-10-06 `unfollow_podcast` changed (outputSchema, annotations)
- 2026-10-06 `follow_podcast` changed (outputSchema, annotations)
- 2026-10-06 `list_following` changed (inputSchema, outputSchema, annotations)
- 2026-10-06 `get_balance` changed (inputSchema, outputSchema, annotations)
- 2026-10-06 `list_episodes` changed (outputSchema, annotations)
- 2026-10-06 `get_transcript` changed (annotations)
- 2026-10-06 `search_podcasts` changed (outputSchema, annotations)

Full history: https://api.protogrid.dev/v1/servers/io.github.spokenmd%2Fspoken/changes

## Dependencies

- npm spoken-mcp@0.4.3: unknown

Dependency graphs from deps.dev; advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database; all CC BY 4.0.

## Remotes

- https://spoken.md/mcp (streamable-http, auth none, reachable true, uptime30d 1)

## Packages

- npm spoken-mcp@0.4.3 secrets: SPOKEN_API_KEY

## Tools (8)

- `follow_podcast`: Declare a follow for a show, or clear a mute. Pass a podcast_id from search_podcasts. A declared follow stays until unfollow_podcast, regardless of fetch activity, and does not use one of the five automatic slots. For a show never fetched, what counts as new starts from its newest episode now. Does not consume credits.
- `get_balance`: Check the current Spoken credit balance, account email, and recent usage for the configured API key. Does not consume credits.
- `get_transcript`: Fetch a podcast episode's transcript as clean Markdown with real speaker names and timestamps. Pass an episode id from search_podcasts. Costs 1 credit on the first fetch of an episode; repeat fetches are free and errors are never charged.
- `list_episodes`: List a podcast's entire back-catalog (every episode, newest first). Pass a podcast_id from a search_podcasts result. Returns each episode's id, title, and date — fetch any with get_transcript. Use this to transcribe a whole show. Does not consume credits itself; transcribing the returned episodes costs 1 credit each (repeat fetches are free), so make sure the key has enough credits before looping.
- `list_following`: The shows this key is kept current on. Every charged fetch makes its show a follow: the five most-fetched shows from the last 180 days are followed automatically (source 'fetch'), and up to 25 more can be declared with follow_podcast (source 'explicit'). Muted shows are listed separately. Use list_new_episodes to see what is new on them. Does not consume credits; the demo key has nothing to follow with.
- `list_new_episodes`: What is new on the shows this key follows: for each show, the episodes released in the last 90 days that are newer than the newest one already fetched from it (up to 10 per show), each with a transcript_url. Episodes with no transcript are left out. Fetch any with get_transcript (1 credit each on first fetch); a fetch raises that show's floor, so the next call lists only what came after. Refreshed hourly, so a show followed moments ago may be empty until its first poll. Does not consume credits.
- `search_podcasts`: Search published podcast episodes by text query, or paste an episode URL (Spotify, YouTube, etc.). Returns matching episodes with their id, title, podcast, podcast_id, and date. Use the id with get_transcript, or the podcast_id with list_episodes to get the show's whole back-catalog. Does not consume credits.
- `unfollow_podcast`: Mute a show: it leaves the followed list and later fetches do not re-add it. follow_podcast reverses it. Pass a podcast_id from list_following. Does not consume credits.
