MCP Fusion/Core concepts/Tools
Tools
Définissez des AI Capabilities avec f.query, f.mutation et f.action : paramètres typés, middleware, la monade Result et le FSM state gating qui retire les tools que l’agent ne peut pas utiliser.
Les tools sont ce que l’agent appelle. En termes Vinkius, ce sont les AI Capabilities de votre connecteur. MCP Fusion vous donne un builder fluide avec trois points d’entrée sémantiques, et la sémantique correspond aux annotations MCP que l’agent voit.
| Builder | Signification | Annotation MCP |
|---|---|---|
f.query() | Lit des données | readOnlyHint: true |
f.mutation() | Écrit des données | Hints destructifs par tool |
f.action() | Effets de bord, appels externes | Hints destructifs par tool |
Une tool complète
export default f.mutation('billing.refund')
.describe('Refund an invoice by ID')
.withString('id', 'Invoice ID')
.withNumber('amount_cents', 'Amount to refund in CENTS')
.withOptionalEnum('reason', ['duplicate', 'customer_request', 'fraud'],
'Why the refund is happening')
.returns(InvoicePresenter)
.use(requireAuth)
.handle(async (input, ctx) => {
const result = await refunds.create(input, ctx.tenantId);
if (!result.ok) return result.response;
return result.value;
});Paramètres
.withString(name, description),.withNumber,.withBoolean,.withEnumet les variantes.withOptionalconstruisent le schema d’entrée Zod- Les tools pilotées par un model peuvent prendre
.fromModel()et réutiliser les champs fillable d’un Model comme paramètres .toonDescription()compresse la description de la tool en un format pipe qui coûte environ deux fois moins de tokens.bindState('approved', 'DISCHARGE')relie la tool à un état FSM, présenté plus bas
Middleware
.use() attache un middleware à une tool. Les middlewares se composent à la manière d’Express et chaque middleware renvoie un contexte partiel fusionné dans ctx, ce qui maintient l’auth, la résolution de tenant et le rate limiting hors de vos handlers :
// A middleware derives context: the returned object merges into ctx,
// typed through the whole fluent chain.
const withUser = f.middleware(async (ctx) => {
const user = await auth.verify(ctx.request);
return { user };
});
f.query('billing.get_profile').use(withUser);Voir Routing pour le middleware global appliqué à chaque tool d’un répertoire.
La monade Result
Les handlers qui peuvent échouer renvoient un Result au lieu de lever une exception, et le framework transforme un Failure en réponse de tool structurée sur laquelle l’agent peut agir :
import { succeed, fail, toolError } from '@mcpfusion/core';
.handle(async (input) => {
const invoice = await db.invoices.findUnique({ where: { id: input.id } });
if (!invoice) {
return fail(toolError('NOT_FOUND', {
message: 'No invoice with that ID',
availableActions: ['billing.list_invoices'],
}));
}
return succeed(invoice);
});La liste availableActions est un contexte auto-réparant : quand l’agent a choisi un mauvais ID, l’erreur lui apprend ce qu’il peut faire à la place. Voir Governance pour la façon dont la même idée fonctionne lors des changements de contrat.
FSM state gating
Certaines tools ne doivent pas exister dans certains états. Une tool de discharge n’a rien à faire visible avant qu’une facture soit approuvée. .bindState() relie la tool à un état de workflow et MCP Fusion la retire physiquement de tools/list tant que l’état l’interdit :
export default f.action('billing.discharge')
.describe('Discharge an approved invoice')
.bindState('approved', 'DISCHARGE')
.handle(async (input, ctx) => { /* ... */ });Le client reçoit notifications/tools/list_changed à mesure que l’état évolue, donc le menu de l’agent reflète la réalité. Cela élimine l’hallucination classique où le model appelle une étape hors séquence. Le state store est enfichable, avec des options Redis et edge KV, donc le gating fonctionne aussi en serverless.
Le state gating retire la tool, il ne la cache pas. L’agent ne voit jamais une tool qu’il ne peut pas appeler, donc il n’essaie jamais et ne gaspille jamais un tour sur un refus.
Prochaines étapes
- Routing : organisez les tools par fichier, regroupez plusieurs actions en une tool
- Models and Presenters : façonnez ce que chaque tool renvoie
- Testing : testez le pipeline complet en mémoire
