Codync
免費、開源的 1:1 替代方案,取代 Grok Bot 與 Muse。從 iPhone、Mac 或 Linux 桌面將 Claude Code、Codex、Cursor 與 40+ 程式碼代理人作為持續機器人傳訊。群組聊天、主題串…
AI 翻譯
尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Find out why a SMART on FHIR login fails — backend services or user sign-in — locally, without your keys or secrets leaving your machine.
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗EHR token endpoints answer almost every client problem with the same thing:
{ "error": "invalid_client" }
That's deliberate: servers shouldn't tell attackers what went wrong. So you're left guessing. Is aud wrong? Is the kid not published, or the JWKS unreachable? Is your clock off? Is the client ID from the wrong environment, or the redirect URI not registered exactly? Was the authorization code already used?
smart-doctor checks everything that can be checked from your side, runs the real login once, and ranks the likely causes in plain English, with the evidence and the exact next step.
npx smart-doctor ui --demo # practise first: a web view with a practice EHR that fails on purpose
npx smart-doctor init # your server: a few questions, everything else is discovered
npx smart-doctor check my-profile # run it any time
Needs Node.js 22 or newer. No Node? Use a standalone binary for macOS, Linux or Windows.
| Flow | Client authentication | What it checks |
|---|---|---|
Backend servicesclient_credentials | private_key_jwt, client_secret_basic, client_secret_post | key or secret · discovery · clock · JWKS (reachable, your kid, the published key is yours, no private-key leaks) · assertion (aud, exp ≤ 5 min, jti, kid, iss/sub) · the real token request · granted scopes · optional FHIR call (status only) |
User sign-inSMART App Launch, authorization_code + PKCE | public (PKCE only), client secret, private key | discovery (authorize endpoint, S256, capabilities) · your redirect URI · sign-in · state and iss · code exchange · patient context · id_token signature, aud, fhirUser · refresh token · optional FHIR call (status only) |
When the server still refuses after every local check passes, smart-doctor reads the server's own words, adds vendor hints (Epic, Oracle Health, athenahealth, OpenEMR) and names the server-side causes it cannot see, so you know exactly what to ask your EHR contact. Every cause is explained in the error catalogue.
smart-doctor ui opens a local web view: pick a profile, run it, watch the trace, and copy a ticket-ready report. It binds to 127.0.0.1 only, needs a per-session token and makes no third-party requests.
Invalid Grant), then vendor knowledge, each with evidence and a fix.http://localhost:PORT redirects are caught directly; for anything else you sign in, land on your company's page and paste its address back. No registration changes.--report writes Markdown for a ticket, a vendor or an AI chat, with the client ID, patient IDs, tokens, codes and secrets masked.smart-doctor.yaml that refuses to hold secrets.npm run smoke:sandbox).| You have | Do |
|---|---|
| Node.js 22+ | npx smart-doctor …, or npm install --global smart-doctor |
| No Node.js | Download the binary for your OS from Releases, with checksums and build attestations (gh attestation verify <file> --repo baselissmail/smart-doctor) |
| Docker | docker build -t smart-doctor https://github.com/baselissmail/smart-doctor.git && docker run --rm -v "$PWD:/work" smart-doctor check my-profile |
| GitHub Actions | Nightly monitoring |
| Claude Code | /plugin marketplace add baselissmail/smart-doctor, then /plugin install smart-doctor@smart-doctor. The skill passes keys by path only and shares --report output |
Profiles live in smart-doctor.yaml (the nearest one up from the current folder, or ~/.config/smart-doctor/). They never contain secrets: keys are referenced by path and secrets by environment-variable name, so you can commit them and share them with your team. Writing a secret into a profile is refused.
profiles:
epic-sandbox:
flow: backend
fhir: https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4
clientId: 1234-non-prod
auth: private_key_jwt
key: ./keys/private-key.pem # relative to this file
kid: sandbox-1
scope: system/Patient.rs
our-app-login:
flow: launch
fhir: https://fhir.example.org/r4
clientId: our-app
auth: client_secret_basic
secretEnv: OUR_APP_SECRET # the variable NAME, never the secret
redirectUri: https://app.example.com/smart/callback
Any flag overrides the profile: smart-doctor check epic-sandbox --kid new-key-2 --verbose. Save a one-off command as a profile with --save <name>.
| Command | Does |
|---|---|
smart-doctor | First time: guided setup. After that: pick a profile to run |
init | Guided setup → saves a profile |
check [profile] | Diagnose (flow from the profile, or --flow backend|launch) |
launch [profile] | check --flow launch |
ui | Local web view (--demo adds the practice EHR) |
profiles | List profiles |
explain '<error>' | Explain an error message you already have |
inspect <jwt> | Lint a client assertion from your app's logs (no key needed; the signature is never printed) |
keygen | New RS384/ES384 key pair and public JWKS |
mock | Practice EHR with 18 failure modes (--list-modes) |
Useful flags: --verbose (every HTTP request and response, secrets masked) · --report (paste-safe Markdown) · --json · --offline (everything up to the token request or sign-in; discovery and the JWKS are still read) · --aud (reproduce your app's aud) · --redirect-mode paste|loopback. Run smart-doctor --help for everything.
Exit codes: 0 works · 1 problems found · 2 usage error.
# .github/workflows/smart-login.yml
on: { schedule: [{ cron: '17 5 * * *' }] }
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5 # contains smart-doctor.yaml and the key path
- uses: baselissmail/smart-doctor@v0
with: { profile: epic-prod-backend }
env: { OUR_APP_SECRET: '${{ secrets.OUR_APP_SECRET }}' }
The report lands in the job summary; the job fails when the login does.
--report, --redact) also mask the patient, encounter and user IDs from a sign-in.Details: SECURITY.md · how it's built: ARCHITECTURE.md · how it's tested: TESTING.md.
Every login failure someone figured out the hard way is worth teaching smart-doctor, and most contributions are a few lines of data plus a test: a server's error message, a vendor quirk with a public source, a clearer fix. Start with CONTRIBUTING.md; the roadmap lists bigger pieces marked help wanted.
--report output.MIT © Basel Issmail. Not affiliated with HL7, SMART Health IT or any EHR vendor; vendor names are trademarks of their owners.