Skip to main content
Glama

stcc-mcp — Triage telefónico: el cálculo lo hace un motor de reglas determinista, el 0.6B solo verifica los criterios

Entra un registro de anamnesis y sale nivel L1–L5 + redacción de la disposición + citas una a una + qué criterios faltan. La clasificación la calcula un motor de reglas determinista (225 protocolos STCC / 849 ramas / 4.168 criterios, distribuidos con el paquete), Qwen3-0.6B solo responde a una cosa: dado el registro y un criterio, yes / no / unknown.

El modelo no elige rama, no fija el nivel, no genera la redacción de la disposición, no hace tool calls.

⚠️ No es un sistema de triaje de urgencias, no hace diagnósticos y no puede sustituir a un médico. L1–L5 es una escalera de disposición (llamar a la ambulancia / urgencias inmediatas / consulta hoy / consulta ambulatoria en 1–2 días / observación en casa). En caso de emergencia, llame directamente al 112.

Tres pasos para ponerlo en marcha

pip install stcc-mcp                                       # 或 uvx stcc-mcp …
ollama pull hf.co/chenhaodev/stcc-checker-0.6b-GGUF:Q8_0   # 640MB 核对器
stcc-mcp doctor                                            # 自检:索引 / Ollama / 模型
stcc-mcp triage --protocol Chest_Pain.md "$(cat 记录.txt)"

Cero procesos residentes, cero Docker, sin conexión a red. El motor es solo biblioteca estándar, sin dependencias de terceros.

En la primera ejecución lo más probable es ver tier: L1 + certain: false — y es lo correcto

Si introduce un registro de anamnesis normal, lo más probable es que obtenga el nivel más urgente más una serie de unresolved. No es un error de clasificación: el motor solo se atreve a descartar una rama cuando todas sus condiciones son no, y una anamnesis real no llega a preguntar todos los criterios de una rama. Por ejemplo, en un registro de fiebre leve, la enfermera preguntó por conciencia/respiración/rigidez de nuca/erupción, pero nunca preguntó por signos de deshidratación (disminución de la diuresis, ojos hundidos, mala turgencia cutánea, sed), así que esa rama no se puede descartar y la salida se queda en el límite superior de su nivel.

unresolved es la lista de "si preguntas estas cosas, puedes ajustar el nivel". Complete las respuestas en el registro y vuelva a ejecutar: unresolved se acorta de forma monótona; pero el nivel solo baja cuando una rama queda completamente descartada — en las pruebas, el mismo registro de fiebre, tras completar los signos de deshidratación, pasó de unresolved 8→2, pero el nivel seguía en L1, porque el tronco restante (ese fragmento a medias de ancianos o inmunodeprimidos… manifestaciones de deshidratación:) el verificador lo marcó como unknown. En ese momento lo que hay que tocar es el mando del umbral de abajo, no seguir preguntando. Ver límites ① y ②.

Conéctelo a un agente (Claude Code / cualquier cliente MCP):

pip install "stcc-mcp[mcp]" && stcc-mcp serve               # stdio MCP

Ollama no soporta MCP, y para esta forma eso no es un problema: el modelo pequeño nunca hace tool calls, la capa de orquestación llama por separado a Ollama (HTTP) y al motor de reglas (en proceso), y no se conocen entre sí. El tool-calling autónomo de un 0.6B es un punto débil conocido; esta arquitectura lo evita por diseño.

Related MCP server: Quellgeist

Salida

Campo

Significado

tier

L1L5, cota superior de seguridad: nunca más leve que la respuesta real

disposition

La redacción de la disposición de esa rama (de la tabla de reglas, no generada por el modelo)

certain

true = la evidencia ya basta para fijar el nivel; false = esto es la cota superior de worst_case

citations

Criterios que fundamentan la decisión + número de línea, auditable

unresolved

Qué criterios faltan — preguntarlos ajusta el nivel

El mapeo de nivel a acción lo define tu capa de orquestación; este paquete solo da el nivel y la redacción de la disposición.

El umbral para juzgar no es un mando

--no-threshold (por defecto 0.63): P(no) ≥ τ ⇒ no, si no, se toma el mayor entre yes/unknown. La curva completa de compensaciones del mismo modelo en la distribución de publicación (n=3225):

τ

acc

false_no🔴

no_recall

0.63 (por defecto)

0.9426

0.0000

0.9027

0.50

0.9457

0.0000

0.9189

0.40

0.9495

0.0024

0.9378

0.30

0.9498

0.0084

0.9432

0.10

0.9516

0.0120

0.9635

El mismo registro de anamnesis de fiebre, solo cambiando τ:

$ stcc-mcp triage --protocol Fever_Adult.md --no-threshold 0.63 "$(cat 记录.txt)"
  tier L1 · 拨打救护车        · unresolved 2
$ stcc-mcp triage --protocol Fever_Adult.md --no-threshold 0.40 "$(cat 记录.txt)"
  tier L3 · 2小时内接受医疗护理 · unresolved 5

