vibo-mcp 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "MCP server for Vibo (vibodj.com) — plan & manage event music, song requests, ideas, guests, and playlists via natural language",
10
- "version": "1.5.0"
10
+ "version": "1.5.2"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "Vibo",
16
16
  "source": "./",
17
17
  "description": "MCP server for Vibo — browse & manage events, timeline, songs, the DJ song ideas/questions, guests, and exports to Spotify/Apple Music",
18
- "version": "1.5.0",
18
+ "version": "1.5.2",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibo-mcp",
3
3
  "displayName": "Vibo",
4
- "version": "1.5.0",
4
+ "version": "1.5.2",
5
5
  "description": "MCP server for Vibo (vibodj.com) — plan & manage event music, song requests, ideas, guests, and playlists via natural language",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/bundle.js CHANGED
@@ -23048,17 +23048,33 @@ function normalizeObjectSchema(schema) {
23048
23048
  }
23049
23049
  return void 0;
23050
23050
  }
23051
+ function getDotPath(path) {
23052
+ if (path.length === 0) {
23053
+ return "object root";
23054
+ }
23055
+ return path.reduce((acc, seg, index) => {
23056
+ if (index === 0) {
23057
+ return String(seg);
23058
+ }
23059
+ if (typeof seg === "number") {
23060
+ return `${acc}[${seg}]`;
23061
+ }
23062
+ return `${acc}.${seg}`;
23063
+ }, "");
23064
+ }
23051
23065
  function getParseErrorMessage(error51) {
23052
23066
  if (error51 && typeof error51 === "object") {
23067
+ if ("issues" in error51 && Array.isArray(error51.issues) && error51.issues.length > 0) {
23068
+ return error51.issues.map((i) => {
23069
+ if (!i.path?.length) {
23070
+ return i.message;
23071
+ }
23072
+ return `${i.message} at ${getDotPath(i.path)}`;
23073
+ }).join("\n");
23074
+ }
23053
23075
  if ("message" in error51 && typeof error51.message === "string") {
23054
23076
  return error51.message;
23055
23077
  }
23056
- if ("issues" in error51 && Array.isArray(error51.issues) && error51.issues.length > 0) {
23057
- const firstIssue = error51.issues[0];
23058
- if (firstIssue && typeof firstIssue === "object" && "message" in firstIssue) {
23059
- return String(firstIssue.message);
23060
- }
23061
- }
23062
23078
  try {
23063
23079
  return JSON.stringify(error51);
23064
23080
  } catch {
@@ -29673,16 +29689,7 @@ var Server = class extends Protocol {
29673
29689
  if (!methodSchema) {
29674
29690
  throw new Error("Schema is missing a method literal");
29675
29691
  }
29676
- let methodValue;
29677
- if (isZ4Schema(methodSchema)) {
29678
- const v4Schema = methodSchema;
29679
- const v4Def = v4Schema._zod?.def;
29680
- methodValue = v4Def?.value ?? v4Schema.value;
29681
- } else {
29682
- const v3Schema = methodSchema;
29683
- const legacyDef = v3Schema._def;
29684
- methodValue = legacyDef?.value ?? v3Schema.value;
29685
- }
29692
+ const methodValue = getLiteralValue(methodSchema);
29686
29693
  if (typeof methodValue !== "string") {
29687
29694
  throw new Error("Schema method literal must be a string");
29688
29695
  }
@@ -30870,8 +30877,17 @@ var EMPTY_COMPLETION_RESULT = {
30870
30877
  import process3 from "node:process";
30871
30878
 
30872
30879
  // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
30880
+ var STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
30873
30881
  var ReadBuffer = class {
30882
+ constructor(options) {
30883
+ this._maxBufferSize = options?.maxBufferSize ?? STDIO_DEFAULT_MAX_BUFFER_SIZE;
30884
+ }
30874
30885
  append(chunk) {
30886
+ const newSize = (this._buffer?.length ?? 0) + chunk.length;
30887
+ if (newSize > this._maxBufferSize) {
30888
+ this.clear();
30889
+ throw new Error(`ReadBuffer exceeded maximum size of ${this._maxBufferSize} bytes`);
30890
+ }
30875
30891
  this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
30876
30892
  }
30877
30893
  readMessage() {
@@ -30899,18 +30915,24 @@ function serializeMessage(message) {
30899
30915
 
30900
30916
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
30901
30917
  var StdioServerTransport = class {
30902
- constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
30918
+ constructor(_stdin = process3.stdin, _stdout = process3.stdout, options) {
30903
30919
  this._stdin = _stdin;
30904
30920
  this._stdout = _stdout;
30905
- this._readBuffer = new ReadBuffer();
30906
30921
  this._started = false;
30907
30922
  this._ondata = (chunk) => {
30908
- this._readBuffer.append(chunk);
30909
- this.processReadBuffer();
30923
+ try {
30924
+ this._readBuffer.append(chunk);
30925
+ this.processReadBuffer();
30926
+ } catch (error51) {
30927
+ this.onerror?.(error51);
30928
+ this.close().catch(() => {
30929
+ });
30930
+ }
30910
30931
  };
30911
30932
  this._onerror = (error51) => {
30912
30933
  this.onerror?.(error51);
30913
30934
  };
30935
+ this._readBuffer = new ReadBuffer({ maxBufferSize: options?.maxBufferSize });
30914
30936
  }
30915
30937
  /**
30916
30938
  * Starts listening for messages on stdin.
@@ -31126,7 +31148,7 @@ function toolAnnotations(opts = {}) {
31126
31148
  }
31127
31149
 
31128
31150
  // src/version.ts
31129
- var VERSION = "1.5.0";
31151
+ var VERSION = "1.5.2";
31130
31152
 
31131
31153
  // src/client.ts
31132
31154
  import { dirname as dirname2, join as join2 } from "path";
@@ -32136,12 +32158,11 @@ function streamingLinkCount(links) {
32136
32158
  (l) => typeof l === "string" && l.length > 0
32137
32159
  ).length;
32138
32160
  }
32139
- function soundcloudHandleMatchesArtist(url2, artist) {
32161
+ function soundcloudHandleIsConsistentWith(url2, artist) {
32140
32162
  const path = url2.replace(/^https?:\/\/(www\.)?soundcloud\.com\//i, "").split("/")[0] ?? "";
32141
32163
  const handle = normalizeName(path).split(" ").join("");
32142
- if (!handle) return false;
32143
32164
  const tokens = normalizeName(artist).split(" ").filter((t) => t.length >= 4);
32144
- if (!tokens.length) return false;
32165
+ if (!handle || !tokens.length) return true;
32145
32166
  return tokens.some((t) => handle.includes(t));
32146
32167
  }
32147
32168
  function assessSong(song, intended) {
@@ -32187,7 +32208,7 @@ function assessSong(song, intended) {
32187
32208
  }
32188
32209
  const soundcloud = song.links?.soundcloud;
32189
32210
  const artistForHandle = isJunkArtist ? intended?.artist : artist || intended?.artist;
32190
- if (soundcloud && artistForHandle && !soundcloudHandleMatchesArtist(soundcloud, artistForHandle)) {
32211
+ if (soundcloud && artistForHandle && !soundcloudHandleIsConsistentWith(soundcloud, artistForHandle)) {
32191
32212
  warnings.push(`SoundCloud handle does not obviously belong to "${artistForHandle}".`);
32192
32213
  }
32193
32214
  const confidence = hard ? "likely-not-original" : warnings.length ? "uncertain" : "likely-original";
@@ -127,21 +127,24 @@ function streamingLinkCount(links) {
127
127
  return [links.spotify, links.appleMusic, links.tidal, links.deezer, links.soundcloud].filter((l) => typeof l === 'string' && l.length > 0).length;
128
128
  }
129
129
  /**
130
- * True when a SoundCloud URL's handle plausibly belongs to `artist` — i.e. the
131
- * handle contains one of the artist's substantial name tokens. Deliberately
132
- * loose: `soundcloud.com/elvissonymusic/...` counts for Elvis Presley (a label
133
- * account), while `soundcloud.com/jen-prince-602192391/...` does not.
130
+ * True when a SoundCloud URL's handle is consistent with `artist` — i.e. the
131
+ * handle contains one of the artist's substantial name tokens, *or* the check
132
+ * cannot be run at all. Deliberately loose: `soundcloud.com/elvissonymusic/...`
133
+ * counts for Elvis Presley (a label account), while
134
+ * `soundcloud.com/jen-prince-602192391/...` does not.
134
135
  */
135
- function soundcloudHandleMatchesArtist(url, artist) {
136
+ function soundcloudHandleIsConsistentWith(url, artist) {
136
137
  const path = url.replace(/^https?:\/\/(www\.)?soundcloud\.com\//i, '').split('/')[0] ?? '';
137
138
  const handle = normalizeName(path).split(' ').join('');
138
- if (!handle)
139
- return false;
140
139
  const tokens = normalizeName(artist)
141
140
  .split(' ')
142
141
  .filter((t) => t.length >= 4);
143
- if (!tokens.length)
144
- return false;
142
+ // Nothing to compare — an unparseable handle, or an artist whose every name
143
+ // token is too short to match on without hitting noise ("Sia", "SZA", "U2",
144
+ // "Nas"). Abstain rather than accuse: this is a soft signal, and a check that
145
+ // cannot run is not evidence against the result.
146
+ if (!handle || !tokens.length)
147
+ return true;
145
148
  return tokens.some((t) => handle.includes(t));
146
149
  }
147
150
  /**
@@ -197,7 +200,7 @@ export function assessSong(song, intended) {
197
200
  // Soft signal: only checkable when a SoundCloud link is present.
198
201
  const soundcloud = song.links?.soundcloud;
199
202
  const artistForHandle = isJunkArtist ? intended?.artist : artist || intended?.artist;
200
- if (soundcloud && artistForHandle && !soundcloudHandleMatchesArtist(soundcloud, artistForHandle)) {
203
+ if (soundcloud && artistForHandle && !soundcloudHandleIsConsistentWith(soundcloud, artistForHandle)) {
201
204
  warnings.push(`SoundCloud handle does not obviously belong to "${artistForHandle}".`);
202
205
  }
203
206
  const confidence = hard
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  // literal on the line carrying the release marker; every manifest and the MCP
3
3
  // server banner import VERSION from here, so there is exactly one place to keep
4
4
  // in sync (and one release-please extra-files entry).
5
- export const VERSION = '1.5.0'; // x-release-please-version
5
+ export const VERSION = '1.5.2'; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibo-mcp",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "mcpName": "io.github.chrischall/vibo-mcp",
5
5
  "description": "Vibo (vibodj.com) MCP server for Claude — host/couple event music planning & management. Developed and maintained by AI (Claude Code).",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -44,11 +44,12 @@
44
44
  "test:coverage": "vitest run --coverage",
45
45
  "worker:dev": "wrangler dev",
46
46
  "worker:deploy": "wrangler deploy",
47
+ "worker:typecheck": "tsc --noEmit -p tsconfig.worker.json",
47
48
  "worker:test": "vitest run --config vitest.workers.config.ts"
48
49
  },
49
50
  "dependencies": {
50
- "@chrischall/mcp-utils": "^0.13.1",
51
- "@fetchproxy/bootstrap": "^1.3.4",
51
+ "@chrischall/mcp-utils": "^0.14.0",
52
+ "@fetchproxy/bootstrap": "^1.7.0",
52
53
  "@modelcontextprotocol/sdk": "^1.29.0",
53
54
  "dotenv": "^17.4.0",
54
55
  "zod": "^4.4.2"
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/vibo-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.5.0",
9
+ "version": "1.5.2",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "vibo-mcp",
14
- "version": "1.5.0",
14
+ "version": "1.5.2",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },