🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

transistor-mcp

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

transistor-mcp - npm Package Compare versions

Comparing version
0.2.0
to
0.3.0
+4
-1
build/api-client.js

@@ -186,3 +186,6 @@ import axios from "axios";

}
// Delete by show_id + email
// Delete by show_id + email — both are required for this branch.
if (!args.show_id || !args.email) {
throw new Error("delete_subscriber requires either subscriber_id, or both show_id and email.");
}
const response = await this.api.delete("/v1/subscribers", {

@@ -189,0 +192,0 @@ params: { show_id: args.show_id, email: args.email },

+21
-3

@@ -11,5 +11,18 @@ /**

/**
* Verify that y/m/d form a real calendar date (e.g. reject 2025-13-40 or
* 2025-02-30). Returns true only when the numbers round-trip through Date.
*/
function isRealDate(year, month, day) {
if (month < 1 || month > 12 || day < 1 || day > 31)
return false;
const d = new Date(Date.UTC(year, month - 1, day));
return (d.getUTCFullYear() === year &&
d.getUTCMonth() === month - 1 &&
d.getUTCDate() === day);
}
/**
* Convert a date string to Transistor's dd-mm-yyyy format.
* Accepts either ISO (yyyy-mm-dd) or already-correct (dd-mm-yyyy).
* Returns undefined for undefined input.
* Throws on a syntactically-ISO string that is not a real calendar date.
*/

@@ -20,7 +33,12 @@ export function toTransistorDate(date) {

if (ISO_DATE_RE.test(date)) {
const [year, month, day] = date.split("-");
return `${day}-${month}-${year}`;
const [year, month, day] = date.split("-").map(Number);
if (!isRealDate(year, month, day)) {
throw new Error(`Invalid date "${date}": expected a real calendar date in yyyy-mm-dd format.`);
}
const [y, m, d] = date.split("-");
return `${d}-${m}-${y}`;
}
if (TRANSISTOR_DATE_RE.test(date)) {
// Already in Transistor format
// Already in Transistor dd-mm-yyyy format (ambiguous: dd-mm vs mm-dd is
// not validated here — passed through and resolved server-side).
return date;

@@ -27,0 +45,0 @@ }

@@ -6,2 +6,14 @@ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";

/**
* Extract a concise, human-readable message from an unknown thrown value,
* preferring the Transistor API's status/message when it is an Axios error.
*/
function errorMessage(e) {
if (axios.isAxiosError(e)) {
const status = e.response?.status;
const apiMsg = e.response?.data?.error ?? e.message;
return status ? `HTTP ${status}: ${apiMsg}` : apiMsg;
}
return e instanceof Error ? e.message : String(e);
}
/**
* Strip heavy fields from episode responses to reduce token usage.

@@ -992,4 +1004,7 @@ * Removes HTML descriptions, embed codes, and formatted variants

if (days.length >= 14) {
const lastWeek = days.slice(-7);
const prevWeek = days.slice(-14, -7);
// Sort chronologically before slicing — the API does not guarantee
// ordering, and ISO yyyy-mm-dd strings sort lexicographically by date.
const byDate = [...days].sort((a, b) => a.date.localeCompare(b.date));
const lastWeek = byDate.slice(-7);
const prevWeek = byDate.slice(-14, -7);
const lastTotal = lastWeek.reduce((s, d) => s + d.downloads, 0);

@@ -1025,3 +1040,5 @@ const prevTotal = prevWeek.reduce((s, d) => s + d.downloads, 0);

const results = await Promise.all(args.episode_ids.map(async (episode_id) => {
// Fetch analytics and episode metadata in parallel
// Fetch analytics and episode metadata in parallel. Capture failures
// per-episode so one bad episode does not abort the whole comparison,
// but surface the error instead of silently reporting zero downloads.
const [analyticsData, episodeData] = await Promise.all([

@@ -1035,3 +1052,3 @@ this.apiClient

})
.catch(() => null),
.catch((e) => ({ __error: errorMessage(e) })),
this.apiClient

@@ -1041,5 +1058,8 @@ .getEpisode({ episode_id })

]);
const days = analyticsData
? this.extractDownloads(analyticsData)
: [];
const analyticsError = analyticsData && typeof analyticsData === "object" && "__error" in analyticsData
? analyticsData.__error
: null;
const days = analyticsError
? []
: this.extractDownloads(analyticsData);
const total = days.reduce((s, d) => s + d.downloads, 0);

@@ -1068,2 +1088,3 @@ const avg = days.length > 0 ? total / days.length : 0;

days_since_publish: daysSincePublish,
...(analyticsError ? { error: analyticsError } : {}),
};

@@ -1070,0 +1091,0 @@ }));

{
"name": "transistor-mcp",
"version": "0.2.0",
"description": "MCP server for the Transistor.fm podcast hosting API — manage shows, episodes, analytics, download summaries, transcripts, subscribers, and webhooks.",
"version": "0.3.0",
"description": "MCP server for the Transistor.fm podcast hosting API \u2014 manage shows, episodes, analytics, download summaries, transcripts, subscribers, and webhooks.",
"type": "module",

@@ -45,4 +45,5 @@ "mcpName": "io.github.conorbronsdon/transistor-mcp",

"dependencies": {
"@modelcontextprotocol/sdk": "0.6.0",
"axios": "^1.7.9"
"@modelcontextprotocol/sdk": "1.25.2",
"axios": "^1.13.5",
"form-data": "^4.0.4"
},

@@ -49,0 +50,0 @@ "devDependencies": {

@@ -21,4 +21,8 @@ <div align="center">

> **Fork notice:** This is a maintained fork of [gxjansen/Transistor-MCP](https://github.com/gxjansen/Transistor-MCP) by [Guido X Jansen](https://github.com/gxjansen), who built the original server. This fork adds full API parity (all documented params, response trimming, search), the `get_download_summary` and `compare_episodes` tools, ISO date handling, and transcript support. The MIT license and original copyright are preserved in [LICENSE](LICENSE).
> **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`) kept in sync with upstream. The MIT license and original copyright are preserved in [LICENSE](LICENSE).
<a href="https://glama.ai/mcp/servers/conorbronsdon/Transistor-MCP">
<img width="380" height="200" src="https://glama.ai/mcp/servers/conorbronsdon/Transistor-MCP/badge" alt="Transistor-MCP MCP server" />
</a>
## About

@@ -25,0 +29,0 @@