stcc-mcp
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 MCPOllama 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 |
|
|
| La redacción de la disposición de esa rama (de la tabla de reglas, no generada por el modelo) |
|
|
| Criterios que fundamentan la decisión + número de línea, auditable |
| 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 |
|
|
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 sí ⇒ 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.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityFmaintenanceAn 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.
- AlicenseAqualityAmaintenanceFirst-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.11MIT
- AlicenseCqualityBmaintenanceEvidence-grounded biomedical retrieval and summarization through the Model Context Protocol, enabling queries for biomedical evidence with citation-backed results.2MIT
- AlicenseAqualityBmaintenanceAuthor rules from policy docs, then decide: a Rete engine gives the verdict, an LLM explains why.8MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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