diff --git a/CLAUDE.md b/CLAUDE.md index a27bbf2..a523ab9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file is auto-loaded by Claude Code when it opens `~/OpenKP/`. It's the on-r ## What OpenKP is -A local MCP server that bridges Claude and Kaiser Permanente's patient portal. Single-user, runs on Hugo's Mac. All credentials and PHI stay on the machine. MIT licensed. No hosted service. See `DESIGN.md` §1-2 for the full "why." +A local MCP server that bridges Claude and Kaiser Permanente's patient portal. Single-user, runs on Hugo's Mac (and also tested on Windows — see `docs/install/windows.md`). All credentials and PHI stay on the machine. Licensed under PolyForm Noncommercial 1.0.0 (see ADR-007). No hosted service. See `DESIGN.md` §1-2 for the full "why." ## v1 audience and distribution @@ -12,7 +12,7 @@ OpenKP v1 ships as an open-source GitHub project for **technically-curious KP me What this means for current work: -- Keep the architecture unchanged. Local-first, MCP-over-stdio, Mac-first is fine. +- Keep the architecture unchanged. Local-first, MCP-over-stdio. Mac is the primary tested platform, Windows runs the same code with a handful of platform-specific setup steps (`docs/install/windows.md`). - The README must read well for a curious human AND be structured enough for Claude Code to walk a user through install end-to-end. - Error messages should be clear, but they don't need to be tuned for non-technical users yet. - Lead positioning with the CAIHL frame: patient-directed AI on patient-owned data, not "AI reads my chart." @@ -50,6 +50,10 @@ See `DESIGN.md` §1 (audience), §5 (Phase 4 / 4.5), §10 (distribution strategy **Website:** [openkp.org](https://openkp.org) live on Cloudflare Pages as of 2026-05-11 (commit `25a7259`, see session-20). Source under `site/` — static single-page, no build step, no framework. CAIHL framing in copy, MCP-client-agnostic at runtime. Codex drafted, two review passes, then deployed via wrangler direct upload. Future deploys from repo root: `wrangler pages deploy site --project-name=openkp --branch=main --commit-dirty=true`. Public repo is live, so you can also switch the Pages project to GitHub auto-deploy any time via the Cloudflare dashboard — no longer gated on anything. +**Site refresh 2026-05-27:** the hero panel is now a 3-slide carousel (visit notes engagement, implants inventory, unresolved message threads) that auto-rotates every 5 seconds with dot navigation, per-slide topic tag, and accent-color shift per slide. Each topic tag leads with a tiny inline-SVG line icon (document for visit notes, device-plus-ECG-lead for implants, envelope for messages) that inherits the per-slide accent via `currentColor`; the icons are decorative (`aria-hidden`) so the tag text stays the accessible label. The tools section reads "24 MCP tools" with a `Care team, specialists, implanted devices` bullet for the new reads. The install card carries a short Windows-supported note linking to `docs/install/windows.md`. Implementation lives in `site/index.html` (HTML), `site/styles.css` (`.hero-carousel*`, `.slide-tag`, `.carousel-dot*`), and `site/script.js` (carousel rotation, pauses on hover/focus, respects `prefers-reduced-motion`). + +**Relicense 2026-05-27 (ADR-007):** OpenKP moved from MIT to **PolyForm Noncommercial 1.0.0**. The relicense reflects Hugo's intent that OpenKP serve patients and not be extracted commercially. Free for personal, research, educational, advocacy, nonprofit, and government use. Commercial use (paid SaaS, paid consulting, embedding in paid products) requires a separate license. `openkp/LICENSE` carries the canonical PolyForm text plus a `Required Notice: Copyright (c) 2026 Hugo Campos` line. Snapshots cloned under MIT before 2026-05-27 remain MIT for whoever has them — we can't claw back what's been licensed. Doc refs, `pyproject.toml`, and `site/index.html` final-CTA all updated. See `docs/adr/007-relicense-to-polyform-noncommercial.md`. + ## Next session: start here Public release is done. Open code work is below. @@ -106,7 +110,7 @@ header capture. - `DESIGN.md` — vision, principles, architecture, roadmap, tool inventory, safety patterns. Single source of truth. - `docs/release-checklist.md` — pre-public-release todos. All hard blockers now closed: README, LICENSE, PHI history rewrite (via fresh-repo strategy), and website are all done. Repo is public at github.com/hugooc/OpenKP. - **Recon journals live in the gitignored sidecar** at `private/documentation/recon/` (consolidated 2026-05-10 from `~/Desktop/OpenKP Documentation/`; the whole `private/` tree is gitignored). The last few are the most relevant context: session-20 (openkp.org site review + deploy + custom domain + repo-state reconciliation, 2026-05-11), session-19 (Codex audit + release hygiene + PHI rewrite + sidecar consolidation, 2026-05-10), session-18 (click-around recon, 2026-05-06), session-17 (PHI scrub + READMEs), session-16 (visit notes + AVS). -- `docs/adr/README.md` — architectural decisions index. ADRs 001-006 live here. +- `docs/adr/README.md` — architectural decisions index. ADRs 001-007 live here. - `docs/research/endpoints/` — per-endpoint request/response maps. Start with `profile.md`. ## Work pattern for a new read tool diff --git a/DESIGN.md b/DESIGN.md index 8af92e0..96a7190 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -16,7 +16,7 @@ Kaiser's sanctioned FHIR patient API is read-only and capped to USCDI. That limi ### What OpenKP is -A local MCP server that runs on the user's Mac, exposes patient-portal actions to Claude via the Model Context Protocol, and keeps all credentials and PHI on the user's machine. +A local MCP server that runs on the user's machine (macOS and Windows are both tested, see `docs/install/windows.md`), exposes patient-portal actions to Claude via the Model Context Protocol, and keeps all credentials and PHI local. ### What OpenKP is not @@ -45,7 +45,7 @@ These are the non-negotiables. Every design decision traces back to one of them. 4. **Everything is auditable.** Every write action is logged locally with timestamp, inputs, and Kaiser's response. The user can always answer "what did my AI do in my record?" -5. **Open source, MIT licensed.** Anyone can fork, inspect, modify, or redistribute. Unlike Open Record's source-available license, OpenKP imposes no commercial or redistribution restrictions. +5. **Source-available, noncommercial license.** OpenKP ships under PolyForm Noncommercial 1.0.0. Anyone can fork, inspect, modify, redistribute, and use it for any noncommercial purpose — personal, research, educational, advocacy, nonprofit, government. Commercial use (paid SaaS, paid consulting, embedding in paid products) requires a separate license from the maintainer. Originally MIT-licensed at public launch in May 2026; relicensed via ADR-007 to align with the maintainer's intent that OpenKP serve patients rather than commercial extraction. 6. **Stand on shoulders, don't copy code.** Open Record is our conceptual predecessor. We learn from its architecture, its tool surface, and its docs. We do not copy its code. @@ -204,7 +204,7 @@ Each phase has an explicit exit criterion. We do not move to the next phase unti 4. License surface, security disclosure path, code of conduct. 5. Announcement to the CAIHL-adjacent community. -**Out of scope for Phase 4:** bundled installer, `.dxt` packaging, signing/notarization, GUI credential entry, cross-platform builds beyond what currently works on the author's Mac. These move to Phase 4.5 if real demand emerges. +**Out of scope for Phase 4:** bundled installer, `.dxt` packaging, signing/notarization, GUI credential entry, cross-platform packaging beyond the source-install path (which works today on macOS and Windows — see `docs/install/windows.md`). These move to Phase 4.5 if real demand emerges. **Exit criterion:** A KP member who knows what a terminal is, with Claude Code installed, can clone the repo and complete a successful end-to-end query of their own record (e.g., "summarize my last lipid panel") without needing to ask the author for help. @@ -463,7 +463,7 @@ The log is append-only. The user can review it at any time to see exactly what O See Section 5 roadmap phases 4, 4.5, and 5 for the full distribution plan. Summary: 1. **Now (Phases 1-3):** Build the read and write tools to a credible MVP. Local install for the author and a small group of contributors. -2. **Phase 4 (next public step):** GitHub release. README structured for both human readers and Claude Code as the install agent. Audience is technically-curious KP members. Mac-first is acceptable in v1 as long as it's called out clearly. +2. **Phase 4 (next public step):** GitHub release. README structured for both human readers and Claude Code as the install agent. Audience is technically-curious KP members. macOS is the primary tested platform, with Windows now supported via a short addendum (`docs/install/windows.md`). 3. **Phase 4.5 (only if demand justifies it):** `.dxt` installer, bundled runtime, GUI credential entry, signing and notarization, install video. Cross-platform if Windows demand emerges. 4. **Phase 5 (maybe):** Chrome extension architecture if Playwright maintenance becomes painful. 5. **Never:** hosted service. The legal and ethical costs outweigh any convenience gain. @@ -474,7 +474,7 @@ See Section 5 roadmap phases 4, 4.5, and 5 for the full distribution plan. Summa Open Record, by Ryan Hughes at Fan Pier Labs, is the prior art and conceptual source for this project. OpenKP does not use any of Open Record's code. We are deliberately implementing from scratch because: -1. Open Record's license is source-available and restricts commercial use and redistribution. OpenKP is MIT-licensed. +1. Open Record's license is source-available and restricts commercial use and redistribution. OpenKP is licensed under PolyForm Noncommercial 1.0.0 (also source-available, also restricts commercial use, but defined in plain-English software-native terms instead of Open Record's bespoke clauses). See ADR-007. 2. Open Record targets vanilla Epic MyChart. Kaiser is a different auth architecture (Ping OAuth in front of Epic). The 896-line MyChart login is not reusable. 3. Open Record is a full web application with Postgres, user accounts, and a Gemini AI proxy. OpenKP is a single-user local tool. The web app scaffolding is overhead we don't need. @@ -488,7 +488,7 @@ Open Record, by Ryan Hughes at Fan Pier Labs, is the prior art and conceptual so **What we do differently:** - Python instead of TypeScript/Bun (solo-builder velocity) - Single-user local instead of multi-tenant web app -- MIT license instead of source-available +- PolyForm Noncommercial 1.0.0 (also source-available, but plain-English software-native terms) - Safety patterns (confirm-before-act, audit log, dry-run) as first-class, not afterthoughts - CAIHL framing as the organizing purpose, not an incidental benefit @@ -605,7 +605,7 @@ Open Record, by Ryan Hughes at Fan Pier Labs, is the prior art and conceptual so |---|---|---| | Python over TypeScript | TypeScript (matches Open Record) | Faster solo iteration; Playwright Python is mature; simpler packaging for `.dxt` | | Playwright over pure HTTP | Raw httpx + Ping OAuth library | Ping's JS-driven login and device fingerprinting make pure HTTP fragile; Playwright pays the reliability tax upfront | -| MIT license | Source-available | We want this to be reusable by anyone, including researchers and other patient-advocacy projects | +| PolyForm Noncommercial 1.0.0 | MIT (original v1), then revisited | Originally MIT at public launch (2026-05-11). Relicensed via ADR-007 on 2026-05-27 to PolyForm NC. Still source-available and freely reusable for individuals, researchers, advocates, nonprofits, and government, but no commercial extraction without a separate license. Aligns the legal terms with the maintainer's intent. | | Single-user local | Multi-tenant hosted | Privacy ethics and legal liability both favor local; also sidesteps HIPAA BAA complexity | | FastMCP over raw MCP SDK | Raw MCP SDK | Decorator syntax is cleaner; official Anthropic recommendation | | Keychain for credentials | Encrypted `.env` with master password | OS keychain is the system's existing answer to this problem; no need to reinvent | diff --git a/README.md b/README.md index 8544df4..309bd61 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Website: [openkp.org](https://openkp.org) -A patient-directed MCP server that bridges Claude and **Kaiser Permanente Northern California's** patient portal — letting you act on your own medical record, with your own credentials, on your own Mac. +A patient-directed MCP server that bridges Claude and **Kaiser Permanente Northern California's** patient portal — letting you act on your own medical record, with your own credentials, on your own machine. Tested on macOS and Windows. ``` You ─► Claude Desktop ─► OpenKP (local) ─► kp.org @@ -18,7 +18,7 @@ Kaiser's portal shows you plans, orders, and results. It doesn't show you how *y This is **critical AI health literacy** in practice — patient-directed AI on patient-owned data, surfacing what institutional systems are not built to make legible. Background: ["Critical AI Health Literacy as Liberation Technology"](https://nam.edu/perspectives/critical-ai-health-literacy-as-liberation-technology-a-new-skill-for-patient-empowerment) (NAM Perspectives) and [aipatients.org](https://aipatients.org). -OpenKP exposes 17 read tools and 2 write tools covering appointments, labs, messages, medications, problems, allergies, demographics, visit notes, and after-visit summaries. Other questions it can handle: +OpenKP exposes 19 read tools and 2 write tools covering appointments, labs, messages, medications, problems, allergies, demographics, visit notes, after-visit summaries, care team and recent providers, and implanted devices. Other questions it can handle: - *"How many appointments did I have last year, split by virtual vs in-person?"* - *"Which lab values have drifted in the last 18 months?"* @@ -47,6 +47,8 @@ Install steps live in [`openkp/README.md`](openkp/README.md). It walks through v If you have Claude Code installed, the easiest path is to clone this repo and ask Claude Code to walk you through the install — `openkp/README.md` is structured for exactly that flow. +**On Windows?** Same instructions, plus a couple of platform-specific setup steps. See [`docs/install/windows.md`](docs/install/windows.md) for the Visual C++ runtime requirement, the `greenlet` reinstall, and the Windows command translations. + ## What's inside ``` @@ -55,6 +57,7 @@ OpenKP/ ├── DESIGN.md ← vision, architecture, roadmap, principles ├── docs/ │ ├── adr/ ← architecture decision records (ADR-001 onward) +│ ├── install/ ← platform-specific install notes (windows.md) │ ├── research/endpoints/ ← per-endpoint Kaiser API maps │ └── release-checklist.md ← pre-public-release todos ├── openkp/ ← the Python package + tests + install README @@ -72,11 +75,13 @@ The full list lives in `DESIGN.md` §2. The three that matter most: ## Status -Phase 2 (read-only) is closed. Phase 3 (writes) is in progress. As of 2026-05-04: 22 MCP tools registered, 527 tests passing, run with `cd openkp && .venv/bin/pytest -q`. Per-tool status (live-verified, preview-only, deferred) is documented in `openkp/README.md`. +Phase 2 (read-only) is closed. Phase 3 (writes) is in progress. As of 2026-05-26: 24 MCP tools registered, 567 tests passing on macOS, run with `cd openkp && .venv/bin/pytest -q`. Per-tool status (live-verified, preview-only, deferred) is documented in `openkp/README.md`. Windows is supported with the caveats in [`docs/install/windows.md`](docs/install/windows.md) — all but 4 platform-specific tests pass, and none of the failures affect any user-facing tool. ## License -MIT. See [`openkp/LICENSE`](openkp/LICENSE). +**PolyForm Noncommercial 1.0.0.** Free for personal, research, educational, advocacy, nonprofit, and government use. Commercial use (paid SaaS, paid consulting, embedding in paid products) requires a separate license from the maintainer. See [`openkp/LICENSE`](openkp/LICENSE) for the full text and [`docs/adr/007-relicense-to-polyform-noncommercial.md`](docs/adr/007-relicense-to-polyform-noncommercial.md) for the rationale. + +Snapshots cloned before the relicense remain under MIT for whoever has them — future commits land under PolyForm NC. ## Credits diff --git a/docs/adr/001-build-fresh-vs-fork-open-record.md b/docs/adr/001-build-fresh-vs-fork-open-record.md index d784a2e..5af715d 100644 --- a/docs/adr/001-build-fresh-vs-fork-open-record.md +++ b/docs/adr/001-build-fresh-vs-fork-open-record.md @@ -1,7 +1,7 @@ # ADR-001: Build fresh, don't fork Open Record **Date:** 2026-04-22 -**Status:** Active +**Status:** Active. The license-specific aspects of this decision (mentions of "MIT" below) are superseded by ADR-007, which relicenses OpenKP from MIT to PolyForm Noncommercial 1.0.0. The build-fresh decision itself is unchanged. **Authors:** Hugo Campos ## Context diff --git a/docs/adr/007-relicense-to-polyform-noncommercial.md b/docs/adr/007-relicense-to-polyform-noncommercial.md new file mode 100644 index 0000000..cc41b9e --- /dev/null +++ b/docs/adr/007-relicense-to-polyform-noncommercial.md @@ -0,0 +1,70 @@ +# ADR-007: Relicense from MIT to PolyForm Noncommercial 1.0.0 + +**Date:** 2026-05-27 +**Status:** Active +**Authors:** Hugo Campos + +## Context + +OpenKP launched publicly on 2026-05-11 under the MIT license. The decision to use MIT traces back to ADR-001, where the rationale was: + +> "Open Record's license is source-available and restricts commercial use and redistribution. We want OpenKP to be fully MIT so CAIHL researchers, other patient-advocacy projects, and future maintainers have no friction." + +That reasoning still holds for the audiences we care about, individual patients, researchers, advocates, nonprofits, and government. What's changed is the maintainer's clarified intent about the audiences we don't care about. OpenKP exists because Kaiser's portal isn't built to make a patient's own record legible to them, and the maintainer wants the project to serve patients. The maintainer does not want OpenKP to become an ingredient in a paid product, a paid SaaS, or paid consulting work. The phrase the maintainer used when this surfaced: "this is my gift to the world. I don't want anyone to use what we built to make a buck." + +MIT explicitly allows all of those commercial paths. That's the gap. + +## Decision + +**Relicense OpenKP from MIT to PolyForm Noncommercial 1.0.0**, effective 2026-05-27. + +The PolyForm Noncommercial license is a modern, plain-English, software-native source-available license. Its key terms in plain language: + +- **Free for any noncommercial purpose.** Personal use, research, experimentation, hobby projects, religious observance. +- **Free for noncommercial organizations.** Charitable organizations, educational institutions, public research bodies, public safety / health organizations, environmental protection orgs, and government institutions. +- **Source remains available.** Anyone can fork, inspect, modify, and redistribute under the same terms. +- **Commercial use requires a separate license** from the maintainer. "Commercial" here means "use intended for or directed toward commercial advantage or monetary compensation." + +We chose PolyForm Noncommercial 1.0.0 over the alternatives because: + +- **It's software-native.** Creative Commons licenses (CC BY-NC, CC BY-NC-SA) are widely recognized but Creative Commons themselves recommend against using CC for code — CC was designed for creative works and doesn't address patent grants, sublicensing, or other software-specific concerns. PolyForm was drafted by a panel of software lawyers specifically for code. +- **The "commercial" definition is clear.** PolyForm spells out what counts. CC's NC clause has been litigated in unpredictable ways across jurisdictions. +- **Patent grant is included.** PolyForm gives licensees a patent license alongside the copyright license. MIT had implied-license ambiguity here; CC has nothing. +- **GitHub recognizes it.** The license shows up correctly on the repo page and in API metadata. + +## Consequences + +**What changes for OpenKP users:** + +- New cloners (after 2026-05-27) get PolyForm NC, not MIT. +- The legal text in `openkp/LICENSE` is replaced. The `Required Notice: Copyright (c) 2026 Hugo Campos` line is preserved at the top per PolyForm's notice requirement. +- Doc references to "MIT licensed" are updated everywhere (`README.md`, `CLAUDE.md`, `DESIGN.md`, `openkp/README.md`, `site/index.html`, `pyproject.toml`). + +**What does NOT change:** + +- The architecture, the tool surface, the local-first guarantees. +- Existing MIT clones taken between 2026-05-11 and 2026-05-26 stay under MIT for whoever has them. We can't claw back what's already been licensed under MIT. In practice, the public repo has no visible forks and no commercial deployments at the time of this decision, so the practical surface area of pre-relicense MIT snapshots is near zero. The real moat for any would-be commercial fork is keeping up with Kaiser's portal changes, which the relicense doesn't help with on either side. +- The maintainer can still grant separate commercial licenses to specific parties later. The "dual license" door remains open. + +**What this supersedes:** + +- ADR-001's mentions of MIT licensing (context item 3, consequences bullet). The build-fresh-vs-fork decision itself is unchanged. + +**What this does not address:** + +- A contributor agreement. Today there are no third-party code contributions, so this isn't urgent. If contributions arrive, a lightweight CLA or DCO inbound-equals-outbound model will be needed so contributors agree their contributions are licensed under PolyForm NC. +- A commercial-license offering. Not built. If a real commercial inquiry arrives, the maintainer will decide terms at that point. Until then, the noncommercial license is the only public license OpenKP offers. + +## Operational record + +The relicense was executed in a single commit on 2026-05-27 covering: + +- `openkp/LICENSE` (replaced with PolyForm NC 1.0.0 text + `Required Notice` line) +- `README.md`, `CLAUDE.md`, `DESIGN.md`, `openkp/README.md` (MIT references replaced) +- `openkp/pyproject.toml` (`license` field updated) +- `site/index.html` (final-CTA copy updated) +- `docs/release-checklist.md` (post-launch item 6 updated to mark the LICENSE attribution work as complete via this relicense) +- `docs/adr/001-build-fresh-vs-fork-open-record.md` (status note added pointing here) +- `docs/adr/007-relicense-to-polyform-noncommercial.md` (this file) + +Reference: diff --git a/docs/adr/README.md b/docs/adr/README.md index 7117064..eb901ca 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -20,6 +20,7 @@ Every ADR has the same five sections: - [ADR-004](004-writes-require-confirm-token.md) — Writes require a confirmation token at the tool layer - [ADR-005](005-interactive-first-run-auth.md) — Interactive first-run auth, silent subsequent runs - [ADR-006](006-user-endpoint-piggyback.md) — Piggyback on the pharmacy consumer identity for `/mycare/v1.0/user` +- [ADR-007](007-relicense-to-polyform-noncommercial.md) — Relicense from MIT to PolyForm Noncommercial 1.0.0 ## When to write a new ADR diff --git a/docs/install/windows.md b/docs/install/windows.md new file mode 100644 index 0000000..61e781c --- /dev/null +++ b/docs/install/windows.md @@ -0,0 +1,51 @@ +# OpenKP on Windows + +OpenKP was originally written for macOS and Linux. It runs on Windows too with a couple of extra setup steps. Of 527 tests, 523 pass on Windows. The 4 remaining failures are Linux-specific code paths that don't affect core functionality (reading appointments, labs, messages, visit notes, or any write tool). + +## 1. Environment setup + +### Visual C++ Redistributable + +The `greenlet` package (a transitive Python dependency) fails to load on Windows with a DLL error when the Visual C++ runtime isn't installed. Install it from: + +https://aka.ms/vs/17/release/vc_redist.x64.exe + +### Reinstall greenlet from a pre-built wheel + +After installing the runtime, force-reinstall `greenlet` so pip pulls a pre-built binary instead of compiling from source: + +``` +.venv\Scripts\pip install --force-reinstall --only-binary=:all: greenlet +``` + +## 2. Credentials + +OpenKP stores Kaiser Permanente credentials in a local `.env` file plus the OS keyring. On Windows: + +1. Copy the example file: `copy .env.example .env` +2. Open it in Notepad: `notepad .env` +3. Windows hides dot-files by default. If Notepad won't open it, navigate directly to `C:\Users\\OpenKP\openkp\.env`. +4. Store the password in Windows Credential Manager via `keyring` from inside the venv. + +## 3. Known Windows-only test failures + +These 4 tests fail on Windows but don't affect any user-facing tool: + +| Count | Issue | Detail | +|-------|-------|--------| +| 3 | `%-d` date format | A Linux-only `strftime` directive for stripping leading zeros from day numbers. Windows doesn't support it. | +| 1 | Unix file permissions (`0600`) | Code sets Unix-style file permissions, which don't exist on Windows. | + +## 4. Command translation + +Same operations, different syntax: + +| Purpose | macOS / Linux | Windows | +|---------|---------------|---------| +| Run pytest | `pytest -q` | `.venv\Scripts\pytest -q` | +| Run python | `python script.py` | `.venv\Scripts\python script.py` | +| Run pip | `pip install pkg` | `.venv\Scripts\pip install pkg` | +| Copy a file | `cp file1 file2` | `copy file1 file2` | +| Open a text file | `open file.txt` | `notepad file.txt` | + +All commands should be run from `C:\Users\\OpenKP\openkp` in Command Prompt (or PowerShell, with adjustments to slashes). diff --git a/docs/release-checklist.md b/docs/release-checklist.md index 3dfc482..58b86ea 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -73,5 +73,5 @@ The public repo is live. The following are housekeeping items, none blocking: - `private/rewrite/replacements*.txt` and `private/rewrite/candidates.txt` contain real LHS values from the rewrite. Safe to delete now. The Python/shell scripts and `phi-audit.txt` (counts only) can stay as historical reference if you want. - `private/documentation/` — your call. Most of it (genesis, sample-questions, screenshots, recon journals) you'll likely keep forever for personal reference. - **Pages → GitHub auto-deploy:** optional swap from wrangler direct-upload to Git-connected auto-deploy. See item 5. -- **LICENSE + release-checklist attribution:** optional fixup commit to restore "Hugo Campos" as the copyright holder in `openkp/LICENSE` and the one mention in this file (currently both say "Test Patient" due to the PHI-rewrite blob rule). See item 2. +- **LICENSE + release-checklist attribution:** ~~optional fixup commit to restore "Hugo Campos" as the copyright holder in `openkp/LICENSE` and the one mention in this file (currently both say "Test Patient" due to the PHI-rewrite blob rule). See item 2.~~ **Done 2026-05-27** as part of the PolyForm Noncommercial relicense (see ADR-007). `openkp/LICENSE` now carries the `Required Notice: Copyright (c) 2026 Hugo Campos` line at the top of the new license text. Item 4's historical statement that "openkp/LICENSE exists with standard MIT text" is preserved as a record of v1 launch state. - **`hugooc/OpenKP-private-archive`:** the partial 2026-04-25 snapshot can be deleted or archived at your discretion. It is not load-bearing for the public repo. diff --git a/openkp/LICENSE b/openkp/LICENSE index a6671ca..4580627 100644 --- a/openkp/LICENSE +++ b/openkp/LICENSE @@ -1,21 +1,133 @@ -MIT License - -Copyright (c) 2026 Hugo Campos - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Required Notice: Copyright (c) 2026 Hugo Campos (https://openkp.org) + +# PolyForm Noncommercial License 1.0.0 + + + +## Acceptance + +In order to get any license under these terms, you must agree +to them as both strict obligations and conditions to all +your licenses. + +## Copyright License + +The licensor grants you a copyright license for the +software to do everything you might do with the software +that would otherwise infringe the licensor's copyright +in it for any permitted purpose. However, you may +only distribute the software according to [Distribution +License](#distribution-license) and make changes or new works +based on the software according to [Changes and New Works +License](#changes-and-new-works-license). + +## Distribution License + +The licensor grants you an additional copyright license +to distribute copies of the software. Your license +to distribute covers distributing the software with +changes and new works permitted by [Changes and New Works +License](#changes-and-new-works-license). + +## Notices + +You must ensure that anyone who gets a copy of any part of +the software from you also gets a copy of these terms or the +URL for them above, as well as copies of any plain-text lines +beginning with `Required Notice:` that the licensor provided +with the software. For example: + +> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) + +## Changes and New Works License + +The licensor grants you an additional copyright license to +make changes and new works based on the software for any +permitted purpose. + +## Patent License + +The licensor grants you a patent license for the software that +covers patent claims the licensor can license, or becomes able +to license, that you would infringe by using the software. + +## Noncommercial Purposes + +Any noncommercial purpose is a permitted purpose. + +## Personal Uses + +Personal use for research, experiment, and testing for +the benefit of public knowledge, personal study, private +entertainment, hobby projects, amateur pursuits, or religious +observance, without any anticipated commercial application, +is use for a permitted purpose. + +## Noncommercial Organizations + +Use by any charitable organization, educational institution, +public research organization, public safety or health +organization, environmental protection organization, +or government institution is use for a permitted purpose +regardless of the source of funding or obligations resulting +from the funding. + +## Fair Use + +You may have "fair use" rights for the software under the +law. These terms do not limit them. + +## No Other Rights + +These terms do not allow you to sublicense or transfer any of +your licenses to anyone else, or prevent the licensor from +granting licenses to anyone else. These terms do not imply +any other licenses. + +## Patent Defense + +If you make any written claim that the software infringes or +contributes to infringement of any patent, your patent license +for the software granted under these terms ends immediately. If +your company makes such a claim, your patent license ends +immediately for work on behalf of your company. + +## Violations + +The first time you are notified in writing that you have +violated any of these terms, or done anything with the software +not covered by your licenses, your licenses can nonetheless +continue if you come into full compliance with these terms, +and take practical steps to correct past violations, within +32 days of receiving notice. Otherwise, all your licenses +end immediately. + +## No Liability + +***As far as the law allows, the software comes as is, without +any warranty or condition, and the licensor will not be liable +to you for any damages arising out of these terms or the use +or nature of the software, under any kind of legal claim.*** + +## Definitions + +The **licensor** is the individual or entity offering these +terms, and the **software** is the software the licensor makes +available under these terms. + +**You** refers to the individual or entity agreeing to these +terms. + +**Your company** is any legal entity, sole proprietorship, +or other kind of organization that you work for, plus all +organizations that have control over, are under the control of, +or are under common control with that organization. **Control** +means ownership of substantially all the assets of an entity, +or the power to direct its management and policies by vote, +contract, or otherwise. Control can be direct or indirect. + +**Your licenses** are all the licenses granted to you for the +software under these terms. + +**Use** means anything you do with the software requiring one +of your licenses. diff --git a/openkp/README.md b/openkp/README.md index 7fba875..3b43d20 100644 --- a/openkp/README.md +++ b/openkp/README.md @@ -8,15 +8,15 @@ Inspired by [Open Record](https://github.com/Fan-Pier-Labs/openrecord) by Ryan H ## Status -**Phase 2 (read-only) closed. Phase 3 (writes) in progress.** As of 2026-05-04: +**Phase 2 (read-only) closed. Phase 3 (writes) in progress.** As of 2026-05-26: -- **22 MCP tools** registered: 3 housekeeping, 17 reads, 2 writes (mail-order refill, non-urgent message). -- **527 tests** passing. +- **24 MCP tools** registered: 3 housekeeping, 19 reads, 2 writes (mail-order refill, non-urgent message). +- **567 tests** passing on macOS. Windows runs the same suite with 4 platform-specific failures that don't affect any user-facing tool — see [`docs/install/windows.md`](../docs/install/windows.md). - **NorCal region only** — see "Regional support" below. -Live-verified end-to-end against real Kaiser data: profile, messages, lab results (incl. PDF download), medications, problems, allergies, appointments (upcoming + past), visit notes, AVS, refill *preview*, send-message *preview*, refill order tracking. Commit paths for `request_refill` and `send_message` are unit-tested but not yet exercised live; see the "Write tools — preview vs commit" section. +Live-verified end-to-end against real Kaiser data: profile, messages, lab results (incl. PDF download), medications, problems, allergies, appointments (upcoming + past), visit notes, AVS, care team and recent providers, implanted devices, refill *preview*, send-message *preview*, refill order tracking. Commit paths for `request_refill` and `send_message` are unit-tested but not yet exercised live; see the "Write tools — preview vs commit" section. -The repo is private during this phase but tracks public-release readiness — see `docs/release-checklist.md` at the workspace root. +The repo is now public at [github.com/hugooc/OpenKP](https://github.com/hugooc/OpenKP). The historical pre-launch checklist lives in `docs/release-checklist.md` at the workspace root. ## Regional support @@ -60,7 +60,7 @@ Authentication uses a persistent Chromium profile driven by Playwright. **First You need: -- macOS (tested) or Linux (untested). +- macOS (tested) or Windows (tested, see [`docs/install/windows.md`](../docs/install/windows.md) for platform-specific steps). Linux is untested but should be close to macOS. - Python 3.11 or newer. - A Kaiser Permanente NorCal member account. @@ -99,7 +99,7 @@ From `~/OpenKP/openkp`: .venv/bin/pytest -q ``` -You should see `527 passed`. If anything fails, stop and investigate before going further. +You should see `567 passed` on macOS. On Windows you'll see 4 failures in `_strftime` / file-permission tests — those are platform-specific and harmless. See [`docs/install/windows.md`](../docs/install/windows.md). If anything else fails, stop and investigate. ### 4. First authenticated run (one-time, ~2 minutes) @@ -181,6 +181,8 @@ For write operations: | `list_past_visits` | Past visits, paginated. Supports `max_pages`, `page_size` (default 50, cap 78), and `until_iso`. | | `read_visit_notes` | Clinical notes (provider chart notes, progress notes) + rendered After Visit Summary. | | `download_visit_avs_pdf` | Saves the canonical AVS PDF to `~/.openkp/downloads/`. | +| `list_care_team` | Care team and recent providers — PCP, specialists, recently-seen clinicians, with per-provider capability flags. | +| `list_implants` | Implanted and explanted devices (pacemakers, ICDs, leads, IOLs, ortho hardware) with manufacturer, model, serial, UDI, body area, and implant/explant procedure details. | | `track_refill_order` | Read-side companion to `request_refill`. Surfaces order status, shipping, and tracking. | | `list_message_recipients` | Providers and pools you can message. | | `list_message_topics` | "Reason for Message" catalog (5 topics). | @@ -213,7 +215,7 @@ openkp/ ├── pyproject.toml ← deps, entry point, build config ├── .env.example ← template for credentials ├── README.md ← this file -├── LICENSE ← MIT +├── LICENSE ← PolyForm Noncommercial 1.0.0 ├── src/openkp/ │ ├── __init__.py │ ├── config.py ← credential loader (env + keychain) @@ -231,11 +233,14 @@ openkp/ │ ├── allergies.py ← allergy list │ ├── appointments.py ← upcoming + past visits │ ├── visit_notes.py ← clinical notes + AVS +│ ├── care_team.py ← care team + recent providers +│ ├── implants.py ← implanted + explanted devices +│ ├── emergency_contacts.py ← emergency contacts + DPOAHC agents │ └── refill.py ← mail-order refill commit + tracking ├── scripts/ │ └── recon_*.py ← per-endpoint reconnaissance scripts └── tests/ - └── test_*.py ← 527 tests, mock httpx via _patch_http + └── test_*.py ← 567 tests, mock httpx via _patch_http ``` ## Privacy @@ -249,7 +254,7 @@ openkp/ ## Legal - Kaiser's terms of service almost certainly prohibit automated access. Personal use on your own account is a gray zone. This is a research tool. -- Open Record's license is source-available and prohibits commercial redistribution. OpenKP is MIT-licensed and does not use Open Record's code, only its public architecture as inspiration. +- Open Record's license is source-available and prohibits commercial redistribution. OpenKP is licensed under [PolyForm Noncommercial 1.0.0](https://polyformproject.org/licenses/noncommercial/1.0.0/) and does not use Open Record's code, only its public architecture as inspiration. See ADR-007 for the relicense rationale. ## Credits diff --git a/openkp/pyproject.toml b/openkp/pyproject.toml index 7fcd08f..1942c4e 100644 --- a/openkp/pyproject.toml +++ b/openkp/pyproject.toml @@ -5,7 +5,7 @@ description = "A patient-directed MCP server that bridges Claude and Kaiser Perm authors = [{name = "Hugo Campos"}] readme = "README.md" requires-python = ">=3.11" -license = {text = "MIT"} +license = {text = "PolyForm-Noncommercial-1.0.0"} dependencies = [ # MCP server diff --git a/site/index.html b/site/index.html index c8a021b..96a3d30 100644 --- a/site/index.html +++ b/site/index.html @@ -57,23 +57,85 @@

Your patient portal, directed by you.

-
+
Claude Desktop
-
-
- Read every visit note from the last two years. Where did I raise concerns, - ask questions, or push back? How was that documented? + @@ -152,9 +214,9 @@

Questions a portal isn't designed to answer.

Tool surface
-

22 MCP tools, focused on real patient workflows.

+

24 MCP tools, focused on real patient workflows.

- Three housekeeping tools, seventeen read tools, and two write tools. + Three housekeeping tools, nineteen read tools, and two write tools. Read paths are broadly live-verified. Write commit paths are still treated carefully.

@@ -163,6 +225,7 @@

22 MCP tools, focused on real patient workflows.

Read

  • Profile, insurance, PCP, emergency contacts
  • +
  • Care team, specialists, implanted devices
  • Messages, message attachments, archival search
  • Lab results, imaging, PDFs, narratives
  • Medications, refill status, order tracking
  • @@ -211,6 +274,12 @@

    Built for technically curious KP NorCal members.

    assistant: Claude Code is the clearest path for non-developers who are comfortable following terminal instructions.

    +

    + Works on Mac and Windows. Windows adds a couple of setup steps + (Visual C++ runtime, a force-reinstall of one Python dependency). + Notes in + docs/install/windows.md. +

@@ -239,7 +308,7 @@

Endpoints can change

Own the interface to your own record.

-

Open source. MIT licensed. Local-first. Built for patients who want to inspect, adapt, and direct their tools.

+

Source-available. Noncommercial license (PolyForm NC 1.0.0). Local-first. A gift for patients who want to inspect, adapt, and direct their tools.

Get OpenKP on GitHub
diff --git a/site/script.js b/site/script.js index 482371e..34eb9a8 100644 --- a/site/script.js +++ b/site/script.js @@ -7,3 +7,66 @@ function syncHeaderElevation() { syncHeaderElevation(); window.addEventListener("scroll", syncHeaderElevation, { passive: true }); + +const carousel = document.querySelector("[data-carousel]"); +if (carousel) { + const slides = Array.from(carousel.querySelectorAll("[data-slide]")); + const dots = Array.from(carousel.querySelectorAll("[data-dot]")); + const rotateMs = 5000; + let activeIndex = 0; + let timer = null; + + function activate(next) { + activeIndex = (next + slides.length) % slides.length; + slides.forEach((slide, i) => { + const isActive = i === activeIndex; + slide.classList.toggle("is-active", isActive); + if (isActive) { + slide.removeAttribute("aria-hidden"); + } else { + slide.setAttribute("aria-hidden", "true"); + } + }); + dots.forEach((dot, i) => { + const isActive = i === activeIndex; + dot.classList.toggle("is-active", isActive); + if (isActive) { + dot.setAttribute("aria-current", "true"); + } else { + dot.removeAttribute("aria-current"); + } + }); + } + + function stopTimer() { + if (timer !== null) { + window.clearInterval(timer); + timer = null; + } + } + + function startTimer() { + stopTimer(); + timer = window.setInterval(() => activate(activeIndex + 1), rotateMs); + } + + dots.forEach((dot, i) => { + dot.addEventListener("click", () => { + activate(i); + startTimer(); + }); + }); + + carousel.addEventListener("mouseenter", stopTimer); + carousel.addEventListener("mouseleave", startTimer); + carousel.addEventListener("focusin", stopTimer); + carousel.addEventListener("focusout", startTimer); + + const reduced = window.matchMedia("(prefers-reduced-motion: reduce)"); + activate(0); + if (!reduced.matches) startTimer(); + reduced.addEventListener("change", (e) => { + if (e.matches) stopTimer(); + else startTimer(); + }); +} diff --git a/site/styles.css b/site/styles.css index ac366a2..602d29b 100644 --- a/site/styles.css +++ b/site/styles.css @@ -217,6 +217,107 @@ h3 { padding: 22px; } +.hero-carousel { + position: relative; +} + +.hero-carousel-track { + display: grid; +} + +.hero-carousel-track > .chat-window { + grid-area: 1 / 1; + opacity: 0; + visibility: hidden; + transition: opacity 320ms ease, visibility 0s linear 320ms; +} + +.hero-carousel-track > .chat-window.is-active { + opacity: 1; + visibility: visible; + transition: opacity 320ms ease, visibility 0s linear 0s; +} + +.slide-tag { + display: inline-flex; + align-items: center; + gap: 6px; + justify-self: start; + padding: 4px 10px; + border: 1px solid currentColor; + color: var(--rust); + font-size: 11px; + font-weight: 850; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.slide-tag svg { + width: 13px; + height: 13px; + flex: none; +} + +.hero-carousel-track > .chat-window:nth-child(1) .slide-tag { + color: var(--rust); +} + +.hero-carousel-track > .chat-window:nth-child(2) .slide-tag { + color: var(--gold); +} + +.hero-carousel-track > .chat-window:nth-child(3) .slide-tag { + color: var(--green); +} + +.hero-carousel-track > .chat-window:nth-child(1) .tool-call { + border-color: var(--rust); + color: var(--rust); +} + +.hero-carousel-track > .chat-window:nth-child(2) .tool-call { + border-color: var(--gold); + color: #6a4f1a; +} + +.hero-carousel-track > .chat-window:nth-child(3) .tool-call { + border-color: var(--green); + color: var(--green-deep); +} + +.carousel-dots { + display: flex; + gap: 10px; + justify-content: center; + padding: 14px 0 18px; + border-top: 1px solid var(--line); + background: #f0eadf; +} + +.carousel-dot { + width: 10px; + height: 10px; + border-radius: 50%; + border: 1px solid var(--ink); + background: transparent; + padding: 0; + cursor: pointer; + transition: background 160ms ease, transform 160ms ease; +} + +.carousel-dot:hover { + transform: translateY(-1px); +} + +.carousel-dot.is-active { + background: var(--ink); +} + +.carousel-dot:focus-visible { + outline: 2px solid var(--rust); + outline-offset: 2px; +} + .bubble { padding: 16px; border: 1px solid var(--line); @@ -442,6 +543,16 @@ code { margin-bottom: 0; } +.install-card a { + color: var(--rust); + text-decoration: underline; + text-underline-offset: 3px; +} + +.install-card a:hover { + color: var(--ink); +} + .limits-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 32px;