npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@healthcloudai/hc-ams

v3.6.4

Published

HealthCloud AMS SDK — application-agent discovery for AMS Services.

Readme

HealthCloud AMS SDK for NodeJS / TypeScript

Typed access to AMS Services: agent/department/team/skill/policy/guardrail CRUD, the data-source and tool catalogs, synthetic test-patient personas, conversation history, and the real-time WebSocket agent-chat runtime.

Installation

npm install @healthcloudai/hc-ams

Quick start

import { HCAmsSDK } from "@healthcloudai/hc-ams";

const sdk = new HCAmsSDK({ environment: "dev" });

const agents = await sdk.ams.getAgentsForTenant("<TENANT_ID>");
// { public: [...], orchestrator: [...] }

Authentication

ams.getAgentsForTenant is public and requires no access token.

Every other REST client (agents, departments, teams, skills, policies, guardrails, dataSources, tools, testPersonas) requires a Tenant Admin Bearer token, set via accessToken in the constructor or sdk.setAccessToken(token). This SDK does not obtain that token itself — get one from AMS's own sdk.auth.login(...) or from @healthcloudai/hc-tenantadmin, and pass it in.

The WebSocket runtime (sdk.connectAgentChat(...) / WssClient) is authenticated with a patient Health Cloud access token instead — obtain one via sdk.testPersonas.login(credentialId) for testing, or from your own patient auth flow in production.

REST clients

| Client | Resource | Notes | | --- | --- | --- | | sdk.ams | Public application-agent discovery | No auth required | | sdk.agents | Agent CRUD, transfer candidates, conversation history | create/update/delete may 405 if the tenant has disable_direct_agent_mutations enabled (see below) | | sdk.departments | Department CRUD + activate/deactivate | | | sdk.teams | Team CRUD | | | sdk.skills | Skill CRUD | | | sdk.policies | Policy CRUD | | | sdk.guardrails | Guardrail CRUD | | | sdk.dataSources | Data source catalog | Read-only — AMS exposes no create/update/delete | | sdk.tools | Tool catalog | Read-only — AMS exposes no create/update/delete | | sdk.testPersonas | Synthetic QA patient persona CRUD + login | login() mints a real Health Cloud patient token | | sdk.auth | AMS's own Tenant Admin auth proxy (/api/auth/*) | Resolves against a different base path than every other client |

const sdk = new HCAmsSDK({ environment: "dev", accessToken: tenantAdminToken });

const department = await sdk.departments.create({ name: "Cardiology", created_by_user_id: "admin-1" });
const agent = await sdk.agents.create({ name: "Cardiology Intake", department_id: department.id });
const history = await sdk.agents.getConversation(agent.id, `${tenantId}/${patientId}`);

Direct agent mutation

Some tenants run with disable_direct_agent_mutations enabled, in which case AMS's plain POST/PUT/DELETE /agents routes respond 405 and real agent authoring happens through the Vibe Coder plan/apply flow instead. That flow is intentionally out of scope for this SDK — sdk.agents.create/update/delete only cover the plain-CRUD path.

WebSocket agent-chat runtime