τ más bajo ⇒ el verificador se atreve más a marcar como no los criterios "preguntados y negados" ⇒ la rama se descarta ⇒ el nivel baja. Esto no hace al modelo más preciso, es cambiar el punto de trabajo en la misma curva de compensaciones — a cambio, sube el riesgo de infratriaje.

false_no (marcar como no lo que debería ser verdadero) es una puerta dura — un no falso excluye la rama verdadera de la convergencia segura. Marcar menos no solo causa sobretriaje, es un mando de coste. El valor por defecto se eligió en dev con false_no ≤ 0.0036 (ese dev solo tiene 495 positivos, resolución 0.0020, sistemáticamente conservador). Así que no hay un "valor óptimo" clavado — se entrega la curva completa, elija el punto según su propia matriz de costes. Reproducción: python -m scripts.threshold_sweep --model <m> --split <s> --collect --report.

🔴 Límites conocidos (lea esto antes de decidir si usarlo)

① La entrada debe ser un registro "ya interrogado según el protocolo", no un relato espontáneo en bruto. Las quejas breves tienen una tasa de unknown del 94 %; incluso un diálogo real rico (IMCS-21, 748 palabras / 40 turnos) sigue teniendo un 88 %. La razón es que las ramas previas del STCC filtran banderas rojas de urgencia (atragantamiento, cianosis, sin respuesta), y los corpus producidos de forma natural por definición no contienen estos casos, y el médico tampoco los pregunta — es un efecto de selección, cambiar a un corpus más rico no sirve.

② Una anamnesis real no llega a preguntar todos los criterios de una rama, así que el nivel se queda en el límite superior de esa rama. Es worst_case funcionando correctamente, pero la holgura de la cota superior depende por completo de la completitud de la anamnesis.

③ La seguridad de worst_case presupone "no generar no falsos". La salida es el nivel más urgente que no se puede descartar con la evidencia disponible (una rama solo se descarta si todas sus condiciones son no), por lo tanto el infratriaje es siempre 0 y cada no adicional en la evidencia ajusta de forma monótona (dos invariantes custodiadas por tests/). Cuando falta información, degenera en "llamar a la ambulancia para todos" — es una decisión de diseño (infratriaje 10·d² vs sobretriaje d), no un bug.

④ La clasificación en sí es silver: la referencia a nivel de rama la fija un modelo fuerte + revisión humana, pero el veredicto final sigue sin un gold de enfermera real.

Por qué unknown es un estado de primera clase

La semántica de las ramas STCC es "si alguna condición de esta rama es ⇒ acierto; si todas son no ⇒ pasar a la siguiente rama". "No se mencionó" ≠ "dijo que no": lo primero debe disparar una pregunta de seguimiento, lo segundo sí permite pasar de rama. Comprimir unknown a no equivale a fabricar negativos de la nada, y haría que el motor llegara a una rama equivocada.

Texto de los criterios

Los criterios del índice son versiones reescritas de forma independiente, uno a uno (5.214/5.214). Los umbrales puros y los términos médicos individuales («tos», «temperatura >100.4°F») se conservan tal cual. La reescritura pasó tres compuertas: validación formal de valores numéricos/negaciones/longitud/similitud, reproducción con oracle idéntica bit a bit a la original, y que los indicadores del checker aguas abajo no cayeran.

Desarrollo

uv sync
uv run pytest -q                        # 27 条回归
uv run python -m scripts.mcp_selfcheck  # oracle 回放 4,168 条判据,<1 秒

scripts/mcp_selfcheck.py es la autocomprobación de fidelidad del motor: pone cada criterio en yes y el resto en no, y comprueba la rama y la disposición a las que llega el motor. Esto no es una evaluación del modelo — si no coincide, hay un agujero en la compilación o en la evaluación.

Modelo

chenhaodev/stcc-checker-0.6b-GGUF (Q8_0 / Q4_K_M). false_no a nivel de criterio 0.0024, latencia mediana ~250 ms, extremo a extremo 1,25 s/ítem.

Apache-2.0.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    F
    maintenance
    An agentic AI system that enables healthcare professionals to log patient symptoms, retrieve similar clinical cases, and search medical documents using RAG. It integrates a Chroma vector database with the Model Context Protocol to provide real-time clinical decision support.
  • A
    license
    A
    quality
    A
    maintenance
    First-line incident triage you can trust: ranked root-cause hypotheses where every claim cites a real evidence handle — and the agent abstains rather than guess.
    1
    1
    MIT
  • A
    license
    C
    quality
    B
    maintenance
    Evidence-grounded biomedical retrieval and summarization through the Model Context Protocol, enabling queries for biomedical evidence with citation-backed results.
    2
    MIT

View all related MCP servers

Related MCP Connectors

  • Physician-reviewed medical opinions and prescriptions for AI agents.

  • Author rules from policy docs, then decide: a Rete engine gives the verdict, an LLM explains why.

  • Doctor-reviewed blood-test markers, conditions & symptoms as agent tools. EN/RU/HE. Hosted.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/devhc123/stcc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server