{
  "markdown": "<div align=\"center\">\n\n# Transistor MCP Server\n\nAn MCP server for the [Transistor.fm](https://transistor.fm/) API. Manage podcasts, episodes, analytics, transcripts, and webhooks from your AI agent.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](LICENSE)\n[![Language: TypeScript](https://img.shields.io/badge/TypeScript-3178c6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![MCP](https://img.shields.io/badge/MCP-Model_Context_Protocol-1f6feb?style=flat-square)](https://modelcontextprotocol.io/)\n[![Podcast](https://img.shields.io/badge/Podcast-Chain_of_Thought-purple?style=flat-square)](https://chainofthought.show)\n[![X](https://img.shields.io/badge/X-@ConorBronsdon-black?style=flat-square&logo=x)](https://x.com/ConorBronsdon)\n\n</div>\n\n---\n\n> [!IMPORTANT]\n> **Transistor now ships an official MCP server: [mcp.transistor.fm](https://mcp.transistor.fm).** It's remote (no install), authenticates with OAuth instead of an API key, and is maintained by the Transistor team as the basis for their upcoming API v2. For most people it's the better choice — start there.\n>\n> With the official server available, this community server is **no longer actively maintained**. It still works, and it remains useful if you specifically want a local, API-key-based server (for example, in headless or automated environments where an OAuth browser flow is awkward). Bug-fix PRs are welcome; feature requests are better directed at the official server.\n\n![Demo: get_episode tool call and response](docs/demo.gif)\n\nThis MCP server provides tools to interact with the [Transistor.fm](https://transistor.fm/) API, allowing you to manage podcasts, episodes, and view analytics. The data shown in the demo above is sample data, not real account values.\n\n> **Fork notice:** The original server was built by [Guido X Jansen](https://github.com/gxjansen) ([gxjansen/Transistor-MCP](https://github.com/gxjansen/Transistor-MCP)). The full-API-parity pass (all documented params, response trimming, search), the `get_download_summary` and `compare_episodes` analytics tools, ISO date handling, and transcript support were contributed here and have since been merged upstream. This repository is a packaged, npm-published build (`transistor-mcp`). The MIT license and original copyright are preserved in [LICENSE](LICENSE).\n\n<a href=\"https://glama.ai/mcp/servers/conorbronsdon/Transistor-MCP\">\n  <img width=\"380\" height=\"200\" src=\"https://glama.ai/mcp/servers/conorbronsdon/Transistor-MCP/badge\" alt=\"Transistor-MCP MCP server\" />\n</a>\n\n## About\n\nBuilt by [Conor Bronsdon](https://github.com/conorbronsdon) for the [Chain of Thought](https://chainofthought.show) podcast production workflow, where it handled episode creation, transcript uploads, and analytics pulls before the official server shipped. Conor hosts Chain of Thought, a show about AI infrastructure and how practitioners actually build with it. More tools for creators live in [ai-tools-for-creators](https://github.com/conorbronsdon/ai-tools-for-creators). Find Conor on X at [@ConorBronsdon](https://x.com/ConorBronsdon).\n\n**Companion tools:**\n- [substack-mcp](https://github.com/conorbronsdon/substack-mcp): read posts and manage Substack drafts\n- [podcastindex-mcp](https://github.com/conorbronsdon/podcastindex-mcp): search the Podcast Index and track guest appearances\n- [op3-mcp](https://github.com/conorbronsdon/op3-mcp): report downloads, listener geography, and apps from OP3\n- [apple-podcasts-mcp](https://github.com/conorbronsdon/apple-podcasts-mcp): pull plays, followers, and per-episode listening from Apple Podcasts Connect\n- [gsc-mcp](https://github.com/conorbronsdon/gsc-mcp): query search performance, keywords, and sitemaps in Google Search Console\n- [podcast-benchmark](https://github.com/conorbronsdon/podcast-benchmark): benchmark a show against its peers using only public data\n\n## Configuration\n\n**Prefer the official server?** No install needed. Add it to Claude Code with:\n\n```bash\nclaude mcp add --transport http transistor https://mcp.transistor.fm\n```\n\nThen run `/mcp` to sign in to Transistor. Other MCP clients that support remote servers with OAuth can point at `https://mcp.transistor.fm` directly.\n\n**To run this community server instead**, add it to your MCP settings configuration file with your Transistor API key:\n\n```json\n{\n  \"mcpServers\": {\n    \"transistor\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"transistor-mcp\"],\n      \"env\": {\n        \"TRANSISTOR_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\nOr run from a local clone (after `npm install && npm run build`):\n\n```json\n{\n  \"mcpServers\": {\n    \"transistor\": {\n      \"command\": \"node\",\n      \"args\": [\"path/to/Transistor-MCP/build/index.js\"],\n      \"env\": {\n        \"TRANSISTOR_API_KEY\": \"your-api-key-here\"\n      }\n    }\n  }\n}\n```\n\n## Available Tools\n\n### get_authenticated_user\nGet details of the authenticated user account.\n\n```json\n{\n  // No parameters needed\n}\n```\n\n### authorize_upload\nGet a pre-signed URL for uploading an audio file. Use this before creating an episode with a local audio file.\n\n```json\n{\n  \"filename\": string  // Required: Name of the audio file to upload\n}\n```\n\nResponse includes:\n- upload_url: Pre-signed S3 URL for uploading the file\n- content_type: Content type to use when uploading (e.g., \"audio/mpeg\")\n- expires_in: Time in seconds until the upload URL expires\n- audio_url: Final URL to use when creating the episode\n\n### list_shows\nList all shows in your Transistor.fm account, ordered by updated date (newest first). Returns a paginated list with 10 items per page.\n\n```json\n{\n  \"page\": number,     // Optional, defaults to 0 (first page)\n  \"per\": number,      // Optional, defaults to 10 items per page\n  \"private\": boolean, // Optional: filter for private shows\n  \"query\": string     // Optional: search query\n}\n```\n\nNote: All parameters are optional. Calling this endpoint without parameters will return the first page of shows.\n\n### list_episodes\nList episodes for a specific show.\n\n```json\n{\n  \"show_id\": string,  // Required\n  \"page\": number,     // Optional, defaults to 0\n  \"per\": number,      // Optional, defaults to 10\n  \"query\": string,    // Optional: search query\n  \"status\": string,   // Optional: \"published\", \"draft\", or \"scheduled\"\n  \"order\": string     // Optional: \"desc\" (newest first) or \"asc\" (oldest first), defaults to \"desc\"\n}\n```\n\n### get_episode\nGet detailed information about a specific episode.\n\n```json\n{\n  \"episode_id\": string,           // Required\n  \"include\": string[],           // Optional: array of related resources to include\n  \"fields\": {                    // Optional: sparse fieldsets\n    \"episode\": string[],         // Fields to include for episode\n    \"show\": string[]            // Fields to include for show\n  }\n}\n```\n\n### get_analytics\nGet analytics for a show or specific episode. Defaults to the last 14 days if no dates are provided.\n\n```json\n{\n  \"show_id\": string,            // Required\n  \"episode_id\": string,         // Optional: include for episode-specific analytics\n  \"start_date\": string,         // Optional: format \"dd-mm-yyyy\", required if end_date is provided\n  \"end_date\": string           // Optional: format \"dd-mm-yyyy\", required if start_date is provided\n}\n```\n\n### create_episode\nCreate a new episode.\n\n```json\n{\n  \"show_id\": string,               // Required\n  \"title\": string,                 // Required\n  \"audio_url\": string,             // Required\n  \"summary\": string,               // Optional\n  \"description\": string,           // Optional: may contain HTML\n  \"transcript_text\": string,       // Optional: full episode transcript\n  \"author\": string,               // Optional\n  \"explicit\": boolean,            // Optional\n  \"image_url\": string,            // Optional: episode artwork\n  \"keywords\": string,             // Optional: comma-separated list\n  \"number\": number,               // Optional: episode number\n  \"season_number\": number,        // Optional\n  \"type\": string,                // Optional: \"full\", \"trailer\", or \"bonus\"\n  \"alternate_url\": string,       // Optional: override share_url\n  \"video_url\": string,           // Optional: YouTube URL\n  \"email_notifications\": boolean, // Optional: override show setting\n  \"increment_number\": boolean     // Optional: auto-set next episode number\n}\n```\n\n### update_episode\nUpdate an existing episode.\n\n```json\n{\n  \"episode_id\": string,           // Required\n  \"title\": string,               // Optional\n  \"summary\": string,             // Optional\n  \"description\": string,         // Optional: may contain HTML\n  \"transcript_text\": string,     // Optional: full episode transcript\n  \"author\": string,             // Optional\n  \"explicit\": boolean,          // Optional\n  \"image_url\": string,          // Optional: episode artwork\n  \"keywords\": string,           // Optional: comma-separated list\n  \"number\": number,             // Optional: episode number\n  \"season_number\": number,      // Optional\n  \"type\": string,              // Optional: \"full\", \"trailer\", or \"bonus\"\n  \"alternate_url\": string,     // Optional: override share_url\n  \"video_url\": string,         // Optional: YouTube URL\n  \"email_notifications\": boolean // Optional: override show setting\n}\n```\n\n### get_all_episode_analytics\nGet analytics for all episodes of a show. Defaults to the last 7 days if no dates are provided.\n\n```json\n{\n  \"show_id\": string,            // Required\n  \"start_date\": string,         // Optional: format \"dd-mm-yyyy\", required if end_date is provided\n  \"end_date\": string           // Optional: format \"dd-mm-yyyy\", required if start_date is provided\n}\n```\n\n### list_webhooks\nList all webhooks for a show.\n\n```json\n{\n  \"show_id\": string            // Required\n}\n```\n\n### subscribe_webhook\nSubscribe to a webhook for a show.\n\n```json\n{\n  \"event_name\": string,        // Required: e.g., \"episode_created\"\n  \"show_id\": string,          // Required\n  \"url\": string              // Required: URL to receive webhook events\n}\n```\n\n### unsubscribe_webhook\nUnsubscribe from a webhook.\n\n```json\n{\n  \"webhook_id\": string        // Required\n}\n```\n\n### Typed errors\n\nTool calls that fail against the Transistor.fm API return a status-specific,\nhuman-readable message via `isError: true` rather than a generic Axios error.\nInternally, `TransistorApiClient` maps every HTTP failure — authentication\n(401/403), rate limiting (429), validation (400), not found (404), and\nserver errors (5xx) — to a typed error class in a single response\ninterceptor (see `src/errors.ts`), so the message you see always names the\nfailure mode and, for auth errors, points at the `TRANSISTOR_API_KEY`\nenvironment variable.\n\n## Important Notes\n\n- API requests are rate-limited to 10 requests per 10 seconds (as prescribed by the (https://developers.transistor.fm/#:~:text=API%20requests%20are%20rate%2Dlimited,to%20use%20the%20API%20again.)[Transistor API reference])\n- Dates must be in \"dd-mm-yyyy\" format\n- Page numbers start at 0\n- All endpoints support:\n  - Sparse fieldsets: Specify which fields to return using `fields[resource_type][]`\n  - Including related resources: Use `include[]` to fetch related resources in a single request\n- Include arrays use the format `[\"resource_name\"]`\n- Fields objects specify which fields to return for each resource type\n- All tools return data in JSONAPI format with proper relationships and metadata\n\n## Example Usage\n\nList shows:\n```typescript\n// List first page of shows (default behavior)\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"list_shows\",\n  arguments: {}\n});\n\n// List shows with pagination and filtering\nconst resultWithParams = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"list_shows\",\n  arguments: {\n    page: 1,\n    per: 20,\n    private: true,\n    query: \"podcast\"\n  }\n});\n```\n\nGet episode details:\n```typescript\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_episode\",\n  arguments: {\n    episode_id: \"123456\",\n    include: [\"show\"],\n    fields: {\n      episode: [\"title\", \"summary\", \"description\"],\n      show: [\"title\"]\n    }\n  }\n});\n```\n\nGet show analytics:\n```typescript\n// Get analytics for the last 14 days (default behavior)\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_analytics\",\n  arguments: {\n    show_id: \"123456\"\n  }\n});\n\n// Get analytics for a specific date range\nconst resultWithDates = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_analytics\",\n  arguments: {\n    show_id: \"123456\",\n    start_date: \"01-01-2024\",\n    end_date: \"31-01-2024\"\n  }\n});\n\n// Get analytics for a specific episode\nconst episodeAnalytics = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_analytics\",\n  arguments: {\n    show_id: \"123456\",\n    episode_id: \"789012\",\n    start_date: \"01-01-2024\",\n    end_date: \"31-01-2024\"\n  }\n});\n```\n\nUpdate episode:\n```typescript\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"update_episode\",\n  arguments: {\n    episode_id: \"123456\",\n    title: \"Updated Episode Title\",\n    summary: \"New episode summary\",\n    description: \"New detailed description\",\n    season_number: 2,\n    episode_number: 5\n  }\n});\n```\n\nGet all episode analytics:\n```typescript\n// Get analytics for all episodes for the last 7 days (default behavior)\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_all_episode_analytics\",\n  arguments: {\n    show_id: \"123456\"\n  }\n});\n\n// Get analytics for all episodes for a specific date range\nconst resultWithDates = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_all_episode_analytics\",\n  arguments: {\n    show_id: \"123456\",\n    start_date: \"01-01-2024\",\n    end_date: \"31-01-2024\"\n  }\n});\n```\n\nManage webhooks:\n```typescript\n// List webhooks\nconst webhooks = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"list_webhooks\",\n  arguments: {\n    show_id: \"123456\"\n  }\n});\n\n// Subscribe to webhook\nconst subscription = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"subscribe_webhook\",\n  arguments: {\n    event_name: \"episode_created\",\n    show_id: \"123456\",\n    url: \"https://your-webhook-endpoint.com/hook\"\n  }\n});\n\n// Unsubscribe from webhook\nconst unsubscribe = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"unsubscribe_webhook\",\n  arguments: {\n    webhook_id: \"webhook123\"\n  }\n});\n```\n\nGet authenticated user:\n```typescript\nconst result = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"get_authenticated_user\",\n  arguments: {}\n});\n```\n\nAuthorize audio file upload:\n```typescript\n// First, get a pre-signed upload URL\nconst auth = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"authorize_upload\",\n  arguments: {\n    filename: \"my-episode.mp3\"\n  }\n});\n\n// Then use the returned upload_url to upload your file via PUT request\n// Finally, use the returned audio_url when creating your episode:\nconst episode = await use_mcp_tool({\n  server_name: \"transistor\",\n  tool_name: \"create_episode\",\n  arguments: {\n    show_id: \"123456\",\n    title: \"My New Episode\",\n    audio_url: auth.data.attributes.audio_url\n  }\n});\n```\n\n### publish_episode\nPublish, schedule, or unpublish an episode.\n\n```json\n{\n  \"episode_id\": string,          // Required\n  \"status\": string,              // Required: \"published\", \"scheduled\", or \"draft\"\n  \"published_at\": string         // Optional: date/time in the podcast's time zone (required for \"scheduled\")\n}\n```\n\n### get_show\nGet details of a single show.\n\n```json\n{\n  \"show_id\": string              // Required\n}\n```\n\n### update_show\nUpdate a show's metadata.\n\n```json\n{\n  \"show_id\": string,             // Required\n  \"author\": string,              // Optional\n  \"category\": string,            // Optional: primary podcast category\n  \"copyright\": string,           // Optional\n  \"description\": string,         // Optional\n  \"explicit\": boolean,           // Optional\n  \"image_url\": string,           // Optional: show artwork URL\n  \"keywords\": string,            // Optional: comma-separated\n  \"language\": string,            // Optional: e.g. \"en\"\n  \"owner_email\": string,         // Optional\n  \"secondary_category\": string,  // Optional\n  \"show_type\": string,           // Optional: \"episodic\" or \"serial\"\n  \"title\": string,               // Optional\n  \"time_zone\": string,           // Optional\n  \"website\": string              // Optional\n}\n```\n\n### list_subscribers\nList subscribers for a private podcast.\n\n```json\n{\n  \"show_id\": string,             // Required\n  \"page\": number,                // Optional\n  \"per\": number,                 // Optional\n  \"query\": string                // Optional: search filter\n}\n```\n\n### get_subscriber\nGet details of a single subscriber.\n\n```json\n{\n  \"subscriber_id\": string        // Required\n}\n```\n\n### create_subscriber\nAdd a subscriber to a private podcast.\n\n```json\n{\n  \"show_id\": string,             // Required\n  \"email\": string,               // Required\n  \"skip_welcome_email\": boolean  // Optional (default false)\n}\n```\n\n### create_subscribers_batch\nAdd multiple subscribers at once.\n\n```json\n{\n  \"show_id\": string,             // Required\n  \"emails\": string[],            // Required: array of email addresses\n  \"skip_welcome_email\": boolean  // Optional (default false)\n}\n```\n\n### update_subscriber\nUpdate a subscriber's email address.\n\n```json\n{\n  \"subscriber_id\": string,       // Required\n  \"email\": string                // Required: new email address\n}\n```\n\n### delete_subscriber\nDelete a subscriber by ID or by show + email.\n\n```json\n{\n  \"subscriber_id\": string,       // Optional: delete by subscriber ID\n  \"show_id\": string,             // Optional: use with email instead of subscriber_id\n  \"email\": string                // Optional: use with show_id instead of subscriber_id\n}\n```\n\n## Contributing\n\nThis server is in maintenance mode now that [the official Transistor MCP](https://mcp.transistor.fm) exists. Bug reports and bug-fix PRs are still welcome: open an issue with the tool name and the request you were trying to make, or fork the repo, run `npm install && npm run build`, and open a PR describing what changed and why. New-feature requests are better directed at the official server, which Transistor is actively developing.\n\n---\n\n## Disclaimer\n\n*All views, opinions, and statements expressed on this account are solely my own and are made in my personal capacity. They do not reflect, and should not be construed as reflecting, the views, positions, or policies of Modular. This account is not affiliated with, authorized by, or endorsed by Modular in any way.*\n\n## License\n\nMIT. This is a fork of [gxjansen/Transistor-MCP](https://github.com/gxjansen/Transistor-MCP); the original copyright by Guido X Jansen is preserved in [LICENSE](LICENSE).\n",
  "bytes": 18839,
  "sha": "3117d9582a334eec6afe74139e2a8f680372c86886ed564c229d1c78845818c6",
  "repo_slug": "conorbronsdon/transistor-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_conorbronsdon_transistor_mcp_becd5027/readme"
}