Uphealth Signal
The adaptive health-messaging engine for apps and agents. Federally-sourced. Not medical advice.
사용해야 할까요
품질 및 안전성
발견 사항 (2)
- HIGH
- MEDIUMlookup_health_fact에서
도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.
컨텍스트 비용
이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.
설치
원클릭 설치
`claude_desktop_config.json` 파일에 다음을 추가하세요:
{
"mcpServers": {
"mcp": {
"command": "npx",
"args": [
"@uphealth/mcp-server"
]
}
}
}실행 가능한 패키지
1.1.7stdio원격 엔드포인트
https://mcp.uphealth.us/mcpstreamable-http할 수 있는 일
도구 목록
도구 (5)
🟢lookup_health_fact(q)
Zero setup — NO key required. Returns ONE already-public federal health fact, list, or tip for a question or topic (e.g. "high blood pressure", "sleep", "type 2 diabetes"), with its federal source (CDC / MedlinePlus / NIH) and a link to the public uphealth.me page. Free + rate-limited. For adaptive, patient-specific message sequencing — receptivity-scored cues + audience-safety verdicts over the full library of federally-sourced facts, lists & tips — get a free Discovery key at https://uphealth.us/signup
입력 스키마
{
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "A health question or topic, e.g. \"high blood pressure\", \"sleep\", or \"type 2 diabetes\"."
}
},
"required": [
"q"
],
"additionalProperties": false
}출력 스키마
{
"type": "object",
"properties": {
"fact": {
"type": "object",
"description": "The single already-public federal message — a fact, list, or tip (see kind).",
"properties": {
"kind": {
"type": "string",
"description": "fact | list | tip"
},
"body": {
"type": "string"
},
"agency": {
"type": "string",
"description": "Federal source agency label, e.g. CDC / MedlinePlus / NIDDK."
},
"source_url": {
"type": "string",
"description": "The federal public-domain source."
},
"uphealth_url": {
"type": "string",
"description": "The public uphealth.me topic page."
}
},
"additionalProperties": true
},
"topic": {
"type": "string",
"description": "The matched topic's title."
},
"disclaimer": {
"type": "string"
},
"attribution": {
"type": "string",
"description": "\"Source: <agency> via Uphealth\"."
},
"upgrade": {
"type": "object",
"description": "The free-key upsell — adaptive sequencing lives behind a Discovery key.",
"additionalProperties": true
}
},
"required": [
"fact",
"disclaimer",
"attribution",
"upgrade"
]
}🟡create_patient_stream(template_id, attributes, audience_tags, delivery_mode, feedback_timeout_days, ...)
Create a Signal cued stream for one patient and get the first cue back synchronously. Every cue is federally-sourced, audience-safety-checked, and sequenced on the patient's prior response — so your agent never fabricates health content. Choose a template_id from the signal://catalog resource and pre-satisfy its required audience_tags + patient_context (clinical templates 422 without them). Display mode renders in your app: no PHI, no BAA. Each later cue MUST submit the prior message's feedback — the engine refuses to advance without it (the sequencing moat).
입력 스키마
{
"type": "object",
"properties": {
"template_id": {
"type": "string",
"enum": [
"diabetes_pharma_initiation_30day",
"general_wellness_daily",
"heart_pharma_initiation_30day",
"hypertension_lifestyle_90day",
"quit_smoking_90day",
"relapse_prevention_90day",
"weight_glp1_initiation_30day"
],
"description": "One of the live Signal templates. Read the signal://catalog resource for each template's required audience_tags + patient_context. On a production key a clinical template 422s if its required tags/context are missing — pre-satisfy them from the catalog. A free sandbox (Discovery) key always cues the curated sandbox corpus."
},
"attributes": {
"type": "object",
"description": "De-identified patient context. v1 accepts free-form jsonb; future templates will enforce schemas."
},
"audience_tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Subset of the 14-tag B5/B6 schema. See list_sandbox_topics for sample topic labels."
},
"delivery_mode": {
"type": "string",
"enum": [
"display"
],
"default": "display",
"description": "v1 is Display-only; Deliver-mode unlocks at Per-Episode tier after BAA."
},
"feedback_timeout_days": {
"type": "integer",
"default": 14
},
"idempotency_key": {
"type": "string",
"format": "uuid",
"description": "Optional. Stripe-style create idempotency: a retried create with the same key returns the ORIGINAL stream instead of minting (and billing) a second one. Forwarded as the Idempotency-Key request header. UUID v4 recommended."
}
},
"required": [
"template_id"
],
"additionalProperties": true
}출력 스키마
{
"type": "object",
"properties": {
"stream_id": {
"type": "integer",
"description": "Persist this — every later cue/read references it."
},
"state": {
"type": "string"
},
"first_cue": {
"type": "object",
"description": "A cued message plus its per-cue receptivity score and audience-safety verdict.",
"properties": {
"cue_event_id": {
"type": "integer"
},
"message_id": {
"type": "integer"
},
"message_class": {
"type": "string"
},
"kind": {
"type": "string",
"description": "fact | list | tip"
},
"body": {
"type": "string"
},
"source_url": {
"type": "string"
},
"source_quote": {
"type": "string"
},
"receptivity": {
"type": "number",
"description": "Advisory receptivity in [0.0, 1.0]; 0.5 = neutral/new patient."
},
"safety": {
"type": "object",
"additionalProperties": true,
"description": "PHI-free audience-safety verdict."
},
"arc": {
"type": [
"object",
"null"
],
"description": "Where this cue sits in the template's curated arc, or null when the cue is not on a spine. source is 'spine' or 'corpus_continuation'; a corpus-continuation cue (past the arc's end) carries source only, with day/phase/seq/total null.",
"properties": {
"source": {
"type": "string",
"description": "spine | corpus_continuation"
},
"day": {
"type": [
"integer",
"null"
],
"description": "The curated arc day of this message."
},
"phase": {
"type": [
"string",
"null"
],
"description": "The curated arc phase, e.g. starting_dose / titrating / re_entry."
},
"seq": {
"type": [
"integer",
"null"
],
"description": "1-based position of this message in the spine."
},
"total": {
"type": [
"integer",
"null"
],
"description": "Total messages in the spine."
}
},
"additionalProperties": true
},
"day_of_stream": {
"type": [
"integer",
"null"
],
"description": "Advisory 1-based wall-clock day the patient is on in this stream (anchored to enrollment). Null on legacy cues issued before day-of-stream tracking."
},
"cued_at": {
"type": "string",
"description": "ISO 8601 timestamp."
}
},
"additionalProperties": true
},
"next_cue_eligible_at": {
"type": [
"string",
"null"
]
},
"rate_limit": {
"type": "object",
"description": "Discovery monthly cue-cap headroom. Absent on non-Discovery tiers (no cap).",
"properties": {
"limit": {
"type": "integer",
"description": "Discovery monthly cue cap."
},
"remaining": {
"type": "integer",
"description": "Cues remaining in the current calendar month (UTC)."
},
"reset": {
"type": "integer",
"description": "Seconds until the cap window resets (start of next calendar month, UTC; same basis as the 429 Retry-After)."
}
},
"additionalProperties": true
},
"_meta": {
"type": "object",
"description": "Legal/disclosure block returned on every 2xx (A1 §6.7).",
"properties": {
"api_version": {
"type": "string"
},
"no_medical_advice": {
"type": "boolean"
},
"not_samd": {
"type": "boolean"
},
"license_attribution": {
"type": "string"
},
"delivery_mode": {
"type": "string"
},
"sequencing_ip_notice": {
"type": "string"
}
},
"additionalProperties": true
}
},
"required": [
"stream_id",
"state",
"first_cue",
"_meta"
]
}🟡get_next_cued_message(stream_id, feedback)
Submit the patient's response to the prior cue and get the next one — federally-sourced, audience-safety-checked, and re-sequenced on that feedback. REFUSES WITHOUT PRIOR-MESSAGE FEEDBACK (the moat): the engine will not advance a stream blind, returning 409 if you skip it. response_action is one of the accepted cue vocabulary (see the signal://catalog resource). Same idempotency_key + same feedback returns the cached cue; conflicting feedback under the same key returns 409.
입력 스키마
{
"type": "object",
"properties": {
"stream_id": {
"type": "integer",
"description": "The stream_id returned by create_patient_stream."
},
"feedback": {
"type": "object",
"properties": {
"response_action": {
"type": "string",
"enum": [
"did_it",
"already_do",
"will_try",
"check_it",
"new_to_me",
"needed_this",
"know_it",
"acknowledge",
"no_response"
]
},
"free_text": {
"type": "string"
},
"idempotency_key": {
"type": "string",
"format": "uuid",
"description": "UUID v4 recommended. Same key + same feedback returns the cached cue; conflicting feedback under the same key returns 409."
}
},
"required": [
"response_action",
"idempotency_key"
]
}
},
"required": [
"stream_id",
"feedback"
],
"additionalProperties": false
}출력 스키마
{
"type": "object",
"properties": {
"stream_id": {
"type": "integer"
},
"state": {
"type": "string"
},
"idempotent": {
"type": "boolean",
"description": "true when this is the cached result of a repeated idempotency_key."
},
"normalized_action": {
"type": [
"string",
"null"
],
"description": "null when the submitted response_action was a recognized value; otherwise the acknowledge-class value the well-formed-but-unrecognized action was folded to (forward-compat tolerance). Always present on a cue result; absent on the exhausted-stream result."
},
"next_cue": {
"type": "object",
"description": "A cued message plus its per-cue receptivity score and audience-safety verdict.",
"properties": {
"cue_event_id": {
"type": "integer"
},
"message_id": {
"type": "integer"
},
"message_class": {
"type": "string"
},
"kind": {
"type": "string",
"description": "fact | list | tip"
},
"body": {
"type": "string"
},
"source_url": {
"type": "string"
},
"source_quote": {
"type": "string"
},
"receptivity": {
"type": "number",
"description": "Advisory receptivity in [0.0, 1.0]; 0.5 = neutral/new patient."
},
"safety": {
"type": "object",
"additionalProperties": true,
"description": "PHI-free audience-safety verdict."
},
"arc": {
"type": [
"object",
"null"
],
"description": "Where this cue sits in the template's curated arc, or null when the cue is not on a spine. source is 'spine' or 'corpus_continuation'; a corpus-continuation cue (past the arc's end) carries source only, with day/phase/seq/total null.",
"properties": {
"source": {
"type": "string",
"description": "spine | corpus_continuation"
},
"day": {
"type": [
"integer",
"null"
],
"description": "The curated arc day of this message."
},
"phase": {
"type": [
"string",
"null"
],
"description": "The curated arc phase, e.g. starting_dose / titrating / re_entry."
},
"seq": {
"type": [
"integer",
"null"
],
"description": "1-based position of this message in the spine."
},
"total": {
"type": [
"integer",
"null"
],
"description": "Total messages in the spine."
}
},
"additionalProperties": true
},
"day_of_stream": {
"type": [
"integer",
"null"
],
"description": "Advisory 1-based wall-clock day the patient is on in this stream (anchored to enrollment). Null on legacy cues issued before day-of-stream tracking."
},
"cued_at": {
"type": "string",
"description": "ISO 8601 timestamp."
}
},
"additionalProperties": true
},
"sandbox_exhausted": {
"type": "boolean",
"description": "Present + true when the sandbox subset is exhausted; no next_cue then."
},
"message": {
"type": "string"
},
"rate_limit": {
"type": "object",
"description": "Discovery monthly cue-cap headroom. Absent on non-Discovery tiers (no cap).",
"properties": {
"limit": {
"type": "integer",
"description": "Discovery monthly cue cap."
},
"remaining": {
"type": "integer",
"description": "Cues remaining in the current calendar month (UTC)."
},
"reset": {
"type": "integer",
"description": "Seconds until the cap window resets (start of next calendar month, UTC; same basis as the 429 Retry-After)."
}
},
"additionalProperties": true
},
"_meta": {
"type": "object",
"description": "Legal/disclosure block returned on every 2xx (A1 §6.7).",
"properties": {
"api_version": {
"type": "string"
},
"no_medical_advice": {
"type": "boolean"
},
"not_samd": {
"type": "boolean"
},
"license_attribution": {
"type": "string"
},
"delivery_mode": {
"type": "string"
},
"sequencing_ip_notice": {
"type": "string"
}
},
"additionalProperties": true
}
},
"required": [
"stream_id",
"state",
"_meta"
]
}🟢read_stream_state(stream_id)
Read a stream's current state, its current cued message, and event count. Read-only — does NOT advance the stream or consume a cue. Use it between feedback turns to inspect where a patient is in their federally-sourced, audience-safety-checked sequence.
입력 스키마
{
"type": "object",
"properties": {
"stream_id": {
"type": "integer",
"description": "The stream_id returned by create_patient_stream."
}
},
"required": [
"stream_id"
],
"additionalProperties": false
}출력 스키마
{
"type": "object",
"properties": {
"stream_id": {
"type": "integer"
},
"template_id": {
"type": "string"
},
"state": {
"type": "string"
},
"current_cue": {
"type": [
"object",
"null"
],
"additionalProperties": true
},
"next_cue_eligible": {
"type": "boolean"
},
"events_count": {
"type": "integer"
},
"rate_limit": {
"type": "object",
"description": "Discovery monthly cue-cap headroom. Absent on non-Discovery tiers (no cap).",
"properties": {
"limit": {
"type": "integer",
"description": "Discovery monthly cue cap."
},
"remaining": {
"type": "integer",
"description": "Cues remaining in the current calendar month (UTC)."
},
"reset": {
"type": "integer",
"description": "Seconds until the cap window resets (start of next calendar month, UTC; same basis as the 429 Retry-After)."
}
},
"additionalProperties": true
},
"_meta": {
"type": "object",
"description": "Legal/disclosure block returned on every 2xx (A1 §6.7).",
"properties": {
"api_version": {
"type": "string"
},
"no_medical_advice": {
"type": "boolean"
},
"not_samd": {
"type": "boolean"
},
"license_attribution": {
"type": "string"
},
"delivery_mode": {
"type": "string"
},
"sequencing_ip_notice": {
"type": "string"
}
},
"additionalProperties": true
}
},
"required": [
"stream_id",
"state",
"_meta"
]
}🟢list_sandbox_topics
List the curated sandbox topic labels that define the free Discovery corpus — every topic federally-sourced and audience-safety-checked. Use it to preview what content domains exist before creating a stream. Does NOT enumerate messages — the corpus stays internal. For the full live template catalog + gating contract, read the signal://catalog resource.
입력 스키마
{
"type": "object",
"properties": {},
"additionalProperties": false
}출력 스키마
{
"type": "object",
"properties": {
"topic_labels": {
"type": "array",
"items": {
"type": "string"
}
},
"template_id_for_sandbox": {
"type": "string"
},
"_meta": {
"type": "object",
"description": "Legal/disclosure block returned on every 2xx (A1 §6.7).",
"properties": {
"api_version": {
"type": "string"
},
"no_medical_advice": {
"type": "boolean"
},
"not_samd": {
"type": "boolean"
},
"license_attribution": {
"type": "string"
},
"delivery_mode": {
"type": "string"
},
"sequencing_ip_notice": {
"type": "string"
}
},
"additionalProperties": true
}
},
"required": [
"topic_labels",
"_meta"
]
}권장 프롬프트
get_next_cued_messageget_next_cued_messagelist_sandbox_topicslist_sandbox_topicslist_sandbox_topicsget_next_cued_message커뮤니티
증거