Since 3.5.1: the patient token is sent as the first WebSocket frame ({"type":"auth","token":"..."}) right after the socket opens, never in the connect URL or as a WS subprotocol — chat.connect() doesn't resolve until the server replies auth_ok. This is handled internally; you don't need to change any calling code that already passes healthcloudToken or getAccessToken. It does require the AMS backend to be on the matching version (the corresponding server-side change is healthcloudservices/healthcloud-ams-services#280, merged via #288) — against an older backend, connect() will reject with an auth timeout instead of connecting. WssClientOptions.tokenTransport (0.0.1) is removed; if your code set it explicitly, delete that line.

const sdk = new HCAmsSDK({ environment: "dev", tenantId: "<TENANT_ID>", accessToken: tenantAdminToken });

// Mint a patient token for a synthetic test persona.
const session = await sdk.testPersonas.login(personaCredentialId);

// Connect and hold a multi-turn conversation with one agent.
const chat = sdk.connectAgentChat({
  patientId: session.patient_id,
  healthcloudToken: session.access_token,
  agentId: "<AGENT_ID>", // omit to use the tenant's default agent
});
await chat.connect();

const turn = await chat.sendAndAwaitTurn("Hi, I'd like to schedule a check-up.");
console.log(turn.message, turn.transfers, turn.artifacts, turn.notifications, turn.activity);

chat.close();

Note: the HCAmsSDK instance's own accessToken (Tenant Admin) above is only needed because this example uses testPersonas.login to mint a synthetic test patient — a testing convenience, not a production pattern. connectAgentChat/WssClient never read that accessToken; they only ever use the healthcloudToken you pass them explicitly. A real patient-facing app needs no Tenant Admin token at all — get the patient token from your own patient auth (@healthcloudai/hc-sdk), e.g.:

import { HCSDK } from "@healthcloudai/hc-sdk";
import { HCAmsSDK } from "@healthcloudai/hc-ams";

const patientSdk = new HCSDK({ environment: "dev", tenantId: "<TENANT_ID>" });
const login = await patientSdk.auth.login({ email, password }); // real patient credentials

const amsSdk = new HCAmsSDK({ environment: "dev", tenantId: "<TENANT_ID>" }); // no accessToken needed
const chat = amsSdk.connectAgentChat({
  patientId: login.fhir_patient_id,
  healthcloudToken: login.access_token,
  agentId: "<AGENT_ID>",
});
await chat.connect();

WssClient also exposes raw typed event subscription for finer-grained control:

chat.on("turn_started", (e) => console.log("turn started", e.turn_id));
chat.on("chat", (e) => process.stdout.write(e.content));
chat.on("transfer", (e) => console.log("agent switched", e.to_agent_id));

The entire multi-agent conversation (orchestrator plus any number of downstream specialist agents) lives on this one WebSocket connection — agent switches arrive as transfer events, not reconnects.

For a reconnect (network drop, or your own periodic re-auth), pass getAccessToken instead of a static healthcloudToken so a fresh token is resolved on every connect() call rather than replaying a captured, possibly-expired one:

const chat = sdk.connectAgentChat({
  patientId,
  getAccessToken: () => myAuthStore.getCurrentPatientToken(), // called on every connect()
  agentId,
});

Guest chat before sign-in, then handoff to an authenticated conversation

For an agent configured with requires_auth: false (a public, pre-login agent), no patient login or access token is needed. The connection still requires a patientId to form its session ID; generate a random guest ID for that — it is not a real FHIR patient ID, and the server never resolves it against a real patient record for a requires_auth: false agent.

const { public: publicAgents, orchestrator } = await amsSdk.ams.getAgentsForTenant(tenantId);

const guestId = crypto.randomUUID();
const guestChat = amsSdk.connectAgentChat({
  patientId: guestId,
  healthcloudToken: "", // no token needed for a requires_auth: false agent
  agentId: publicAgents[0],
});
await guestChat.connect();

const guestTurn = await guestChat.sendAndAwaitTurn("What services are available?");
console.log(guestTurn.message);

Once the patient signs in, start a new connection with the real patientId/healthcloudToken — and pass handoff with the guest transcript so the orchestrator's first greeting can acknowledge it, instead of the conversation starting as if nothing was said:

guestChat.close();

const login = await patientSdk.auth.login({ email, password });

const chat = amsSdk.connectAgentChat({
  patientId: login.fhir_patient_id,
  healthcloudToken: login.access_token,
  agentId: orchestrator[0],
  handoff: [
    { role: "user", content: "What services are available?" },
    { role: "assistant", content: guestTurn.message },
  ],
});
await chat.connect();

handoff is sent once, at connect time — the server reads it before generating the first greeting, so the greeting itself can reference the handed-off content (e.g. "I see you were asking about X — let's continue from there"). It is not the same as sendHandoff(messages) (a post-connect frame kept only for callers on the older contract): that one can only silently append to history after the greeting has already gone out.

On Node < 21 (no global WebSocket), pass a compatible implementation:

import WebSocket from "ws";

const chat = sdk.connectAgentChat({
  patientId,
  healthcloudToken,
  WebSocketImpl: WebSocket as any,
});

See TEST_LIST.md for a full end-to-end flow: creating a department/team/agents/test-persona, logging in as the persona, and validating a multi-turn conversation's turns, transfers, artifacts, notifications, and activity.

Configuration

| Option | Description | | --- | --- | | environment | "dev" | "uat" | "prod" — resolves the AMS base URL ({env-}amsservices.health.cloud/api/ams, no prefix for prod). | | tenantId | Optional default tenant ID, used by connectAgentChat when no tenantId is passed per-call. | | accessToken | Optional Tenant Admin bearer token for authenticated REST methods. | | baseUrlOverride | Overrides the resolved AMS base URL (e.g. for local/staging testing). | | timeout | Request timeout in milliseconds. Defaults to 30000. |