MCP Fusion/Core concepts/Gating de estado FSM
Gating de estado FSM
Anti-alucinación temporal: vincula tools a estados del flujo para que una acción fuera de orden desaparezca físicamente de la lista de tools en lugar de rechazarse después de que el agente la intente.
La alucinación más costosa en un flujo de agente no es un valor equivocado: es llamar al paso cuatro antes que al tres. El agente ve una tool, la llama, el servidor la rechaza y el turno se desperdicia. MCP Fusion elimina el paso del menú.
Vincula una tool a un estado
export default f.action('invoice.discharge')
.describe('Discharge an approved invoice')
.bindState('approved', 'DISCHARGE')
.handle(async (input, ctx) => discharge(input.id));bindState(states, transition) significa que esta tool aparece en tools/list solo mientras el flujo está en uno de los estados indicados y, tras una llamada correcta, dispara transition. Los estados proceden de una máquina que configuras una vez:
const fsm = f.fsm({
id: 'invoice',
initial: 'draft',
states: {
draft: { on: { SUBMIT: 'review' } },
review: { on: { APPROVE: 'approved', REJECT: 'draft' } },
approved: { on: { DISCHARGE: 'discharged' } },
discharged: { type: 'final' },
},
});La forma es compatible con XState v5. XState es un peer opcional: cuando está instalado, el gate ejecuta un actor real; sin él, el gate usa una tabla de transiciones manual incorporada, así que la función se degrada con elegancia en vez de impedir el arranque.
Lo que experimenta el agente
- En
draft,invoice.dischargeno aparece en la lista. El agente no puede llamar a lo que no puede ver. - En la tool que lleva a
approved, la llamada correcta mueve la máquina y el servidor envíanotifications/tools/list_changed. - El cliente actualiza la lista y ahora aparece
invoice.discharge, con su propia descripción.
Esto es más fuerte que una guardia: una guardia rechaza después del intento, mientras que el gating elimina la tentación. Los errores de validación sobre el orden desaparecen de los logs porque el conflicto de orden no puede expresarse.
El gating también se aplica en la ruta de llamada, no solo en la lista. Un cliente que adivine un nombre de tool sigue recibiendo FORBIDDEN con las acciones permitidas, así que la seguridad nunca depende de que el cliente actualice su menú.
Divulgación progresiva en el esquema
Un conector vinculado a una FSM también puede reducir su propio contexto. compactDescription() da a una tool una descripción corta mientras la máquina está en el estado inicial, y el .describe() completo aparece en estados posteriores. El menú del agente en draft es más pequeño y preciso que el de la misma tool en approved, sin una segunda implementación.
Estado serverless y stateless
Una máquina de estados es estado duradero, y los transportes stateless de MCP 2.0 no tienen una sesión donde guardarla. Tres mecanismos cubren el caso:
stateHandleKey: la llamada de la tool puede llevar un argumento de handle explícito que el modelo devuelve, el patrón recomendado por la especificación para flujos stateless- id de sesión: cuando el transporte tiene uno (
Mcp-Session-Id), el gate guarda el estado por sesión - fallback por attachment: un servidor single-tenant sin ninguna de las dos claves usa una identidad en el proceso
La persistencia es una interfaz FsmStateStore que implementas tú:
interface FsmStateStore {
load(handle: string): Promise<{ state: string; updatedAt: string } | undefined>;
save(handle: string, snapshot: { state: string; updatedAt: string }): Promise<void>;
}Usa el store en memoria para un solo proceso o respáldalo con Redis, DynamoDB, un KV de edge o una fila de base de datos. El framework clona y restaura el gate por solicitud, así que las solicitudes simultáneas nunca comparten una máquina por accidente.
Cuándo usarlo
- Flujos de aprobación y revisión, nada se puede descargar antes de la aprobación
- Pagos y fulfillment, captura después de la autorización, nunca antes
- Migraciones de varios pasos y ventanas de mantenimiento destructivo
- Cualquier caso en que un orden incorrecto cueste dinero o datos y una llamada rechazada siga costando un turno
El gating de FSM se combina con Exposición de tools, porque la superficie visible cambia con el estado, y con Enrutamiento, porque las tools vinculadas a estados viven en sus propios archivos. Los handlers no cambian: siempre se escribieron para un estado del mundo.
Siguientes pasos
- Tools: los métodos del builder alrededor de
bindState - Sincronización de estado: el otro problema temporal, los datos obsoletos
- Economía de tokens: por qué compensa un menú más pequeño
