@chrischall/myatriumhealth-mcp 1.3.3 → 1.3.4

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 MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits and messages. Requests relay through the user's own signed-in browser tab via the ContextMint Bridge extension, reusing their existing session.",
10
- "version": "1.3.3"
10
+ "version": "1.3.4"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -15,7 +15,7 @@
15
15
  "displayName": "MyAtriumHealth",
16
16
  "source": "./",
17
17
  "description": "Read MyAtriumHealth (Epic MyChart) records — test results, medications, allergies, immunizations, health issues, visits — by relaying requests through the user's signed-in browser tab via the ContextMint Bridge extension.",
18
- "version": "1.3.3",
18
+ "version": "1.3.4",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "myatriumhealth-mcp",
3
3
  "displayName": "MyAtriumHealth",
4
- "version": "1.3.3",
4
+ "version": "1.3.4",
5
5
  "description": "MyAtriumHealth (Epic MyChart) access for Claude — test results, medications, allergies, immunizations, visits",
6
6
  "author": {
7
7
  "name": "Chris Hall",
package/dist/bundle.js CHANGED
@@ -28408,7 +28408,7 @@ var OAuthTokenRevocationRequestSchema = z.object({
28408
28408
  token_type_hint: z.string().optional()
28409
28409
  }).strip();
28410
28410
 
28411
- // node_modules/@modelcontextprotocol/server/dist/src-BHSMhZ_W.mjs
28411
+ // node_modules/@modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs
28412
28412
  var z2 = __toESM(require_v4(), 1);
28413
28413
  var BRANDS = /* @__PURE__ */ Symbol.for("mcp.sdk.errorBrands");
28414
28414
  function stampErrorBrands(instance, ctor) {
@@ -30652,7 +30652,8 @@ function build() {
30652
30652
  ListResourceTemplatesResultResponseSchema: wireResultResponse(ListResourceTemplatesResultSchema$1),
30653
30653
  ReadResourceResultResponseSchema: wireResultResponse(z2.union([ReadResourceResultSchema$1, InputRequiredResultSchema])),
30654
30654
  CompleteResultResponseSchema: wireResultResponse(CompleteResultSchema$1),
30655
- DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1)
30655
+ DiscoverResultResponseSchema: wireResultResponse(DiscoverResultSchema$1),
30656
+ SubscriptionsListenResultResponseSchema: wireResultResponse(SubscriptionsListenResultSchema$1)
30656
30657
  };
30657
30658
  }
30658
30659
  var memo;
