{"id":"c7df4153-4ebe-46d6-a6be-564c2d3954cc","entityType":"agent","slug":"clawhub-chrischall-myatriumhealth-mcp","name":"myatriumhealth-mcp","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chrischall-myatriumhealth-mcp","canonicalPath":"/agent/clawhub-chrischall-myatriumhealth-mcp","generatedAt":"2026-10-11T21:00:25.426Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":null},"description":"Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server. Skill: myatriumhealth-mcp Owner: chrischall Summary: Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server. Tag","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:myatriumhealth-mcp","sourceUrl":"https://clawhub.ai/chrischall/myatriumhealth-mcp","homepage":"https://clawhub.ai/chrischall/skills/myatriumhealth-mcp","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chrischall/myatriumhealth-mcp","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chrischall/skills/myatriumhealth-mcp","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a s"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":null},"stars":null,"forks":null,"downloads":1032,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"1.3.6","tractionLabel":"1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T16:02:40.305Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T16:02:40.375Z","lastCrawledAt":"2026-10-11T16:02:40.305Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T16:02:40.305Z","lastVerifiedAt":null,"highlights":[{"version":"1.3.6","createdAt":"2026-10-09T23:25:57.972Z","changelog":"- Updated endpoint documentation in references/endpoints.md. - Removed the skill-card.md file.","fileCount":5,"zipByteSize":10007},{"version":"1.3.5","createdAt":"2026-10-07T13:38:27.094Z","changelog":"- Removed the file skill-card.md. - No feature or interface changes; documentation only.","fileCount":5,"zipByteSize":9853},{"version":"1.3.4","createdAt":"2026-10-05T02:50:17.549Z","changelog":"- Removed the skill-card.md file. - No user-facing feature changes. This update is a minor cleanup of documentation files.","fileCount":5,"zipByteSize":9850},{"version":"1.3.3","createdAt":"2026-10-03T01:40:56.643Z","changelog":"- Removed the skill card documentation file (skill-card.md). - No changes to code or user-facing functionality.","fileCount":5,"zipByteSize":9963},{"version":"1.3.2","createdAt":"2026-09-28T13:55:36.583Z","changelog":"- Switched extension setup to use ContextMint Bridge (renamed fetchproxy extension), with updated installation instructions. - Updated documentation to reference ContextMint Bridge for pairing and usage. - Removed outdated skill-card.md file.","fileCount":5,"zipByteSize":9925},{"version":"1.3.1","createdAt":"2026-09-25T15:51:27.425Z","changelog":"- Removed the file: skill-card.md - No other functional or documentation changes in this version.","fileCount":5,"zipByteSize":9688},{"version":"1.3.0","createdAt":"2026-09-24T15:34:29.201Z","changelog":"- Removed the skill-card.md file. - No functional or user-facing changes; documentation file only.","fileCount":5,"zipByteSize":9777},{"version":"1.2.2","createdAt":"2026-09-23T21:41:35.454Z","changelog":"- Removed the file skill-card.md.","fileCount":5,"zipByteSize":9884}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:myatriumhealth-mcp","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T21:00:25.423Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-myatriumhealth-mcp/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":null},"readme":"Skill: myatriumhealth-mcp\n\nOwner: chrischall\n\nSummary: Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server.\n\nTags: latest:1.3.6\n\nVersion history:\n\nv1.3.6 | 2026-10-09T23:25:57.972Z | auto\n\n- Updated endpoint documentation in references/endpoints.md.\n- Removed the skill-card.md file.\n\nv1.3.5 | 2026-10-07T13:38:27.094Z | auto\n\n- Removed the file skill-card.md.\n- No feature or interface changes; documentation only.\n\nv1.3.4 | 2026-10-05T02:50:17.549Z | auto\n\n- Removed the skill-card.md file.\n- No user-facing feature changes. This update is a minor cleanup of documentation files.\n\nv1.3.3 | 2026-10-03T01:40:56.643Z | auto\n\n- Removed the skill card documentation file (skill-card.md).\n- No changes to code or user-facing functionality.\n\nv1.3.2 | 2026-09-28T13:55:36.583Z | auto\n\n- Switched extension setup to use ContextMint Bridge (renamed fetchproxy extension), with updated installation instructions.\n- Updated documentation to reference ContextMint Bridge for pairing and usage.\n- Removed outdated skill-card.md file.\n\nv1.3.1 | 2026-09-25T15:51:27.425Z | auto\n\n- Removed the file: skill-card.md\n- No other functional or documentation changes in this version.\n\nv1.3.0 | 2026-09-24T15:34:29.201Z | auto\n\n- Removed the skill-card.md file.\n- No functional or user-facing changes; documentation file only.\n\nv1.2.2 | 2026-09-23T21:41:35.454Z | auto\n\n- Removed the file skill-card.md.\n\nv1.2.1 | 2026-09-23T15:47:36.426Z | auto\n\n- Removed the file skill-card.md.\n- No other changes were made to the skill functionality or documentation.\n\nv1.2.0 | 2026-09-21T20:01:39.475Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing feature or behavior changes; this update removes redundant or unused documentation.\n\nv1.1.1 | 2026-09-21T04:12:50.359Z | auto\n\n- Removed the \"skill-card.md\" file.\n- No functional changes to code or user-facing features.\n- Clean-up of repository documentation only.\n\nv1.1.0 | 2026-09-20T02:50:43.099Z | auto\n\n- Removed the file skill-card.md.\n- No changes to core functionality or usage.\n- Documentation and skill description remain unchanged.\n\nv1.0.0 | 2026-09-19T11:19:06.695Z | auto\n\n- Initial release.\n- Removed the sample file skill-card.md.\n\nv0.4.4 | 2026-09-15T19:24:01.359Z | auto\n\n- Removed the skill-card.md file.\n- No changes to features or functionality; documentation file only.\n\nv0.4.3 | 2026-09-14T14:15:06.721Z | auto\n\n- Removed the skill card file (skill-card.md).\n- No functional or interface changes to the core skill.\n- Documentation and usage instructions remain unchanged.\n\nv0.4.2 | 2026-09-10T17:53:32.909Z | auto\n\n- Removed the skill-card.md file.\n- No functional or user experience changes.\n\nv0.4.1 | 2026-09-10T13:19:02.902Z | auto\n\nNo user-facing changes in this version.\n\n- Version bump to 0.4.1 without file modifications.\n- No updates to documentation or code detected.\n\nv0.4.0 | 2026-09-10T13:12:01.008Z | auto\n\n- Removed the file skill-card.md from the project.\n- No changes to main functionality or usage; documentation and interface remain the same.\n\nv0.3.0 | 2026-09-04T22:23:20.491Z | auto\n\n- Renamed skill to **myatriumhealth-fpx** and updated description to reflect usage via the fpx CLI with the Chrome browser relay.\n- Added clear setup instructions for installing dependencies and pairing the profile with required cookies and headers.\n- Documented usage of helper commands (`mah_signed_in`, `mah_token`, `mah_api`, `mah_legacy`) to access health data endpoints through the browser session.\n- Clarified session management, including signed-in checks, handling of expired sessions, and accurate exit codes for different connection states.\n- Provided specific instructions for accessing message center data, including necessary parameters and helper usage.\n- Emphasized privacy: all actions are limited to the signed-in user's own MyAtriumHealth account, with no external storage of credentials or cookies.\n\nArchive index:\n\nArchive v1.3.6: 5 files, 10007 bytes\n\nFiles: references/endpoints.md (6991b), references/mah.sh (6264b), skill-card.md (2243b), SKILL.md (4559b), _meta.json (137b)\n\nFile v1.3.6:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.6:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.6\",\n  \"publishedAt\": 1791588357972\n}\n\nFile v1.3.6:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\n`search/LoadMenuInfo` currently answers 302 to `Home/FiveHundred` (a server error), so\nexpect that call to fail until its real parameters are captured.\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.6:skill-card.md\n\n## Description:\n\nHelps users read their own MyAtriumHealth records through a signed-in Chrome tab using shell commands, without running the MyAtriumHealth MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople accessing their own MyAtriumHealth account, including developers writing personal scripts, can retrieve and filter health records, visits, and messages through their signed-in browser session.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Persistent browser access to a sensitive healthcare account can expose private records.\n\nMitigation: Install only if you trust the browser extension and CLI, use your own account, and remove the profile or extension when no longer needed.\n\nRisk: Broad shell helpers can read sensitive records and expose tokens or output to untrusted scripts or logs.\n\nMitigation: Review scripts before use, keep tokens and command output private, and limit output to the fields needed.\n\nRisk: Expired sessions or a missing browser tab can make results appear empty or successful.\n\nMitigation: Check that the browser session is active before trusting empty results, and sign in again when needed.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth endpoint recipes](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n- [ContextMint Bridge extension releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance, JSON]\n\n**Output Format:** [Shell examples and JSON responses]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Responses can contain sensitive personal health information; filter before sharing or storing.]\n\n## Skill Version(s):\n\n1.3.6 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.5: 5 files, 9853 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (1944b), SKILL.md (4559b), _meta.json (137b)\n\nFile v1.3.5:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.5:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.5\",\n  \"publishedAt\": 1791380307094\n}\n\nFile v1.3.5:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.5:skill-card.md\n\n## Description:\n\nHelps users read their MyAtriumHealth records, including test results, medications, allergies, and visits, through a signed-in Chrome tab and shell commands.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPatients and their authorized agents use this skill to retrieve and selectively summarize their own MyAtriumHealth records from a signed-in browser session without running a separate MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The browser bridge retains access to a signed-in MyAtriumHealth session.\n\nMitigation: Use only on a private device and remove the bridge profile or extension when access is no longer needed.\n\nRisk: Raw API responses, shell output, and MAH_TOKEN can expose sensitive medical information.\n\nMitigation: Use a private, unrecorded terminal; limit output to the fields needed and protect the token and results.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [Endpoint recipes](references/endpoints.md)\n- [Shell helpers](references/mah.sh)\n- [ContextMint Bridge releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell commands and JSON projection examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Selected patient-record data may appear in command output; treat it as sensitive.]\n\n## Skill Version(s):\n\n1.3.5 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.4: 5 files, 9850 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (1985b), SKILL.md (4559b), _meta.json (137b)\n\nFile v1.3.4:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.4:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.4\",\n  \"publishedAt\": 1791168617549\n}\n\nFile v1.3.4:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.4:skill-card.md\n\n## Description:\n\nHelps agents read a signed-in user's MyAtriumHealth records through a Chrome tab using shell commands, without running the MyAtriumHealth MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople with a signed-in MyAtriumHealth account and their authorized agents can retrieve their own test results, medications, allergies, visits, and other health records for review or scripting.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Persistent browser-bridge pairing can relay requests from a signed-in healthcare session.\n\nMitigation: Use a dedicated shell and browser profile; remove the fpx profile or revoke the bridge pairing when finished.\n\nRisk: Patient records and the MAH_TOKEN session token can be exposed through logs or shared environments.\n\nMitigation: Avoid sharing logs or environments containing MAH_TOKEN, and limit record output to necessary fields.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [Endpoint recipes](references/endpoints.md)\n- [Shell helpers](references/mah.sh)\n- [ContextMint Bridge releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Shell commands, JSON]\n\n**Output Format:** [Markdown guidance and shell commands; JSON health records from portal requests]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Contains sensitive personal health information; filter responses to the fields needed.]\n\n## Skill Version(s):\n\n1.3.4 (source: ClawHub release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.3: 5 files, 9963 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2209b), SKILL.md (4559b), _meta.json (137b)\n\nFile v1.3.3:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.3\",\n  \"publishedAt\": 1790991656643\n}\n\nFile v1.3.3:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.3:skill-card.md\n\n## Description:\n\nHelps users read their own MyAtriumHealth test results, medications, allergies, visits, and other records through a signed-in Chrome tab using shell commands.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPatients and developers use this skill to retrieve and filter their own MyAtriumHealth records in scripts without running the separate MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The paired shell can read sensitive medical records from the signed-in portal.\n\nMitigation: Use only on a trusted, single-user machine; avoid shared terminals and CI, and limit what you display or share.\n\nRisk: The browser pairing persists and an exported antiforgery token remains available in the shell session.\n\nMitigation: Clear MAH_TOKEN when finished and revoke or remove the fpx/bridge pairing when no longer needed.\n\nRisk: An expired session may return a login page with HTTP 200 or empty JSON, obscuring missing results.\n\nMitigation: Check the signed-in session when results are unexpectedly empty, then sign in again if necessary.\n\n## Reference(s):\n\n- [ClawHub release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth endpoint recipes](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n- [ContextMint Bridge releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Configuration instructions, JSON, Guidance]\n\n**Output Format:** [Shell examples and JSON responses from the patient's portal]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Responses can contain sensitive personal health information; filter results before displaying or sharing.]\n\n## Skill Version(s):\n\n1.3.3 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.2: 5 files, 9925 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2161b), SKILL.md (4559b), _meta.json (137b)\n\nFile v1.3.2:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.2\",\n  \"publishedAt\": 1790603736583\n}\n\nFile v1.3.2:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.2:skill-card.md\n\n## Description:\n\nHelps users read their own MyAtriumHealth records from a shell through a signed-in Chrome tab, including test results, medications, allergies, immunizations, health issues, visits, and goals.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPatients and developers use this skill to retrieve their own MyAtriumHealth portal data in one-off shell queries or scripts without running a separate MCP server.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Raw command output may expose personal health information.\n\nMitigation: Avoid saving, logging, or sharing raw output; select only the fields needed.\n\nRisk: The browser bridge retains trust after pairing and grants shell access to the signed-in account.\n\nMitigation: Install only if you intend to access your own data; review the CLI and bridge source or checksums before pairing.\n\nRisk: An expired session or missing browser tab can yield empty or misleading results.\n\nMitigation: Check the signed-in session and reopen or reauthenticate the browser tab before relying on empty results.\n\n## Reference(s):\n\n- [MyAtriumHealth skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [Endpoint recipes](references/endpoints.md)\n- [Shell helpers](references/mah.sh)\n- [ContextMint Bridge releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Configuration instructions, Guidance]\n\n**Output Format:** [Markdown with shell commands and jq examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands can return sensitive personal health information from the signed-in user's account.]\n\n## Skill Version(s):\n\n1.3.2 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.1: 5 files, 9688 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2121b), SKILL.md (4170b), _meta.json (137b)\n\nFile v1.3.1:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the Transporter Chrome extension\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the Transporter popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.1\",\n  \"publishedAt\": 1790351487425\n}\n\nFile v1.3.1:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.1:skill-card.md\n\n## Description:\n\nGuides signed-in MyAtriumHealth users in reading their own patient-portal data through shell commands relayed via a Chrome tab.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPatients and their authorized agents use this skill to retrieve their own MyAtriumHealth records, including results, medications, allergies, visits, and messages, from an authenticated browser session.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Broad, persistent browser-mediated access exposes sensitive patient records to shell commands.\n\nMitigation: Use only on a trusted machine for your own authorized account; review the persistent pairing and remove it when no longer needed.\n\nRisk: Raw responses or shell output may expose health details, messages, insurance information, or access tokens.\n\nMitigation: Project only needed fields; avoid logging, saving, or sharing raw responses and shell history.\n\nRisk: Expired sessions or missing browser tabs can produce misleadingly empty responses.\n\nMitigation: Check the signed-in session and keep a signed-in portal tab open before interpreting empty results.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth endpoint recipes](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance]\n\n**Output Format:** [Markdown with shell commands and JSON query examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Retrieved patient records can contain sensitive personal health and insurance information.]\n\n## Skill Version(s):\n\n1.3.1 (source: server-resolved ClawHub release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.3.0: 5 files, 9777 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2378b), SKILL.md (4170b), _meta.json (137b)\n\nFile v1.3.0:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the Transporter Chrome extension\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the Transporter popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.0\",\n  \"publishedAt\": 1790264069201\n}\n\nFile v1.3.0:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.3.0:skill-card.md\n\n## Description:\n\nRead MyAtriumHealth, Atrium Health's Epic MyChart patient portal, from a shell with the fpx CLI by relaying requests through the user's signed-in Chrome tab.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to retrieve their own MyAtriumHealth/MyChart records from a signed-in Chrome session for shell scripts or one-shot analysis.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can expose sensitive health information from the user's signed-in MyAtriumHealth session.\n\nMitigation: Treat MAH_TOKEN and command output as sensitive health information, avoid saving raw responses or shell logs, and sign out when finished.\n\nRisk: The fpx bridge relays requests through a trusted browser session.\n\nMitigation: Install only when this relay behavior is intended, review the declared profile scope before pairing, and remove the fpx profile or Transporter trust when no longer needed.\n\nRisk: Expired sessions or missing browser tabs can produce login pages, empty responses, or empty JSON results.\n\nMitigation: Use mah_signed_in before relying on results and re-authenticate or reopen the MyAtriumHealth tab when the helper reports a missing or expired session.\n\n## Reference(s):\n\n- [MyAtriumHealth skill page](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth portal](https://my.atriumhealth.org/myatriumhealth)\n- [Endpoint recipes](references/endpoints.md)\n- [Shell helpers](references/mah.sh)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown with inline shell commands and shell helper functions]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Commands can output JSON API responses containing sensitive personal health information; project responses with jq and avoid storing raw output.]\n\n## Skill Version(s):\n\n1.3.0 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.2: 5 files, 9884 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2584b), SKILL.md (4170b), _meta.json (137b)\n\nFile v1.2.2:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the Transporter Chrome extension\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the Transporter popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.2.2\",\n  \"publishedAt\": 1790199695454\n}\n\nFile v1.2.2:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.2:skill-card.md\n\n## Description:\n\nRead MyAtriumHealth patient portal data from a shell by using the fpx CLI to relay requests through the user's signed-in Chrome tab.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use this skill to retrieve their own MyAtriumHealth data, including test results, medications, allergies, immunizations, health issues, visits, goals, and messages, for scripting or one-shot shell workflows. It is intended for use only with the signed-in user's own patient portal account.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can give shell commands broad, persistent access to live MyChart health data through a signed-in browser session.\n\nMitigation: Install it only when shell-level access to the user's own MyAtriumHealth data is intended, run it on a private machine, and revoke the fpx or extension pairing when persistent access is no longer needed.\n\nRisk: Raw command output may expose personal health information in terminals, shell history, logs, or saved files.\n\nMitigation: Avoid saving raw outputs or tokens, project responses with jq to the minimum needed fields, and handle terminal output as sensitive health data.\n\nRisk: Commands rely on the user's active browser session and may produce misleading empty results when the session is expired or the bridge is unavailable.\n\nMitigation: Run the provided session checks before data access and review command behavior before relying on returned results.\n\n## Reference(s):\n\n- [MyAtriumHealth endpoints - verified recipes](artifact/references/endpoints.md)\n- [MyAtriumHealth helper script](artifact/references/mah.sh)\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with shell command examples and a Bash helper script]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [The generated commands and helper functions can return live patient portal data and should be reviewed before execution.]\n\n## Skill Version(s):\n\n1.2.2 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.1: 5 files, 9853 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2533b), SKILL.md (4170b), _meta.json (137b)\n\nFile v1.2.1:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the Transporter Chrome extension\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the Transporter popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.2.1\",\n  \"publishedAt\": 1790178456426\n}\n\nFile v1.2.1:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.1:skill-card.md\n\n## Description:\n\nReads MyAtriumHealth data such as test results, medications, allergies, immunizations, health issues, visits, goals, insurance, care team, and messages from a signed-in Chrome session using fpx shell helpers.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and account holders use this skill to query their own MyAtriumHealth MyChart data from shell scripts or one-shot agent workflows through a signed-in browser session.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can expose sensitive MyChart health, insurance, identity, and message data through authenticated portal requests.\n\nMitigation: Install only for intentional access to your own account, treat all command output as protected health and identity data, avoid saving raw responses, and project responses to the minimum fields needed.\n\nRisk: The persistent fpx and Chrome extension trust grant can allow broad authenticated request relay within the MyAtriumHealth portal.\n\nMitigation: Review the declared fpx profile scope before pairing, keep the browser session limited to intended use, and revoke or re-pair the trust grant when scope changes.\n\nRisk: Expired sessions or missing relay tabs can return login pages, empty bodies, or empty JSON that may look like successful calls.\n\nMitigation: Run the provided session checks before relying on results, treat empty output as a sign-in or bridge problem, and reauthenticate when needed.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth endpoints](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown guidance with bash helper functions and jq command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Generated commands can relay authenticated portal requests and print sensitive health, insurance, identity, and message data to stdout.]\n\n## Skill Version(s):\n\n1.2.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.2.0: 5 files, 9941 bytes\n\nFiles: references/endpoints.md (6838b), references/mah.sh (6264b), skill-card.md (2691b), SKILL.md (4170b), _meta.json (137b)\n\nFile v1.2.0:SKILL.md\n\n---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the Transporter Chrome extension\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the Transporter popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the status code\n\nMyChart answers an **expired session with HTTP 200 whose body is the login page**, and\nthe JSON endpoints then quietly return `{}`. A status check would report success\nforever. `mah_signed_in` tests the body — use it when results come back empty. Sessions\nare short-lived; expect to sign in again between uses.\n\nThere is a second, sneakier false green: an **empty** body. fetchproxy issues requests\nfrom *inside* a tab on the target host, so with no my.atriumhealth.org tab open it\nrelays nothing — and empty text contains no login marker, so a naive \"is this the login\npage?\" check reports SIGNED IN for a response that never happened. `mah_signed_in`\nchecks emptiness first and returns `2` with the real remedy (exit `1` means signed out,\n`0` means signed in).\n\n## Exit codes (fpx)\n\n`0` ok · `1` usage · `2` bridge unavailable (extension not connected, or pairing not\napproved) · `3` bot wall · `4` upstream HTTP error.\n\nData goes to stdout, pair codes and status to stderr — so `| jq` stays clean.\n\n## Messages\n\n`mah_messages [folderTag]` reads the Message Center. It is the one endpoint that cannot\nbe called with `{}`: it needs a five-key body whose `PageNonce` is the CSP nonce of an\n`/app/*` page, and whose `externalLoadParams` must list the **non-local** organizations\nonly (filter `api/conversations/GetOrganizations` on the explicit `isLocal` flag —\npassing the local org returns HTTP 500). The helper handles all of that.\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.2.0\",\n  \"publishedAt\": 1790020899475\n}\n\nFile v1.2.0:references/endpoints.md\n\n# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    mah_api health-summary/FetchHealthSummary | jq '{patientFirstName, actionPlans}'\n    mah_api conversations/GetFoldersList     | jq '.folders'      # [{tag, badgeCount, totalCount}]\n    mah_api search/LoadMenuInfo              | jq '[.submenus[] | {menu: .name, items: [.menuItems[].name]}]'\n\nFolder tags seen: `1` Conversations/inbox, `2` Archive, `3`, `6`, `7`\n(Bookmarked / Appointments / Automated — exact mapping unconfirmed).\n\n## Insurance\n\n    mah_legacy_form Insurance/Coverages/GetCoverages 'isStandAlone=true' | jq '.ActiveCoverages'\n\nNeeds the form body `isStandAlone=true`; an empty body returns the \"Oops!\" page.\nCoverages arrive in five buckets — `ActiveCoverages`, `CoveragesPendingSubmission`,\n`CoveragesPendingDeletion`, `CoveragesInReview`, `CoveragesInVerification` — so check\nall of them, not just the first. Each item has `CoverageName`, `PlanName`, `PayorName`,\n`MemberId`, `GroupNumber`, `Status`, `CoverageType`, `FormattedEffectiveDate`,\n`FormattedEndDate`, `SubscriberName`, `PatientIsSubscriber`, `Termed` and more.\n\n## Care team\n\n    mah_legacy Clinical/CareTeam/Load \"hfrId=&sources=&actions=&isPrimaryStandalone=true&ComponentNumber=2\" \\\n      | jq '[.ProvidersList[] | {name: .Name, specialty: .Specialty, relation: .Relation}]'\n\n`LoadExternal` (same query minus `isPrimaryStandalone`) returns providers at linked\noutside organizations. The page shows the union of both — de-duplicate on `.ID`.\n\nBilling is server-rendered with **no data endpoint**; the MCP's\n`mah_list_billing_accounts` parses it. Documents renders no list on its landing page and\nhas not been captured.\n\n## Visits (legacy form-encoded endpoints — use `mah_legacy`)\n\n    mah_legacy Visits/VisitsList/LoadUpcoming \"timeZone=America%2FNew_York&ComponentNumber=5\" \\\n      | jq '{next: .NextNDaysVisits, later: .LaterVisitsList, inProgress: .InProgressVisits}'\n\n    NOW=$(date -u +%Y-%m-%dT%H:%M:%S.000Z)\n    mah_legacy Visits/VisitsList/LoadPast \"loadpast=1&searchString=&oldestRenderedDate=$NOW&ComponentNumber=7\" \\\n      | jq '[.List[] | .Organization.OrganizationName as $o\n             | .List[] | {org: $o, date: .PrimaryDate, bucket: .PastVisitBucket, csn: .Csn}]'\n\nPast visits are grouped by an opaque organization handle under `.List`.\n\n---\n\n## Messages\n\n    mah_messages       | jq '[.conversations[] | {subject, preview: .previewText,\n                              date: .messages[0].deliveryInstantISO,\n                              unread: ([.messages[].isUnread] | any)}]'\n    mah_messages 2     | jq '.conversations | length'    # 2 = Archive\n\n`POST api/conversations/GetConversationList` needs a five-key body, and every part\nmatters — this is the one endpoint here that cannot be called with `{}`:\n\n    {\"tag\":1,\n     \"localLoadParams\":{\"loadStartInstantISO\":\"\",\"loadEndInstantISO\":\"\",\"pagingInfo\":1},\n     \"externalLoadParams\":{\"<external org handle>\":{\"communicationCenter\":{…same three…}}},\n     \"searchQuery\":\"\",\n     \"PageNonce\":\"<32-hex CSP nonce from an /app/* page>\"}\n\n**`externalLoadParams` takes the NON-local organizations only.** Get them from\n`api/conversations/GetOrganizations` (which does take `{}`) and filter on the explicit\n`isLocal` flag. Passing the local organization — or the handles from the visits\nresponse, which include it — returns HTTP 500.\n\nResponse: `{conversations[], users, viewers, localSummary, externalSummaries,\nlegacyXUnreadCount}`. Each conversation has `subject`, `previewText`, `messageType`,\n`hasAttachments`, `hasUrgentMsgs`, `organizationId` and `messages[]`\n→ `{author, body, deliveryInstantISO, isUnread, attachments, tasks}`.\n\nDo not try to satisfy the nonce by generating values — it is an anti-CSRF control;\nread the one the server sent (`mah_nonce`).\n\n`api/item-feed/FetchItemFeed` still needs parameters that have not been captured.\n\nFile v1.2.0:skill-card.md\n\n## Description:\n\nRead MyAtriumHealth patient portal data such as test results, medications, allergies, immunizations, health issues, visits, goals, insurance, care team, and messages from a shell by relaying requests through a signed-in Chrome tab.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and technically proficient users use this skill to retrieve their own MyAtriumHealth data for scripting, one-shot inspection, and JSON projection without running the myatriumhealth-mcp server. It is intended for authenticated access to the signed-in user's own patient portal data.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can relay broad authenticated requests from a signed-in MyAtriumHealth browser session and expose highly sensitive health information.\n\nMitigation: Use it only with the documented read-only recipes, only for the signed-in user's own account, and revoke the fpx/Transporter pairing when ongoing access is no longer needed.\n\nRisk: Command output may contain protected health information that could be retained in shell history, terminal logs, files, or shared debugging artifacts.\n\nMitigation: Project responses with jq to the minimum fields needed, avoid saving raw responses, and keep outputs out of shared logs or files.\n\nRisk: Expired sessions, MFA prompts, or a missing relay tab can produce misleading empty or login-page responses.\n\nMitigation: Check session state with mah_signed_in before interpreting empty results, and sign in again when the helper reports a missing bridge or auth wall.\n\n## Reference(s):\n\n- [MyAtriumHealth endpoint recipes](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n- [MyAtriumHealth portal](https://my.atriumhealth.org/myatriumhealth)\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Shell commands, Configuration, Code, JSON]\n\n**Output Format:** [Markdown guidance with shell commands and jq-oriented JSON output recipes]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Outputs can contain protected health information and should be minimized, projected, and handled as sensitive data.]\n\n## Skill Version(s):\n\n1.2.0 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.","readmeExcerpt":"Skill: myatriumhealth-mcp Owner: chrischall Summary: Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server. Tag","codeSnippets":[],"executableExamples":[],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: myatriumhealth-fpx\ndescription: >-\n  Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test\n  results, medications, allergies, immunizations, health issues, visits, goals\n  — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests\n  through your signed-in Chrome tab. Use when you want your MyChart data in a\n  script or one-shot without running the myatriumhealth-mcp server.\n---\n\n# MyAtriumHealth via fpx\n\nAtrium Health's patient portal is Epic MyChart at `my.atriumhealth.org`. Its web app\ntalks to a clean JSON API, and this skill drives that same API through your signed-in\nbrowser tab.\n\n**Why the browser is required:** every MyChart cookie is `HttpOnly`, so the session\ncannot be read or reproduced outside the browser, and login is MFA-gated. Requests are\nrelayed through the tab; the session cookie is never extracted or stored.\n\nThis reads personal health information. It only ever touches the signed-in user's own\naccount.\n\n## One-time setup\n\n    npm i -g @fetchproxy/cli          # also needs the ContextMint Bridge extension\n\nContextMint Bridge comes from\nhttps://github.com/nullnet-app/contextmint-bridge/releases (Chrome: load the `chrome`\nzip unpacked; use Chrome for now — Safari will ship inside the ContextMint app, which\nhas no public download yet). It is the fetchproxy extension renamed, same maintainer;\nsource is public there — build it, or verify a zip with `shasum -a 256 -c <zip>.sha256`.\n\nCreate the profile with its **full scope declared up front** — widening scope later\ninvalidates the grant and forces a re-pair:\n\n    fpx profile add myatriumhealth --domain atriumhealth.org\n    fpx profile declare myatriumhealth \\\n      --cookie '_Host-MyChart_Session' \\\n      --cookie '__RequestVerificationToken_L215YXRyaXVtaGVhbHRo0' \\\n      --cookie '_Host-MyChartLocale' --cookie 'MYCPERS' --cookie 'p-MYC-LBPersistence' \\\n      --capture-header 'cookie@my.atriumhealth.org'\n\nThen sign in to MyAtriumHealth in Chrome and run any command below. The first one\nprints a pair code — approve it in the ContextMint Bridge popup. The trust persists.\n\n## Use it\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"      # cache once per shell\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem | {name, severe: .isSevere}]'\n\n`mah_api <area/Action> [json-body]` posts to the modern `api/…` endpoints (body\ndefaults to `{}`, which is all most of them need). `mah_legacy <Area/Controller/Action>\n[querystring]` handles the older form-encoded ones (visits).\n\nEvery call needs the ASP.NET antiforgery token — `mah_token` scrapes it from a\nsigned-in page and the helpers attach it. Responses are large (test results 33 KB,\nmedications 30 KB); always project with `jq`.\n\n**See `references/endpoints.md`** for the full endpoint list with ready-to-run,\nlive-verified `jq` recipes, and `references/mah.sh` for the helpers.\n\n## Check the session, not the"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"myatriumhealth-mcp\",\n  \"version\": \"1.3.6\",\n  \"publishedAt\": 1791588357972\n}"},{"path":"references/endpoints.md","content":"# MyAtriumHealth endpoints — verified recipes\n\nEvery recipe below was run against a live signed-in session. `source mah.sh` first and\ncache the token once per shell:\n\n    source references/mah.sh\n    mah_signed_in || echo \"sign in to MyAtriumHealth in Chrome first\"\n    export MAH_TOKEN=\"$(mah_token)\"       # 172 chars; avoids re-fetching a 137KB page per call\n\nResponse envelopes are large (test results 33KB, medications 30KB) — always project\nwith `jq` rather than printing whole responses.\n\n---\n\n## Allergies\n\n    mah_api allergies/LoadAllergies | jq '[.dataList[].allergyItem\n      | {name, severe: .isSevere, reactions: [.reactionList[]?.name]}]'\n\n`dataList[].allergyItem` → `{id, name, reactionList[], classification, isSevere, priority, displayType}`.\n`localItem` repeats the same shape for this organization; `externalItems`/`externalOrgs`\ncarry the same allergy as recorded at linked outside organizations.\n\n## Health issues (problem list)\n\n    mah_api HealthIssues/LoadHealthIssuesData | jq '[.dataList[].healthIssueItem\n      | {name, noted: .formattedDateNoted}]'\n\n`healthIssueItem` → `{name, id, formattedDateNoted, action, isReadOnly}`.\n\n## Immunizations\n\n    mah_api immunizations/LoadImmunizations | jq '[.organizationImmunizationList[]\n      | {org: .organization.OrganizationName?} + {shots: [.orgImmunizations[] | {name, dates: .formattedAdministeredDates}]}]'\n\nGrouped per organization: `organizationImmunizationList[].orgImmunizations[]`\n→ `{id, name, formattedAdministeredDates}`.\n\n## Medications\n\n    mah_api medications/LoadMedicationsPage | jq '[.communityMembers[]\n      | .prescriptionList.prescriptions[]?\n      | {name, friendly: .patientFriendlyName, sig, provider: .authorizingProvider}]'\n\n`communityMembers[]` is one entry per organization; each has\n`prescriptionList.prescriptions[]` → `{name, patientFriendlyName, sig,\nprescriptionNumber, authorizingProvider, orderingProvider, dateToDisplay,\nisPatientReported, …}`. `sig` is the dosing instruction text.\n\n## Test results\n\n    # index of result groups (visits), newest first\n    mah_api test-results/GetList | jq '[.newResultGroups[]\n      | {date: .formattedDate, type: .contactType, count: (.resultList | length)}]'\n\n    # the results themselves — newResults is a MAP keyed by an opaque handle\n    mah_api test-results/GetList | jq '[.newResults[]\n      | {name, abnormal: .isAbnormal,\n         when: .orderMetadata.prioritizedInstantDisplay,\n         provider: .orderMetadata.orderProviderName,\n         comments: [.providerComments[]?.content]}]'\n\n`newResultGroups[].resultList` is an array of **strings** — handles into `newResults`.\n`resultComponents` is empty in the list view (individual values load on the detail page).\n`orderMetadata` → `{orderProviderName, authorizingProviderName, prioritizedInstantISO,\nprioritizedInstantDisplay, resultType, read}`.\n\n## Goals\n\n    mah_api goals/LoadPatientGoals | jq '[.patientGoals[] | {goalId, goalType, lastUpdatedDate}]'\n\n## Health summary / menu / folders\n\n    m"},{"path":"skill-card.md","content":"## Description:\n\nHelps users read their own MyAtriumHealth records through a signed-in Chrome tab using shell commands, without running the MyAtriumHealth MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nPeople accessing their own MyAtriumHealth account, including developers writing personal scripts, can retrieve and filter health records, visits, and messages through their signed-in browser session.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Persistent browser access to a sensitive healthcare account can expose private records.\n\nMitigation: Install only if you trust the browser extension and CLI, use your own account, and remove the profile or extension when no longer needed.\n\nRisk: Broad shell helpers can read sensitive records and expose tokens or output to untrusted scripts or logs.\n\nMitigation: Review scripts before use, keep tokens and command output private, and limit output to the fields needed.\n\nRisk: Expired sessions or a missing browser tab can make results appear empty or successful.\n\nMitigation: Check that the browser session is active before trusting empty results, and sign in again when needed.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/myatriumhealth-mcp)\n- [MyAtriumHealth endpoint recipes](references/endpoints.md)\n- [MyAtriumHealth shell helpers](references/mah.sh)\n- [ContextMint Bridge extension releases](https://github.com/nullnet-app/contextmint-bridge/releases)\n\n## Skill Output:\n\n**Output Type(s):** [Shell commands, Guidance, JSON]\n\n**Output Format:** [Shell examples and JSON responses]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Responses can contain sensitive personal health information; filter before sharing or storing.]\n\n## Skill Version(s):\n\n1.3.6 (source: ClawHub release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server. Skill: myatriumhealth-mcp Owner: chrischall Summary: Read MyAtriumHealth (Atrium Health's Epic MyChart patient portal) — test results, medications, allergies, immunizations, health issues, visits, goals — from a shell with the fpx CLI (@fetchproxy/cli), by relaying requests through your signed-in Chrome tab. Use when you want your MyChart data in a script or one-shot without running the myatriumhealth-mcp server. Tag","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1553,"uniquenessScore":46,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T16:02:40.375Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T21:00:25.426Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}