Semblekit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Semblekit (Plugin) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
CLI, library & MCP server for the Semble practice-management API — usable by any agent, human, or script.
semblekit drives Semble over its public GraphQL API. It models Semble's own concepts (contacts, patients & relationships, users) rather than any one organisation's usage of them, and ships four ways to use it: a semble CLI, an importable library, an MCP server, and a Claude Code plugin.
Not affiliated with, endorsed by, or supported by Semble Ltd. "Semble" names the API this tool interoperates with.
Design principle. Commands map to Semble resources, not workflows. A "Responsible Clinician", for example, is not a first-class Semble thing — it is just a patient relationship with a label pointing at a contact. So the tool exposes semble patient relationship … and leaves the meaning to the consumer.Naming. The repo and CLI command aresemblekit/semble; the published package is `@burrows99/semblekit` on the GitHub Packages registry (the bare namesemblekitis taken on npmjs). The Claude plugin issemble@semblekit.
Semble is a practice-management / EHR system, so treat everything it returns as sensitive.
it: direct identifiers — name, email, date of birth, phone, address, NHS number — are redacted, and free-text is scrubbed for embedded emails / phone / NHS numbers, while Semble's opaque ids and clinical values are kept. Per the ICO, pseudonymised data is still personal data — this reduces what agents read, it does not anonymise. Disable with the CLI --no-deid flag or SEMBLE_DEID=false (honoured by the CLI and the MCP server; for MCP it is set at launch, so an agent cannot turn it off itself).
patient data is likely special-category personal data under UK GDPR / the DataProtection Act. You remain the controller or processor for anything you move with this tool. Prefer the sandbox for development.
~/.config/semble/config.json — neverhardcoded. Keep them out of version control; the tool never logs credential values.
.semble/trace.jsonl.--trace / --trace-full additionally persist full request and response bodies — which may contain patient data — to that file. Secrets (tokens) are redacted, patient data is not. .semble/ is git-ignored by default; avoid full tracing against production data unless your obligations allow it.
Credentials and API URLs come from flags, environment variables, or a config file — never hardcoded — so semblekit is not coupled to any deployment. It runs on plain Node (built-in fetch, Node ≥ 18); no Docker.
It talks to Semble's public GraphQL API (x-token). The design is object-oriented: typed entities own their behaviour, thin resources do I/O, and a single fetch chokepoint makes request tracing a one-line wrap.
Requires Node ≥ 18. semblekit is published to the GitHub Packages npm registry, which requires a token even for public reads — so there's a one-time scope + token setup (a GitHub token with the read:packages scope).
With the GitHub CLI (recommended — substitutes your token automatically, no copy-paste):
gh auth refresh -h github.com -s read:packages # one-time: ensure your token can read packages
printf '@burrows99:registry=https://npm.pkg.github.com\n//npm.pkg.github.com/:_authToken=%s\n' "$(gh auth token)" >> ~/.npmrcWithout it, create a token with the read:packages scope, then add these two lines to ~/.npmrc (replace <TOKEN> with the real value):
@burrows99:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=<TOKEN>Then install:
npm install -g @burrows99/semblekit # global: the `semble` CLI + `semble-mcp` MCP server
# or, as a library in a project:
npm install @burrows99/semblekitNode ≥ 18 only (uses the built-in fetch). No Docker, no database.
Credentials resolve flags > environment > config file > built-in presets, and are auto-discovered from the nearest .env / .claude/.env walking up from the working directory. See .env.example. For the public API the relevant variables are SEMBLE_OPEN_URL and SEMBLE_TOKEN.
semble patient search "smith" --limit 5 # find a patient id
semble patient get <patientId> --json
semble contact search "clinic" --json # find a contact/clinician id
semble user list
semble patient relationship add <patientId> <contactId> --label "Responsible Clinician"
semble help--json for machine output, --trace for a DevTools-style request log, --limit to cap paginated results. stdout is data, stderr is messages; exit 0 success · 1 runtime error · 2 usage error.
import { SembleClient, SembleTracer, loadConfig } from "@burrows99/semblekit";
const client = new SembleClient(loadConfig({ profile: "sandbox" }));
const [patient] = await client.patients.search("smith");
const rels = await client.patients.listRelationships(patient.id);
new SembleTracer(client, (record) => console.error(record)); // optional: trace every HTTP exchangeMethods return data or throw SembleError; they never call process.exit or print. search / list paginate automatically and accept { limit }.
semblekit ships a stdio MCP server so an AI host can drive Semble as tools — run it with npx, no install needed (uses the .npmrc set up in Install):
npx -p @burrows99/semblekit semble-mcpPoint an MCP host at it:
{
"mcpServers": {
"semblekit": { "command": "npx", "args": ["-y", "-p", "@burrows99/semblekit", "semble-mcp"] }
}
}Inspect it with the MCP Inspector:
npx @modelcontextprotocol/inspector npx -p @burrows99/semblekit semble-mcpRead-only tools: semble_patient_search, semble_patient_get, semble_patient_relationships, semble_contact_search, semble_contact_get, semble_user_list, semble_user_get.
claude plugin marketplace add /path/to/semblekit
claude plugin install semble@semblekitconfig withloadConfig(options).
search(query?, { limit? }), get(id), listRelationships(patientId).search(query?, { limit? }), get(id).list({ limit? }), get(id).sink(record) firesper request, with secrets redacted.
sandbox and prod.Patient, Contact, User, RelatedAccount; each JSON.stringifys to its API shape.SembleError and its subclasses SembleConfigError, SembleAuthError, SembleApiError,SembleNotFoundError, SembleValidationError.
@burrows99 (Raunak Burrows).
Questions and bugs: open an issue at github.com/burrows99/semblekit/issues. PRs are welcome and target main. Keep org-specific meaning out of the library — expose the generic Semble operation.
npm install # installs deps, builds via `prepare`
npm run build # tsc → dist/ + .d.ts
npm run typecheck # tsc --noEmit
npm test # placeholder suiteSource is TypeScript (ESM, NodeNext) in src/**/*.ts, compiled to dist/. Add a resource by creating its entity in src/entities/, a src/resources/<resource>.ts, wiring it onto the client in src/client.ts, and a matching src/commands/<resource>.ts.
MIT © Raunak Burrows.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.