@@ -31160,6 +31161,9 @@ function isSpecRequestMethod(method) {
31160
31161
  function isSpecNotificationMethod(method) {
31161
31162
  return ALL_CODECS.some((codec2) => codec2.hasNotificationMethod(method));
31162
31163
  }
31164
+ function isExtensionReusedRequestMethod(method) {
31165
+ return method === "tasks/get" || method === "tasks/cancel";
31166
+ }
31163
31167
  var ALL_CODECS = [rev2025Codec, rev2026Codec];
31164
31168
  function isPlainObject$3(value) {
31165
31169
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -32168,6 +32172,8 @@ var Protocol = class {
32168
32172
  _transport;
32169
32173
  _requestMessageId = 0;
32170
32174
  _requestHandlers = /* @__PURE__ */ new Map();
32175
+ /** Methods registered with an explicit schema; the era gate in `_onrequest` reads it for the Tasks extension names. */
32176
+ _customSchemaRequestMethods = /* @__PURE__ */ new Set();
32171
32177
  _requestHandlerAbortControllers = /* @__PURE__ */ new Map();
32172
32178
  _notificationHandlers = /* @__PURE__ */ new Map();
32173
32179
  _responseHandlers = /* @__PURE__ */ new Map();
@@ -32451,7 +32457,7 @@ var Protocol = class {
32451
32457
  return;
32452
32458
  }
32453
32459
  }
32454
- if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method)) {
32460
+ if (isSpecRequestMethod(request.method) && !codec2.hasRequestMethod(request.method) && !(isExtensionReusedRequestMethod(request.method) && this._customSchemaRequestMethods.has(request.method))) {
32455
32461
  sendErrorResponse(ProtocolErrorCode.MethodNotFound, "Method not found");
32456
32462
  return;
32457
32463
  }
@@ -32584,8 +32590,11 @@ var Protocol = class {
32584
32590
  }
32585
32591
  request(request, schemaOrOptions, maybeOptions) {
32586
32592
  const codec2 = this._resolveOutboundCodec(request.method);
32593
+ if (isStandardSchema(schemaOrOptions)) {
32594
+ if (!isExtensionReusedRequestMethod(request.method)) this._assertOutboundRequestInEra(codec2, request.method);
32595
+ return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
32596
+ }
32587
32597
  this._assertOutboundRequestInEra(codec2, request.method);
32588
- if (isStandardSchema(schemaOrOptions)) return this._requestWithSchemaViaCodec(codec2, request, schemaOrOptions, maybeOptions);
32589
32598
  const validate2 = codecResultValidator(codec2, request.method);
32590
32599
  if (validate2 === void 0) throw new TypeError(`'${request.method}' is not a spec method; pass a result schema as the second argument to request().`);
32591
32600
  return this._requestWithSchemaViaCodec(codec2, request, validate2, schemaOrOptions);
@@ -32829,6 +32838,8 @@ var Protocol = class {
32829
32838
  return maybeHandler(parsed.data, ctx);
32830
32839
  };
32831
32840
  else throw new TypeError("setRequestHandler: handler is required");
32841
+ if (typeof schemasOrHandler === "function") this._customSchemaRequestMethods.delete(method);
32842
+ else this._customSchemaRequestMethods.add(method);
32832
32843
  this._requestHandlers.set(method, this._wrapHandler(method, stored));
32833
32844
  }
32834
32845
  /**
@@ -32858,6 +32869,7 @@ var Protocol = class {
32858
32869
  */
32859
32870
  removeRequestHandler(method) {
32860
32871
  this._requestHandlers.delete(method);
32872
+ this._customSchemaRequestMethods.delete(method);
32861
32873
  }
32862
32874
  /**
32863
32875
  * Asserts that a request handler has not already been set for the given method, in preparation for a new one being automatically installed.
@@ -40100,7 +40112,7 @@ var Ajv = import_ajv.Ajv;
40100
40112
  // node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
40101
40113
  import process2 from "node:process";
40102
40114
 
40103
- // node_modules/@modelcontextprotocol/server/dist/mcp-DYuW2ZSs.mjs
40115
+ // node_modules/@modelcontextprotocol/server/dist/mcp-DIH4cS6P.mjs
40104
40116
  var COMPLETABLE_SYMBOL = /* @__PURE__ */ Symbol.for("mcp.completable");
40105
40117
  function isCompletable(schema) {
40106
40118
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
@@ -40165,7 +40177,7 @@ var StdioListenRouter = class {
40165
40177
  _serverCapabilities;
40166
40178
  /**
40167
40179
  * The serving instance's identity, stamped onto the graceful-close
40168
- * results' `_meta` (the spec's `SubscriptionsListenResultMeta` extends
40180
+ * results' `_meta` (the spec's `SubscriptionsListenResultMetaObject` extends
40169
40181
  * `ResultMetaObject`). Handed over together with the capabilities.
40170
40182
  */
40171
40183
  _serverInfo;
@@ -40497,6 +40509,11 @@ var Server = class extends Protocol {
40497
40509
  if (modernProtocolVersions(this._supportedProtocolVersions).length > 0) this.setRequestHandler("server/discover", () => this._ondiscover());
40498
40510
  if (this._capabilities.logging) this._registerLoggingHandler();
40499
40511
  }
40512
+ /** Attaches to the given transport; rejects while this instance is connected to another one. */
40513
+ async connect(transport2) {
40514
+ if (this.transport !== void 0) throw new SdkError(SdkErrorCode.AlreadyConnected, "Use a separate Server instance per connection: this instance is already connected to a transport. To connect it to a new transport, call close() first.");
40515
+ await super.connect(transport2);
40516
+ }
40500
40517
  /**
40501
40518
  * Registers the built-in `logging/setLevel` request handler.
40502
40519
  *
@@ -41050,21 +41067,41 @@ var Server = class extends Protocol {
41050
41067
  function discoverAdvertisedCapabilities(capabilities) {
41051
41068
  return { ...capabilities };
41052
41069
  }
41070
+ function toolInputElementCount(value, max) {
41071
+ let count = 0;
41072
+ const stack = [value];
41073
+ while (stack.length > 0) {
41074
+ const node2 = stack.pop();
41075
+ if (node2 === null || typeof node2 !== "object") continue;
41076
+ if (Array.isArray(node2)) for (const child of node2) {
41077
+ if (++count > max) return count;
41078
+ if (child !== null && typeof child === "object") stack.push(child);
41079
+ }
41080
+ else for (const key in node2) {
41081
+ if (!Object.prototype.hasOwnProperty.call(node2, key)) continue;
41082
+ if (++count > max) return count;
41083
+ const child = node2[key];
41084
+ if (child !== null && typeof child === "object") stack.push(child);
41085
+ }
41086
+ }
41087
+ return count;
41088
+ }
41089
+ function resolveMaxToolInputElements(value) {
41090
+ if (value === void 0 || value === Infinity) return void 0;
41091
+ if (typeof value !== "number" || Number.isNaN(value) || value < 1) throw new RangeError(`maxToolInputElements must be a number of at least 1, or Infinity, got ${String(value)}`);
41092
+ return value;
41093
+ }
41053
41094
  var McpServer = class {
41054
41095
  /**
41055
41096
  * The underlying {@linkcode Server} instance, useful for advanced operations like sending notifications.
41056
41097
  */
41057
41098
  server;
41099
+ _maxToolInputElements;
41058
41100
  _registeredResources = {};
41059
41101
  _registeredResourceTemplates = {};
41060
41102
  _registeredTools = {};
41061
41103
  _registeredPrompts = {};
41062
- /**
41063
- * Per-tool JSON-converted `inputSchema`, memoized so the SEP-2243
41064
- * registration-time scan and the pre-dispatch validation step share one
41065
- * conversion instead of paying it twice per request under the
41066
- * per-request-factory `createMcpHandler` model.
41067
- */
41104
+ /** Per-tool JSON-converted `inputSchema`, filled on first use by `toolInputSchemaJson()`. */
41068
41105
  _toolInputSchemaJson = {};
41069
41106
  /**
41070
41107
  * The JSON-serialized `inputSchema` of a registered tool, or `undefined`
@@ -41089,6 +41126,7 @@ var McpServer = class {
41089
41126
  }
41090
41127
  constructor(serverInfo, options) {
41091
41128
  this.server = new Server(serverInfo, options);
41129
+ this._maxToolInputElements = resolveMaxToolInputElements(options?.maxToolInputElements);
41092
41130
  if (options?.capabilities?.tools) this.setToolRequestHandlers();
41093
41131
  if (options?.capabilities?.resources) this.setResourceRequestHandlers();
41094
41132
  if (options?.capabilities?.prompts) this.setPromptRequestHandlers();
@@ -41161,7 +41199,7 @@ var McpServer = class {
41161
41199
  name,
41162
41200
  title: tool.title,
41163
41201
  description: tool.description,
41164
- inputSchema: tool.inputSchema ? standardSchemaToJsonSchema(tool.inputSchema, "input") : EMPTY_OBJECT_JSON_SCHEMA,
41202
+ inputSchema: tool.inputSchema ? convertListedInputSchema(name, tool.inputSchema) : EMPTY_OBJECT_JSON_SCHEMA,
41165
41203
  annotations: tool.annotations,
41166
41204
  icons: tool.icons,
41167
41205
  execution: tool.execution,
@@ -41206,6 +41244,7 @@ var McpServer = class {
41206
41244
  * Validates tool input arguments against the tool's input schema.
41207
41245
  */
41208
41246
  async validateToolInput(tool, args, toolName) {
41247
+ if (this._maxToolInputElements !== void 0 && toolInputElementCount(args, this._maxToolInputElements) > this._maxToolInputElements) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: arguments contain more than the maximum of ${this._maxToolInputElements} elements`);
41209
41248
  if (!tool.inputSchema) return;
41210
41249
  const parseResult = await validateStandardSchema(tool.inputSchema, args ?? {});
41211
41250
  if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${parseResult.error}`);
@@ -41480,20 +41519,19 @@ var McpServer = class {
41480
41519
  }
41481
41520
  _createRegisteredTool(name, title, description, inputSchema, outputSchema, annotations, icons, execution, scopeChallenge, _meta, handler) {
41482
41521
  validateAndWarnToolName(name);
41483
- if (inputSchema !== void 0) try {
41484
- const json2 = standardSchemaToJsonSchema(inputSchema, "input");
41485
- this._toolInputSchemaJson[name] = json2;
41486
- const scan = scanXMcpHeaderDeclarations(json2);
41487
- if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
41488
- } catch {
41489
- }
41490
41522
  let currentHandler = handler;
41523
+ let outputSchemaJson;
41491
41524
  const registeredTool = {
41492
41525
  title,
41493
41526
  description,
41494
41527
  inputSchema,
41495
41528
  outputSchema,
41496
- outputSchemaJson: convertOutputSchemaJson(outputSchema),
41529
+ get outputSchemaJson() {
41530
+ return outputSchemaJson ??= convertOutputSchemaJson(registeredTool.outputSchema);
41531
+ },
41532
+ set outputSchemaJson(value) {
41533
+ outputSchemaJson = value;
41534
+ },
41497
41535
  annotations,
41498
41536
  icons,
41499
41537
  execution,
@@ -41620,6 +41658,12 @@ var EMPTY_OBJECT_JSON_SCHEMA = {
41620
41658
  type: "object",
41621
41659
  properties: {}
41622
41660
  };
41661
+ function convertListedInputSchema(name, inputSchema) {
41662
+ const json2 = standardSchemaToJsonSchema(inputSchema, "input");
41663
+ const scan = scanXMcpHeaderDeclarations(json2);
41664
+ if (!scan.valid) console.warn(`[mcp-sdk] tool '${name}' carries an invalid x-mcp-header declaration and will be excluded by conforming Streamable HTTP clients: ${scan.reason}`);
41665
+ return json2;
41666
+ }
41623
41667
  function convertOutputSchemaJson(outputSchema) {
41624
41668
  if (outputSchema === void 0) return void 0;
41625
41669
  try {
@@ -41632,7 +41676,7 @@ function createPromptHandler(name, argsSchema, callback) {
41632
41676
  if (argsSchema) {
41633
41677
  const typedCallback = callback;
41634
41678
  return async (args, ctx) => {
41635
- const parseResult = await validateStandardSchema(argsSchema, args);
41679
+ const parseResult = await validateStandardSchema(argsSchema, args ?? {});
41636
41680
  if (!parseResult.success) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid arguments for prompt ${name}: ${parseResult.error}`);
41637
41681
  return typedCallback(parseResult.data, ctx);
41638
41682
  };
@@ -62659,7 +62703,10 @@ function surfaceToolHints(server) {
62659
62703
  ));
62660
62704
  }
62661
62705
  async function createMcpServer(opts) {
62662
- const server = new McpServer({ name: opts.name, version: opts.version }, { supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS] });
62706
+ const server = new McpServer({ name: opts.name, version: opts.version }, {
62707
+ supportedProtocolVersions: [...SERVER_PROTOCOL_VERSIONS],
62708
+ ...opts.maxToolInputElements !== void 0 ? { maxToolInputElements: opts.maxToolInputElements } : {}
62709
+ });
62663
62710
  if (opts.surfaceHints !== false)
62664
62711
  surfaceToolHints(server);
62665
62712
  if (opts.banner !== void 0) {
@@ -75921,7 +75968,7 @@ function registerVisitTools(server, client2, patients2) {
75921
75968
  }
75922
75969
 
75923
75970
  // src/version.ts
75924
- var VERSION = "1.3.3";
75971
+ var VERSION = "1.3.4";
75925
75972
 
75926
75973
  // src/index.ts
75927
75974
  var dotenvCandidates = [
@@ -76006,7 +76053,7 @@ await runMcp({
76006
76053
  });
76007
76054
  /*! Bundled license information:
76008
76055
 
76009
- @modelcontextprotocol/server/dist/src-BHSMhZ_W.mjs:
76056
+ @modelcontextprotocol/server/dist/src-Cqbh3MYc.mjs:
76010
76057
  (*!
76011
76058
  * content-type
76012
76059
  * Copyright(c) 2015 Douglas Christopher Wilson
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrischall/myatriumhealth-mcp",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "MCP server for MyAtriumHealth (Atrium Health's Epic MyChart patient portal) via the fetchproxy browser bridge.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,15 +42,15 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "@chrischall/mcp-utils": "^2.13.0",
45
+ "@chrischall/mcp-utils": "^2.14.0",
46
46
  "@fetchproxy/server": "^3.4.1",
47
- "@modelcontextprotocol/server": "^2.2.0",
47
+ "@modelcontextprotocol/server": "^2.3.0",
48
48
  "dotenv": "^18.0.1",
49
49
  "node-html-parser": "^9.0.3",
50
50
  "zod": "^4.6.5"
51
51
  },
52
52
  "devDependencies": {
53
- "@modelcontextprotocol/client": "^2.2.0",
53
+ "@modelcontextprotocol/client": "^2.3.0",
54
54
  "@types/node": "^26.0.0",
55
55
  "@vitest/coverage-v8": "^5.0.0",
56
56
  "esbuild": "^0.28.1",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/chrischall/myatriumhealth-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.3.3",
9
+ "version": "1.3.4",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@chrischall/myatriumhealth-mcp",
14
- "version": "1.3.3",
14
+ "version": "1.3.4",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },