@chrischall/myatriumhealth-mcp 0.1.0 → 0.2.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/bundle.js +2 -1
- package/mint.yaml +111 -17
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
},
|
|
8
8
|
"metadata": {
|
|
9
9
|
"description": "MCP server for Angi — find home-service pros by trade and city, read ratings, reviews and pro profiles. Angi serves its pages only to a real browser, so requests route through the user's own angi.com tab via the fetchproxy browser extension, reusing their existing session. The trade/city taxonomy is read from Angi's public sitemaps directly.",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.2.0"
|
|
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 fetchproxy bridge.",
|
|
18
|
-
"version": "0.
|
|
18
|
+
"version": "0.2.0",
|
|
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": "0.
|
|
4
|
+
"version": "0.2.0",
|
|
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
|
@@ -39884,6 +39884,7 @@ var MyAtriumHealthAuth = class {
|
|
|
39884
39884
|
if (/SecondaryValidation/i.test(nextLocation) || /SecondaryValidation/i.test(landing.body)) {
|
|
39885
39885
|
const ctx = await this.challengeContext();
|
|
39886
39886
|
this.mfaPending = true;
|
|
39887
|
+
this.persist();
|
|
39887
39888
|
throw new MfaRequiredError(ctx?.channels ?? ["sms", "email"], {
|
|
39888
39889
|
...ctx?.displayEmail !== void 0 ? { email: ctx.displayEmail } : {},
|
|
39889
39890
|
...ctx?.displayPhone !== void 0 ? { phone: ctx.displayPhone } : {}
|
|
@@ -49417,7 +49418,7 @@ function registerVisitTools(server, client2) {
|
|
|
49417
49418
|
}
|
|
49418
49419
|
|
|
49419
49420
|
// src/version.ts
|
|
49420
|
-
var VERSION = "0.
|
|
49421
|
+
var VERSION = "0.2.0";
|
|
49421
49422
|
|
|
49422
49423
|
// src/index.ts
|
|
49423
49424
|
var username = readEnvVar("MAH_USERNAME");
|
package/mint.yaml
CHANGED
|
@@ -2,33 +2,127 @@ version: 1
|
|
|
2
2
|
name: MyAtriumHealth
|
|
3
3
|
slug: myatriumhealth
|
|
4
4
|
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# bridge
|
|
5
|
+
# This server has TWO transports and the hosted one is the bridge-less path:
|
|
6
|
+
# with MAH_USERNAME/MAH_PASSWORD set it signs in server-side with its own cookie
|
|
7
|
+
# jar, so no browser, extension or bridge is involved and this registers like any
|
|
8
|
+
# other credential MCP.
|
|
9
|
+
#
|
|
10
|
+
# Without those credentials it falls back to the fetchproxy browser bridge, which
|
|
11
|
+
# relays through the user's signed-in tab. Hosting THAT would additionally need
|
|
12
|
+
# `bridge: true` + `bridgePortEnv: MAH_WS_PORT` on `runtime: fly-shared` — set
|
|
13
|
+
# over the control API, since this manifest has no column for them — and
|
|
14
|
+
# mcp-host's docs/BROWSER-BRIDGE.md still calls bridge hosting built but
|
|
15
|
+
# unproven over the WAN. Prefer the credential path.
|
|
16
|
+
#
|
|
17
|
+
# Verification is human-in-the-loop and cannot be automated away: when the portal
|
|
18
|
+
# challenges, the connector reports the available channels, the portal sends a
|
|
19
|
+
# code to the ACCOUNT HOLDER, and they supply it. Expect that on first use and
|
|
20
|
+
# again whenever the stored session lapses. Nothing needs reconnecting when it
|
|
21
|
+
# does.
|
|
13
22
|
|
|
14
23
|
env:
|
|
24
|
+
# MAH_USERNAME / MAH_PASSWORD are deliberately NOT here: they are collected
|
|
25
|
+
# from each connector user at connect time (see `auth.fields` below), and an
|
|
26
|
+
# auth field may not name a host-set variable. Set them in .env only for a
|
|
27
|
+
# local, single-user install.
|
|
28
|
+
- name: MAH_DEVICE_FILE
|
|
29
|
+
required: false
|
|
30
|
+
help: >-
|
|
31
|
+
Override the session-state file path. Defaults to device.json under the
|
|
32
|
+
data directory, which is where it belongs when hosted — and with
|
|
33
|
+
per-user children each caller gets their own.
|
|
15
34
|
- name: MAH_WS_PORT
|
|
16
35
|
required: false
|
|
17
36
|
help: >-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
37
|
+
fetchproxy WebSocket concentrator port (default 37149). Only meaningful for
|
|
38
|
+
the browser-bridge fallback; ignored on the credential path.
|
|
39
|
+
|
|
40
|
+
identity:
|
|
41
|
+
# One child per caller. Required for `auth` below, and right on its own merits:
|
|
42
|
+
# these are personal health records, so two people sharing one child would
|
|
43
|
+
# share one signed-in session.
|
|
44
|
+
perUserChild: true
|
|
45
|
+
|
|
46
|
+
auth:
|
|
47
|
+
# Collected once, on the connector's authorize page, before any tool runs.
|
|
48
|
+
fields:
|
|
49
|
+
- name: MAH_USERNAME
|
|
50
|
+
label: MyAtriumHealth username
|
|
51
|
+
type: text
|
|
52
|
+
required: true
|
|
53
|
+
help: The username you use at my.atriumhealth.org — not your email, unless that is your username.
|
|
54
|
+
- name: MAH_PASSWORD
|
|
55
|
+
label: Password
|
|
56
|
+
type: password
|
|
57
|
+
required: true
|
|
58
|
+
help: >-
|
|
59
|
+
Your MyAtriumHealth password. It is stored as a per-user secret and is
|
|
60
|
+
never shown again. The portal counts failed sign-ins and escalates to a
|
|
61
|
+
captcha, so nothing here retries for you.
|
|
62
|
+
|
|
63
|
+
# The portal challenges every fresh sign-in, so the connection cannot finish
|
|
64
|
+
# on username and password alone — hence a flow. There is no `capture`: the
|
|
65
|
+
# child persists its own session under its per-user data directory, so there
|
|
66
|
+
# is no durable credential to hand back.
|
|
67
|
+
flow:
|
|
68
|
+
steps:
|
|
69
|
+
- tool: mah_sign_in
|
|
70
|
+
title: Sign in to MyAtriumHealth
|
|
71
|
+
description: >-
|
|
72
|
+
Sends the username and password you just entered. MyAtriumHealth
|
|
73
|
+
challenges a sign-in from a new device, so expect to be asked for a
|
|
74
|
+
verification code next. Your password is not what the remaining steps
|
|
75
|
+
are about.
|
|
76
|
+
- tool: mah_send_verification_code
|
|
77
|
+
args:
|
|
78
|
+
channel: { from: channel }
|
|
79
|
+
prompt:
|
|
80
|
+
- name: channel
|
|
81
|
+
label: Where should MyAtriumHealth send your code?
|
|
82
|
+
type: choice
|
|
83
|
+
options:
|
|
84
|
+
- { value: sms, label: Text message }
|
|
85
|
+
- { value: email, label: Email }
|
|
86
|
+
help: >-
|
|
87
|
+
It goes to the number or address on your MyAtriumHealth account.
|
|
88
|
+
Codes are short-lived, so pick the one you can read right now.
|
|
89
|
+
title: Choose where your code goes
|
|
90
|
+
description: >-
|
|
91
|
+
If a channel is refused it is not configured on your account — start
|
|
92
|
+
the connection again and choose the other one.
|
|
93
|
+
- tool: mah_verify_code
|
|
94
|
+
args:
|
|
95
|
+
code: { from: code }
|
|
96
|
+
prompt:
|
|
97
|
+
- name: code
|
|
98
|
+
label: Verification code
|
|
99
|
+
type: text
|
|
100
|
+
help: >-
|
|
101
|
+
The code MyAtriumHealth just sent you. Codes are single-use and
|
|
102
|
+
expire quickly; if yours has lapsed, start the connection again
|
|
103
|
+
and a fresh one will be sent.
|
|
104
|
+
title: Enter the code
|
|
105
|
+
description: >-
|
|
106
|
+
This finishes the connection and stores the session, so restarts
|
|
107
|
+
resume without signing in again. When the session eventually lapses,
|
|
108
|
+
the same three steps run in the conversation — nothing needs
|
|
109
|
+
reconnecting.
|
|
21
110
|
|
|
22
111
|
state:
|
|
23
112
|
dataDir: true
|
|
24
113
|
reason: >-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
114
|
+
Holds device.json — one per caller, since identity.perUserChild is set —
|
|
115
|
+
which stores the LIVE SESSION COOKIE JAR (plus the portal's
|
|
116
|
+
device-trust token, recorded but never sent). That jar is what lets a restart
|
|
117
|
+
resume an existing session. Without persistence every cold start signs in
|
|
118
|
+
again and, because this portal challenges a fresh sign-in, prompts the account
|
|
119
|
+
holder for a verification code — on a scale-to-zero machine, repeatedly. The
|
|
120
|
+
file is written 0600 and is credential-equivalent: anyone who can read it can
|
|
121
|
+
act as the account until the session lapses.
|
|
29
122
|
|
|
30
123
|
egress:
|
|
31
|
-
#
|
|
32
|
-
#
|
|
124
|
+
# The only host contacted. On the credential path the server fetches paths under
|
|
125
|
+
# my.atriumhealth.org/myatriumhealth directly; on the bridge fallback the same
|
|
126
|
+
# host is reached through the user's tab. No other host appears as a fetch base.
|
|
33
127
|
allow:
|
|
34
128
|
- my.atriumhealth.org
|
package/package.json
CHANGED
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": "0.
|
|
9
|
+
"version": "0.2.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@chrischall/myatriumhealth-mcp",
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.2.0",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|