@chrischall/eventbrite-mcp 1.0.0 → 1.1.0

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 Eventbrite — your tickets and orders, organizer data, and public event discovery",
10
- "version": "1.0.0"
10
+ "version": "1.1.0"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "Eventbrite",
16
16
  "source": "./",
17
17
  "description": "MCP server for Eventbrite — tickets, orders, organizer data, and public event search. Account tools use a personal API token; discovery search routes through the user's signed-in eventbrite.com tab via the fetchproxy bridge, reusing their authenticated session.",
18
- "version": "1.0.0",
18
+ "version": "1.1.0",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eventbrite-mcp",
3
3
  "displayName": "Eventbrite",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "description": "MCP server for Eventbrite — your tickets and orders, organizer data, and public event discovery",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/bundle.js CHANGED
@@ -52862,24 +52862,10 @@ async function runCredentialHealthcheck(args) {
52862
52862
  };
52863
52863
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
52864
52864
  }
52865
- function registerCredentialHealthcheckTool(args) {
52866
- args.server.registerTool(`${args.prefix}_healthcheck`, {
52867
- title: "Verify credentials and upstream reachability",
52868
- description: `${credentialHealthcheckDescription(args.hostLabel)} Call this when a real tool fails and you want to know which hop broke.`,
52869
- annotations: {
52870
- title: "Verify credentials and upstream reachability",
52871
- readOnlyHint: true,
52872
- idempotentHint: true,
52873
- openWorldHint: true
52874
- },
52875
- inputSchema: external_exports.object({})
52876
- }, async () => runCredentialHealthcheck(args));
52877
- }
52878
52865
  var CREDENTIAL_ARMS;
52879
52866
  var init_healthcheck = __esm({
52880
52867
  "node_modules/@chrischall/mcp-utils/dist/healthcheck/index.js"() {
52881
52868
  init_errors();
52882
- init_zod();
52883
52869
  CREDENTIAL_ARMS = /* @__PURE__ */ new Set([
52884
52870
  "ok",
52885
52871
  "no_credential",
@@ -52925,7 +52911,6 @@ __export(fetchproxy_exports, {
52925
52911
  mapWithConcurrency: () => mapWithConcurrency,
52926
52912
  registerAdaptiveHealthcheckTool: () => registerAdaptiveHealthcheckTool,
52927
52913
  registerBridgeHealthcheckTool: () => registerBridgeHealthcheckTool,
52928
- registerCredentialHealthcheckTool: () => registerCredentialHealthcheckTool,
52929
52914
  retryOnceOnTimeout: () => retryOnceOnTimeout,
52930
52915
  runBridgeHealthcheck: () => runBridgeHealthcheck,
52931
52916
  sleep: () => sleep2,
@@ -53303,7 +53288,6 @@ var init_fetchproxy = __esm({
53303
53288
  init_errors();
53304
53289
  init_dist2();
53305
53290
  init_healthcheck();
53306
- init_healthcheck();
53307
53291
  init_zod();
53308
53292
  PLACEHOLDER_RE2 = /^\$\{[^}]*\}$/;
53309
53293
  SERVER_DEFAULT_FETCH_TIMEOUT_MS = 3e4;
@@ -54485,6 +54469,7 @@ function missingClientCapabilities(required2, declared) {
54485
54469
  return Object.keys(missing).length > 0 ? missing : void 0;
54486
54470
  }
54487
54471
  var FIRST_MODERN_PROTOCOL_VERSION = "2026-07-28";
54472
+ var SUPPORTED_MODERN_PROTOCOL_VERSIONS = [FIRST_MODERN_PROTOCOL_VERSION];
54488
54473
  function isModernProtocolVersion(version2) {
54489
54474
  return version2 >= FIRST_MODERN_PROTOCOL_VERSION;
54490
54475
  }
@@ -57043,6 +57028,25 @@ function isSpecNotificationMethod(method) {
57043
57028
  return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
57044
57029
  }
57045
57030
  var ALL_CODECS = [rev2025Codec, rev2026Codec];
57031
+ function isPlainObject$3(value) {
57032
+ return value !== null && typeof value === "object" && !Array.isArray(value);
57033
+ }
57034
+ function requestMetaOf(params) {
57035
+ if (!isPlainObject$3(params)) return void 0;
57036
+ const meta3 = params["_meta"];
57037
+ return isPlainObject$3(meta3) ? meta3 : void 0;
57038
+ }
57039
+ function hasEnvelopeClaim(params) {
57040
+ const meta3 = requestMetaOf(params);
57041
+ return meta3 !== void 0 && PROTOCOL_VERSION_META_KEY in meta3;
57042
+ }
57043
+ function envelopeClaimVersion(params) {
57044
+ const value = requestMetaOf(params)?.[PROTOCOL_VERSION_META_KEY];
57045
+ return typeof value === "string" ? value : void 0;
57046
+ }
57047
+ function validateEnvelopeMeta(meta3) {
57048
+ return codecForVersion(MODERN_WIRE_REVISION).validateEnvelopeMeta(meta3);
57049
+ }
57046
57050
  var schemas_exports = /* @__PURE__ */ __exportAll({
57047
57051
  AnnotationsSchema: () => AnnotationsSchema,
57048
57052
  AudioContentSchema: () => AudioContentSchema,
@@ -57393,6 +57397,45 @@ var LADDER_ERROR_HTTP_STATUS = {
57393
57397
  [ProtocolErrorCode.MissingRequiredClientCapability]: 400,
57394
57398
  [HEADER_MISMATCH_ERROR_CODE]: 400
57395
57399
  };
57400
+ function rejection(rung, cell, httpStatus, error62, settled) {
57401
+ return {
57402
+ kind: "reject",
57403
+ rung,
57404
+ cell,
57405
+ httpStatus,
57406
+ code: error62.code,
57407
+ message: error62.message,
57408
+ ...error62.data !== void 0 && { data: error62.data },
57409
+ settled
57410
+ };
57411
+ }
57412
+ function carriesValidModernEnvelopeClaim(params) {
57413
+ if (!hasEnvelopeClaim(params)) return false;
57414
+ const claimedVersion = envelopeClaimVersion(params);
57415
+ if (claimedVersion === void 0 || !isModernProtocolVersion(claimedVersion)) return false;
57416
+ const meta3 = requestMetaOf(params);
57417
+ return meta3 !== void 0 && validateEnvelopeMeta(meta3).length === 0;
57418
+ }
57419
+ function modernOnlyStrictRejection(route, supportedVersions) {
57420
+ switch (route.reason) {
57421
+ case "http-method":
57422
+ return rejection("http-method", "modern-only-method-not-allowed", 405, new ProtocolError(-32e3, "Method not allowed."), true);
57423
+ case "batch":
57424
+ return rejection("jsonrpc-shape", "modern-only-batch-not-supported", 400, new ProtocolError(ProtocolErrorCode.InvalidRequest, "Bad Request: JSON-RPC batches are not supported by this endpoint"), true);
57425
+ case "response":
57426
+ return rejection("jsonrpc-shape", "modern-only-response-post", 400, new ProtocolError(ProtocolErrorCode.InvalidRequest, "Bad Request: JSON-RPC responses cannot be posted to this endpoint"), true);
57427
+ case "notification":
57428
+ return;
57429
+ case "initialize":
57430
+ case "no-claim": {
57431
+ const requested = route.requestedVersion;
57432
+ return rejection("era-classification", "modern-only-missing-envelope", 400, requested === void 0 ? new ProtocolError(ProtocolErrorCode.UnsupportedProtocolVersion, "Unsupported protocol version: the request did not name a protocol version", { supported: [...supportedVersions] }) : new UnsupportedProtocolVersionError({
57433
+ supported: [...supportedVersions],
57434
+ requested
57435
+ }), true);
57436
+ }
57437
+ }
57438
+ }
57396
57439
  function parseSchema(schema, data) {
57397
57440
  return z2.safeParse(schema, data);
57398
57441
  }
@@ -57954,6 +57997,9 @@ function withRequestStateValue(ctx, value) {
57954
57997
  };
57955
57998
  }
57956
57999
  var writeNegotiatedProtocolVersion;
58000
+ function setNegotiatedProtocolVersion(instance, version2) {
58001
+ writeNegotiatedProtocolVersion(instance, version2);
58002
+ }
57957
58003
  var Protocol = class {
57958
58004
  _transport;
57959
58005
  _requestMessageId = 0;
@@ -65897,6 +65943,190 @@ function getCompleter(schema) {
65897
65943
  return schema[COMPLETABLE_SYMBOL]?.complete;
65898
65944
  }
65899
65945
  var MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
65946
+ function listenFilterAccepts(filter, event) {
65947
+ switch (event.kind) {
65948
+ case "tools_list_changed":
65949
+ return filter.toolsListChanged === true;
65950
+ case "prompts_list_changed":
65951
+ return filter.promptsListChanged === true;
65952
+ case "resources_list_changed":
65953
+ return filter.resourcesListChanged === true;
65954
+ case "resource_updated":
65955
+ return filter.resourceSubscriptions !== void 0 && filter.resourceSubscriptions.includes(event.uri);
65956
+ }
65957
+ }
65958
+ function honoredSubset(requested, capabilities) {
65959
+ const honored = {};
65960
+ const allow = (bit) => capabilities === void 0 || bit === true;
65961
+ if (requested.toolsListChanged === true && allow(capabilities?.tools?.listChanged)) honored.toolsListChanged = true;
65962
+ if (requested.promptsListChanged === true && allow(capabilities?.prompts?.listChanged)) honored.promptsListChanged = true;
65963
+ if (requested.resourcesListChanged === true && allow(capabilities?.resources?.listChanged)) honored.resourcesListChanged = true;
65964
+ if (requested.resourceSubscriptions !== void 0 && requested.resourceSubscriptions.length > 0 && allow(capabilities?.resources?.subscribe)) honored.resourceSubscriptions = [...requested.resourceSubscriptions];
65965
+ return honored;
65966
+ }
65967
+ var DEFAULT_MAX_SUBSCRIPTIONS = 1024;
65968
+ function stampSubscriptionId(notification, subscriptionId) {
65969
+ return {
65970
+ method: notification.method,
65971
+ params: {
65972
+ ...notification.params,
65973
+ _meta: {
65974
+ ...notification.params?._meta,
65975
+ [SUBSCRIPTION_ID_META_KEY]: subscriptionId
65976
+ }
65977
+ }
65978
+ };
65979
+ }
65980
+ function parseListenFilter(message) {
65981
+ const outcome = codecForVersion(MODERN_WIRE_REVISION).validateRequest("subscriptions/listen", message);
65982
+ return outcome.ok ? outcome.value.params?.notifications : void 0;
65983
+ }
65984
+ var CHANGE_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
65985
+ "notifications/tools/list_changed",
65986
+ "notifications/prompts/list_changed",
65987
+ "notifications/resources/list_changed",
65988
+ "notifications/resources/updated"
65989
+ ]);
65990
+ var StdioListenRouter = class {
65991
+ /** Active subscriptions, keyed by the listen request's JSON-RPC id verbatim. */
65992
+ _subs = /* @__PURE__ */ new Map();
65993
+ /**
65994
+ * The serving instance's declared capabilities. Filled in by the entry
65995
+ * once the modern instance is constructed (the router is created before
65996
+ * the instance exists), so the acknowledged filter is narrowed against
65997
+ * what the server can actually deliver.
65998
+ */
65999
+ _serverCapabilities;
66000
+ /**
66001
+ * The serving instance's identity, stamped onto the graceful-close
66002
+ * results' `_meta` (the spec's `SubscriptionsListenResultMeta` extends
66003
+ * `ResultMetaObject`). Handed over together with the capabilities.
66004
+ */
66005
+ _serverInfo;
66006
+ constructor(_maxSubscriptions = DEFAULT_MAX_SUBSCRIPTIONS, serverCapabilities, serverInfo) {
66007
+ this._maxSubscriptions = _maxSubscriptions;
66008
+ this._serverCapabilities = serverCapabilities;
66009
+ this._serverInfo = serverInfo;
66010
+ }
66011
+ /**
66012
+ * Record the serving instance's declared capabilities and identity once
66013
+ * it has been constructed. Called by `serveStdio`'s connect path;
66014
+ * subsequent `serve()` calls narrow the honored filter against the
66015
+ * capabilities, and `teardownAll()` stamps the identity.
66016
+ */
66017
+ setServerCapabilities(capabilities, serverInfo) {
66018
+ this._serverCapabilities = capabilities;
66019
+ if (serverInfo !== void 0) this._serverInfo = serverInfo;
66020
+ }
66021
+ /** Whether `id` is an active listen subscription on this connection. */
66022
+ has(id) {
66023
+ return this._subs.has(id);
66024
+ }
66025
+ /**
66026
+ * Serve one inbound `subscriptions/listen` request: registers the
66027
+ * subscription and returns the stamped acknowledged notification (or, on
66028
+ * capacity / params rejection, the in-band JSON-RPC error response).
66029
+ *
66030
+ * @throws when called before {@linkcode setServerCapabilities} (or the
66031
+ * constructor) has supplied the serving instance's capabilities. Honoring a
66032
+ * filter without knowing the server's advertised capabilities would fail
66033
+ * open (deliver unadvertised types); the entry guarantees capabilities are
66034
+ * set before any listen request is routed here.
66035
+ */
66036
+ serve(message) {
66037
+ if (this._serverCapabilities === void 0) throw new Error("StdioListenRouter.serve() called before setServerCapabilities(); refusing to honor a filter without capabilities");
66038
+ if (this._subs.size >= this._maxSubscriptions) return {
66039
+ jsonrpc: "2.0",
66040
+ id: message.id,
66041
+ error: {
66042
+ code: -32603,
66043
+ message: "Subscription limit reached"
66044
+ }
66045
+ };
66046
+ const filter = parseListenFilter(message);
66047
+ if (filter === void 0) return {
66048
+ jsonrpc: "2.0",
66049
+ id: message.id,
66050
+ error: {
66051
+ code: -32602,
66052
+ message: "Invalid params: 'notifications' is required and must be a valid SubscriptionFilter"
66053
+ }
66054
+ };
66055
+ const honored = honoredSubset(filter, this._serverCapabilities);
66056
+ this._subs.set(message.id, honored);
66057
+ return stampSubscriptionId({
66058
+ method: "notifications/subscriptions/acknowledged",
66059
+ params: { notifications: honored }
66060
+ }, message.id);
66061
+ }
66062
+ /**
66063
+ * Tear down one subscription (inbound `notifications/cancelled`). Returns
66064
+ * `true` when a subscription was removed. After this call NOTHING further
66065
+ * is delivered for that subscription id (the post-cancel hardening).
66066
+ */
66067
+ cancel(id) {
66068
+ return this._subs.delete(id);
66069
+ }
66070
+ /**
66071
+ * Route an outbound notification through the active subscriptions.
66072
+ *
66073
+ * - For a subscription-gated change notification, returns one stamped copy
66074
+ * per subscription that opted in to it (an empty array means it is
66075
+ * dropped — the modern era never delivers an un-requested change type).
66076
+ * - For any other outbound message, returns `'passthrough'` (the entry
66077
+ * forwards it as-is).
66078
+ */
66079
+ routeOutbound(message) {
66080
+ if (!CHANGE_NOTIFICATION_METHODS.has(message.method)) return "passthrough";
66081
+ const uriParam = message.params?.["uri"];
66082
+ const uri = typeof uriParam === "string" ? uriParam : void 0;
66083
+ const event = notificationToServerEvent(message.method, uri);
66084
+ const out = [];
66085
+ for (const [subscriptionId, filter] of this._subs) if (listenFilterAccepts(filter, event)) out.push(stampSubscriptionId({
66086
+ method: message.method,
66087
+ params: message.params ?? {}
66088
+ }, subscriptionId));
66089
+ return out;
66090
+ }
66091
+ /**
66092
+ * Server-side graceful teardown of every active subscription: returns the
66093
+ * empty `subscriptions/listen` JSON-RPC result for each subscription id —
66094
+ * the spec's graceful-close signal, `_meta` carrying the subscription id
66095
+ * and the serving instance's identity — for the entry to emit before
66096
+ * closing the wire. Clears the set so nothing further is delivered.
66097
+ */
66098
+ teardownAll() {
66099
+ const out = [];
66100
+ for (const id of this._subs.keys()) out.push({
66101
+ jsonrpc: "2.0",
66102
+ id,
66103
+ result: {
66104
+ resultType: "complete",
66105
+ _meta: {
66106
+ [SUBSCRIPTION_ID_META_KEY]: id,
66107
+ ...this._serverInfo !== void 0 && { [SERVER_INFO_META_KEY]: this._serverInfo }
66108
+ }
66109
+ }
66110
+ });
66111
+ this._subs.clear();
66112
+ return out;
66113
+ }
66114
+ };
66115
+ function notificationToServerEvent(method, uri) {
66116
+ switch (method) {
66117
+ case "notifications/tools/list_changed":
66118
+ return { kind: "tools_list_changed" };
66119
+ case "notifications/prompts/list_changed":
66120
+ return { kind: "prompts_list_changed" };
66121
+ case "notifications/resources/list_changed":
66122
+ return { kind: "resources_list_changed" };
66123
+ default:
66124
+ return {
66125
+ kind: "resource_updated",
66126
+ uri: uri ?? ""
66127
+ };
66128
+ }
66129
+ }
65900
66130
  var DEFAULT_LEGACY_SHIM_MAX_ROUNDS = 8;
65901
66131
  var DEFAULT_LEGACY_SHIM_ROUND_TIMEOUT_MS = 6e5;
65902
66132
  function resolveLegacyShimOptions(options) {
@@ -66034,6 +66264,12 @@ var INPUT_REQUIRED_CAPABLE_METHODS = /* @__PURE__ */ new Set([
66034
66264
  var writeClientIdentity;
66035
66265
  var installDiscoverHandler;
66036
66266
  var readServerIdentity;
66267
+ function installModernOnlyHandlers(server, servedModernVersions) {
66268
+ installDiscoverHandler(server, servedModernVersions);
66269
+ }
66270
+ function serverIdentityOf(server) {
66271
+ return readServerIdentity(server);
66272
+ }
66037
66273
  var Server = class extends Protocol {
66038
66274
  _clientCapabilities;
66039
66275
  _clientVersion;
@@ -67308,6 +67544,400 @@ var StdioServerTransport = class {
67308
67544
  });
67309
67545
  }
67310
67546
  };
67547
+ var DISCARD_ANSWER_TIMEOUT_MS = 3e3;
67548
+ var StdioConnectionChannel = class {
67549
+ onclose;
67550
+ onerror;
67551
+ onmessage;
67552
+ _closed = false;
67553
+ /** Request ids the entry delivered to the instance that the instance has not yet answered. */
67554
+ _pendingRequests = /* @__PURE__ */ new Set();
67555
+ _drainWaiters = [];
67556
+ constructor(_wire, _onInstanceClose, _outboundIntercept) {
67557
+ this._wire = _wire;
67558
+ this._onInstanceClose = _onInstanceClose;
67559
+ this._outboundIntercept = _outboundIntercept;
67560
+ }
67561
+ async start() {
67562
+ }
67563
+ async send(message, options) {
67564
+ if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {
67565
+ const { id } = message;
67566
+ if (id !== void 0) this._settle(id);
67567
+ }
67568
+ if (this._closed) return;
67569
+ if (this._outboundIntercept?.(message) === "handled") return;
67570
+ return this._wire.send(message, options);
67571
+ }
67572
+ setProtocolVersion = (version2) => {
67573
+ this._wire.setProtocolVersion?.(version2);
67574
+ };
67575
+ /** Forwards one inbound message to the connected instance. */
67576
+ deliver(message, extra) {
67577
+ if (this._closed) return;
67578
+ if (isJSONRPCRequest(message)) this._pendingRequests.add(message.id);
67579
+ else if (isJSONRPCNotification(message) && message.method === "notifications/cancelled") {
67580
+ const cancelledId = message.params?.requestId;
67581
+ if (cancelledId !== void 0) this._settle(cancelledId);
67582
+ }
67583
+ this.onmessage?.(message, extra);
67584
+ }
67585
+ /**
67586
+ * Resolves once every request delivered to the instance has been answered
67587
+ * through {@linkcode send}, settled by a delivered cancellation, or the
67588
+ * channel has been closed and nothing further can be answered. The wait is
67589
+ * bounded by `timeoutMs` as a backstop so no edge can hold the caller
67590
+ * indefinitely; resolves `false` only when the bound elapsed with requests
67591
+ * still unanswered. Used by the probe-discard path so a probe request the
67592
+ * entry accepted is never silently dropped.
67593
+ */
67594
+ async whenRequestsAnswered(timeoutMs) {
67595
+ if (this._closed || this._pendingRequests.size === 0) return true;
67596
+ return await new Promise((resolve) => {
67597
+ const waiter = () => {
67598
+ clearTimeout(timer);
67599
+ resolve(true);
67600
+ };
67601
+ const timer = setTimeout(() => {
67602
+ this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
67603
+ resolve(false);
67604
+ }, timeoutMs);
67605
+ this._drainWaiters.push(waiter);
67606
+ });
67607
+ }
67608
+ async close() {
67609
+ if (this._closed) return;
67610
+ this._closed = true;
67611
+ this._pendingRequests.clear();
67612
+ this._releaseDrainWaiters();
67613
+ try {
67614
+ this._onInstanceClose();
67615
+ } finally {
67616
+ this.onclose?.();
67617
+ }
67618
+ }
67619
+ _settle(id) {
67620
+ this._pendingRequests.delete(id);
67621
+ if (this._pendingRequests.size === 0) this._releaseDrainWaiters();
67622
+ }
67623
+ _releaseDrainWaiters() {
67624
+ const waiters = this._drainWaiters;
67625
+ this._drainWaiters = [];
67626
+ for (const waiter of waiters) waiter();
67627
+ }
67628
+ };
67629
+ function classifyOpeningMessage(message) {
67630
+ const params = message.params;
67631
+ if (message.method === "initialize" && !carriesValidModernEnvelopeClaim(params)) {
67632
+ const requestedVersion = params !== null && typeof params === "object" && typeof params.protocolVersion === "string" ? params.protocolVersion : void 0;
67633
+ return {
67634
+ kind: "legacy",
67635
+ reason: "initialize",
67636
+ ...requestedVersion !== void 0 && { requestedVersion }
67637
+ };
67638
+ }
67639
+ if (!hasEnvelopeClaim(params)) return {
67640
+ kind: "legacy",
67641
+ reason: "no-claim"
67642
+ };
67643
+ const meta3 = requestMetaOf(params);
67644
+ const firstIssue = (meta3 === void 0 ? [] : validateEnvelopeMeta(meta3))[0];
67645
+ if (firstIssue !== void 0) return {
67646
+ kind: "invalid-envelope",
67647
+ issue: firstIssue
67648
+ };
67649
+ const claimedVersion = envelopeClaimVersion(params);
67650
+ if (claimedVersion === void 0 || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) return {
67651
+ kind: "unsupported-revision",
67652
+ requested: claimedVersion ?? "unknown"
67653
+ };
67654
+ return {
67655
+ kind: "modern",
67656
+ revision: claimedVersion,
67657
+ classification: {
67658
+ era: "modern",
67659
+ revision: claimedVersion
67660
+ }
67661
+ };
67662
+ }
67663
+ function serveStdio(factory, options = {}) {
67664
+ const legacyMode = options.legacy ?? "serve";
67665
+ const wire = options.transport ?? new StdioServerTransport();
67666
+ let state = { phase: "opening" };
67667
+ let discarding;
67668
+ let closing = false;
67669
+ const isTornDown = () => closing || state.phase === "closed";
67670
+ const reportError = (error62) => {
67671
+ try {
67672
+ options.onerror?.(error62);
67673
+ } catch {
67674
+ }
67675
+ };
67676
+ const writeErrorResponse = (id, code, message, data) => wire.send({
67677
+ jsonrpc: "2.0",
67678
+ id,
67679
+ error: {
67680
+ code,
67681
+ message,
67682
+ ...data !== void 0 && { data }
67683
+ }
67684
+ }).catch((error62) => reportError(toError(error62)));
67685
+ const listenRouter = new StdioListenRouter(options.maxSubscriptions ?? DEFAULT_MAX_SUBSCRIPTIONS);
67686
+ const modernOutboundIntercept = (message) => {
67687
+ if (!isJSONRPCNotification(message)) return void 0;
67688
+ const routed = listenRouter.routeOutbound(message);
67689
+ if (routed === "passthrough") return void 0;
67690
+ for (const stamped of routed) wire.send({
67691
+ jsonrpc: "2.0",
67692
+ ...stamped
67693
+ }).catch((error62) => reportError(toError(error62)));
67694
+ return "handled";
67695
+ };
67696
+ const tryServeListen = async (message) => {
67697
+ if (isJSONRPCRequest(message) && message.method === "subscriptions/listen") {
67698
+ const meta3 = requestMetaOf(message.params);
67699
+ const issue2 = hasEnvelopeClaim(message.params) ? (meta3 === void 0 ? [] : validateEnvelopeMeta(meta3))[0] : {
67700
+ key: "_meta",
67701
+ problem: "the per-request envelope is required on protocol revision 2026-07-28"
67702
+ };
67703
+ const claimedVersion = envelopeClaimVersion(message.params);
67704
+ let reply;
67705
+ if (issue2 !== void 0) reply = {
67706
+ jsonrpc: "2.0",
67707
+ id: message.id,
67708
+ error: {
67709
+ code: -32602,
67710
+ message: `Invalid _meta envelope: ${issue2.key}: ${issue2.problem}`
67711
+ }
67712
+ };
67713
+ else if (claimedVersion === void 0 || !SUPPORTED_MODERN_PROTOCOL_VERSIONS.includes(claimedVersion)) {
67714
+ const error62 = new UnsupportedProtocolVersionError({
67715
+ supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],
67716
+ requested: claimedVersion ?? "unknown"
67717
+ });
67718
+ reply = {
67719
+ jsonrpc: "2.0",
67720
+ id: message.id,
67721
+ error: {
67722
+ code: error62.code,
67723
+ message: error62.message,
67724
+ data: error62.data
67725
+ }
67726
+ };
67727
+ } else reply = listenRouter.serve(message);
67728
+ await wire.send("error" in reply ? reply : {
67729
+ jsonrpc: "2.0",
67730
+ method: reply.method,
67731
+ params: reply.params
67732
+ }).catch((error62) => reportError(toError(error62)));
67733
+ return true;
67734
+ }
67735
+ if (isJSONRPCNotification(message) && message.method === "notifications/cancelled") {
67736
+ const cancelledId = message.params?.requestId;
67737
+ if (cancelledId !== void 0 && listenRouter.cancel(cancelledId)) return true;
67738
+ }
67739
+ return false;
67740
+ };
67741
+ const answerLegacyRejection = (request, reason, requestedVersion) => {
67742
+ const rejection2 = modernOnlyStrictRejection({
67743
+ kind: "legacy",
67744
+ reason,
67745
+ ...requestedVersion !== void 0 && { requestedVersion }
67746
+ }, SUPPORTED_MODERN_PROTOCOL_VERSIONS);
67747
+ if (rejection2 === void 0) return Promise.resolve();
67748
+ reportError(/* @__PURE__ */ new Error(`Rejected 2025-era request on a modern-only stdio connection (${rejection2.cell}): ${rejection2.message}`));
67749
+ return writeErrorResponse(request.id, rejection2.code, rejection2.message, rejection2.data);
67750
+ };
67751
+ const onInstanceClosed = (channel) => {
67752
+ if (closing || channel === discarding) return;
67753
+ closeAll();
67754
+ };
67755
+ const connectInstance = async (era, revision) => {
67756
+ const product = await factory({ era });
67757
+ const server = product instanceof McpServer ? product.server : product;
67758
+ if (era === "modern") {
67759
+ setNegotiatedProtocolVersion(server, revision);
67760
+ installModernOnlyHandlers(server, SUPPORTED_MODERN_PROTOCOL_VERSIONS);
67761
+ listenRouter.setServerCapabilities(server.getCapabilities(), serverIdentityOf(server));
67762
+ }
67763
+ const channel = new StdioConnectionChannel(wire, () => onInstanceClosed(channel), era === "modern" ? modernOutboundIntercept : void 0);
67764
+ await product.connect(channel);
67765
+ return {
67766
+ product,
67767
+ channel
67768
+ };
67769
+ };
67770
+ const disposeLateInstance = (instance) => instance.product.close().catch((error62) => reportError(toError(error62)));
67771
+ const discardProbeInstance = async (instance) => {
67772
+ discarding = instance.channel;
67773
+ try {
67774
+ if (!await instance.channel.whenRequestsAnswered(DISCARD_ANSWER_TIMEOUT_MS)) reportError(/* @__PURE__ */ new Error(`Discarded the probe instance with requests still unanswered after ${DISCARD_ANSWER_TIMEOUT_MS}ms; continuing with the fallback`));
67775
+ await instance.product.close();
67776
+ } catch (error62) {
67777
+ reportError(toError(error62));
67778
+ } finally {
67779
+ discarding = void 0;
67780
+ }
67781
+ };
67782
+ const processMessage = async (message) => {
67783
+ if (state.phase === "closed") return;
67784
+ if (state.phase === "pinned") {
67785
+ if (state.era === "modern" && isJSONRPCRequest(message) && message.method === "initialize" && !carriesValidModernEnvelopeClaim(message.params)) {
67786
+ await answerLegacyRejection(message, "initialize", message.params !== null && typeof message.params === "object" && typeof message.params.protocolVersion === "string" ? message.params.protocolVersion : void 0);
67787
+ return;
67788
+ }
67789
+ if (state.era === "modern" && await tryServeListen(message)) return;
67790
+ state.instance.channel.deliver(message);
67791
+ return;
67792
+ }
67793
+ if (!isJSONRPCRequest(message) && !isJSONRPCNotification(message)) {
67794
+ reportError(/* @__PURE__ */ new Error("Discarded a JSON-RPC response received before the connection negotiated an era"));
67795
+ return;
67796
+ }
67797
+ const opening = classifyOpeningMessage(message);
67798
+ switch (opening.kind) {
67799
+ case "invalid-envelope": {
67800
+ const detail = `Invalid _meta envelope for protocol revision 2026-07-28: ${opening.issue.key}: ${opening.issue.problem}`;
67801
+ if (isJSONRPCRequest(message)) await writeErrorResponse(message.id, ProtocolErrorCode.InvalidParams, detail, { envelope: opening.issue });
67802
+ else reportError(/* @__PURE__ */ new Error(`Discarded a notification with a malformed envelope: ${detail}`));
67803
+ return;
67804
+ }
67805
+ case "unsupported-revision":
67806
+ if (isJSONRPCRequest(message)) {
67807
+ const error62 = new UnsupportedProtocolVersionError({
67808
+ supported: [...SUPPORTED_MODERN_PROTOCOL_VERSIONS],
67809
+ requested: opening.requested
67810
+ });
67811
+ reportError(error62);
67812
+ await writeErrorResponse(message.id, error62.code, error62.message, error62.data);
67813
+ } else reportError(/* @__PURE__ */ new Error(`Discarded a notification claiming unsupported protocol revision ${opening.requested}`));
67814
+ return;
67815
+ case "modern":
67816
+ if (isJSONRPCRequest(message) && message.method === "server/discover") {
67817
+ if (state.phase === "probe") {
67818
+ state.instance.channel.deliver(message, { classification: opening.classification });
67819
+ return;
67820
+ }
67821
+ const instance = await connectInstance("modern", opening.revision);
67822
+ if (isTornDown()) {
67823
+ await disposeLateInstance(instance);
67824
+ return;
67825
+ }
67826
+ state = {
67827
+ phase: "probe",
67828
+ instance
67829
+ };
67830
+ instance.channel.deliver(message, { classification: opening.classification });
67831
+ return;
67832
+ }
67833
+ if (state.phase === "probe") {
67834
+ if (isJSONRPCNotification(message)) {
67835
+ state.instance.channel.deliver(message, { classification: opening.classification });
67836
+ return;
67837
+ }
67838
+ state = {
67839
+ phase: "pinned",
67840
+ era: "modern",
67841
+ instance: state.instance
67842
+ };
67843
+ } else {
67844
+ const instance = await connectInstance("modern", opening.revision);
67845
+ if (isTornDown()) {
67846
+ await disposeLateInstance(instance);
67847
+ return;
67848
+ }
67849
+ state = {
67850
+ phase: "pinned",
67851
+ era: "modern",
67852
+ instance
67853
+ };
67854
+ }
67855
+ if (await tryServeListen(message)) return;
67856
+ state.instance.channel.deliver(message, { classification: opening.classification });
67857
+ return;
67858
+ case "legacy": {
67859
+ if (legacyMode === "reject") {
67860
+ if (isJSONRPCRequest(message)) await answerLegacyRejection(message, opening.reason, opening.requestedVersion);
67861
+ return;
67862
+ }
67863
+ if (state.phase === "probe") {
67864
+ await discardProbeInstance(state.instance);
67865
+ if (isTornDown()) return;
67866
+ state = { phase: "opening" };
67867
+ }
67868
+ const instance = await connectInstance("legacy");
67869
+ if (isTornDown()) {
67870
+ await disposeLateInstance(instance);
67871
+ return;
67872
+ }
67873
+ state = {
67874
+ phase: "pinned",
67875
+ era: "legacy",
67876
+ instance
67877
+ };
67878
+ state.instance.channel.deliver(message);
67879
+ return;
67880
+ }
67881
+ }
67882
+ };
67883
+ const queue = [];
67884
+ let pumping = false;
67885
+ const pump = async () => {
67886
+ if (pumping) return;
67887
+ pumping = true;
67888
+ try {
67889
+ while (queue.length > 0) {
67890
+ const message = queue.shift();
67891
+ try {
67892
+ await processMessage(message);
67893
+ } catch (error62) {
67894
+ if (isJSONRPCRequest(message)) await writeErrorResponse(message.id, ProtocolErrorCode.InternalError, "Internal server error");
67895
+ reportError(toError(error62));
67896
+ }
67897
+ }
67898
+ } finally {
67899
+ pumping = false;
67900
+ }
67901
+ };
67902
+ const closeAll = async () => {
67903
+ if (closing || state.phase === "closed") return;
67904
+ closing = true;
67905
+ const current = state;
67906
+ state = { phase: "closed" };
67907
+ for (const result of listenRouter.teardownAll()) await wire.send(result).catch((error62) => reportError(toError(error62)));
67908
+ if (current.phase === "probe" || current.phase === "pinned") await current.instance.product.close().catch((error62) => reportError(toError(error62)));
67909
+ await wire.close().catch((error62) => reportError(toError(error62)));
67910
+ };
67911
+ wire.onmessage = (message) => {
67912
+ queue.push(message);
67913
+ pump();
67914
+ };
67915
+ wire.onerror = (error62) => {
67916
+ reportError(error62);
67917
+ if (state.phase === "probe" || state.phase === "pinned") state.instance.channel.onerror?.(error62);
67918
+ };
67919
+ wire.onclose = () => {
67920
+ if (closing || state.phase === "closed") return;
67921
+ closing = true;
67922
+ const current = state;
67923
+ state = { phase: "closed" };
67924
+ if (current.phase === "probe" || current.phase === "pinned") current.instance.product.close().catch((error62) => reportError(toError(error62)));
67925
+ };
67926
+ const started = wire.start().catch((error62) => {
67927
+ reportError(toError(error62));
67928
+ throw error62;
67929
+ });
67930
+ started.catch(() => {
67931
+ });
67932
+ return { close: async () => {
67933
+ await started.catch(() => {
67934
+ });
67935
+ await closeAll();
67936
+ } };
67937
+ }
67938
+ function toError(value) {
67939
+ return value instanceof Error ? value : new Error(String(value));
67940
+ }
67311
67941
 
67312
67942
  // node_modules/@chrischall/mcp-utils/dist/server/index.js
67313
67943
  init_errors();
@@ -67437,7 +68067,7 @@ async function createMcpServer(opts) {
67437
68067
  }
67438
68068
  return server;
67439
68069
  }
67440
- function withGracefulShutdown(server, opts = {}) {
68070
+ function withGracefulShutdown(target, opts = {}) {
67441
68071
  const shouldExit = opts.exit ?? true;
67442
68072
  let shuttingDown = false;
67443
68073
  const handler = (signal) => {
@@ -67448,7 +68078,7 @@ function withGracefulShutdown(server, opts = {}) {
67448
68078
  try {
67449
68079
  if (opts.onSignal)
67450
68080
  await opts.onSignal(signal);
67451
- await server.close();
68081
+ await target.close();
67452
68082
  } catch (err) {
67453
68083
  console.error(`[mcp-utils] error during graceful shutdown on ${signal}: ${err instanceof Error ? err.message : String(err)}`);
67454
68084
  } finally {
@@ -67460,16 +68090,26 @@ function withGracefulShutdown(server, opts = {}) {
67460
68090
  process.on("SIGINT", () => handler("SIGINT"));
67461
68091
  process.on("SIGTERM", () => handler("SIGTERM"));
67462
68092
  }
67463
- async function runMcp(opts) {
67464
- const server = await createMcpServer(opts);
68093
+ function runMcp(opts) {
68094
+ if (opts.banner !== void 0) {
68095
+ console.error(opts.banner);
68096
+ }
68097
+ const spec = opts.transport ?? "stdio";
68098
+ const handle = serveStdio(() => createMcpServer({ ...opts, banner: void 0 }), {
68099
+ legacy: opts.legacy ?? "serve",
68100
+ onerror: opts.onerror ?? ((error62) => {
68101
+ console.error(`[mcp-utils] stdio server error: ${redactSecrets(error62.message)}`);
68102
+ }),
68103
+ // `'stdio'` means "let the entry make its own StdioServerTransport over
68104
+ // this process"; anything else is the caller's transport, which the entry
68105
+ // then owns (it starts it, pumps it, and closes it with the handle).
68106
+ ...spec === "stdio" ? {} : { transport: spec }
68107
+ });
67465
68108
  const shutdown = opts.shutdown ?? true;
67466
68109
  if (shutdown !== false) {
67467
- withGracefulShutdown(server, shutdown === true ? {} : shutdown);
68110
+ withGracefulShutdown(handle, shutdown === true ? {} : shutdown);
67468
68111
  }
67469
- const spec = opts.transport ?? "stdio";
67470
- const transport2 = spec === "stdio" ? new StdioServerTransport() : spec;
67471
- await server.connect(transport2);
67472
- return server;
68112
+ return handle;
67473
68113
  }
67474
68114
 
67475
68115
  // node_modules/@chrischall/mcp-utils/dist/index.js
@@ -67750,7 +68390,7 @@ var pageSchema = {
67750
68390
  init_errors();
67751
68391
 
67752
68392
  // src/version.ts
67753
- var VERSION = "1.0.0";
68393
+ var VERSION = "1.1.0";
67754
68394
 
67755
68395
  // src/client.ts
67756
68396
  import { dirname, join } from "path";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '1.0.0'; // x-release-please-version
1
+ export const VERSION = '1.1.0'; // x-release-please-version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrischall/eventbrite-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "mcpName": "io.github.chrischall/eventbrite-mcp",
5
5
  "description": "Eventbrite MCP server for Claude — developed and maintained by AI (Claude Code)",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
@@ -45,7 +45,7 @@
45
45
  "typecheck": "tsc -p tsconfig.json --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@chrischall/mcp-utils": "^0.28.0",
48
+ "@chrischall/mcp-utils": "^1.0.0",
49
49
  "@fetchproxy/server": "^3.0.1",
50
50
  "@modelcontextprotocol/server": "^2.0.0",
51
51
  "dotenv": "^17.4.0",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/eventbrite-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.0.0",
9
+ "version": "1.1.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@chrischall/eventbrite-mcp",
14
- "version": "1.0.0",
14
+ "version": "1.1.0",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },