URL canónica
https://trusteed.xyz/.well-known/mcp-tools-manifest.json
- Cache-Control:
- public, max-age=3600, s-maxage=3600
- Content-Type:
- application/json
Trusteed soporta la firma del manifiesto público de tools MCP con Ed25519 (JWS compacto, payload detachado). Cada tool lleva hashes SHA-256 separados de su descripción y su inputSchema, permitiendo a agentes y operadores detectar cualquier cambio silencioso antes de ejecutar una tool.
Capacidad de spec — en activación
El manifiesto está disponible en una URL canónica estable con cabeceras HTTP que exponen la firma y el hash directamente, sin necesidad de parsear el cuerpo JSON para verificación rápida.
https://trusteed.xyz/.well-known/mcp-tools-manifest.json
La firma sigue el perfil JWS Compact Serialization (RFC 7515) con payload detachado: el JSON del manifiesto no se incluye dentro del token JWS, solo se firma como bytes en crudo.
EdDSA (Ed25519) — clave de 255 bits, firma de 64 bytes, resistente a ataques de canal lateral.
alg: "EdDSA", crv: "Ed25519"
Publicada en el endpoint JWKS estándar. El campo kid en el header JWS identifica qué clave usar.
https://trusteed.xyz/.well-known/jwks.json
Período de gracia: la clave anterior sigue publicada en JWKS tras introducir la nueva. Ambas son válidas durante ese período para permitir transiciones sin interrupción.
Además de la firma global del manifiesto, cada entrada de tool incluye dos hashes SHA-256 independientes que cubren la descripción y el inputSchema de la tool.
description_sha256Hash SHA-256 de la descripción de la tool. Permite detectar cambios en el texto visible al agente sin necesidad de comparar el manifiesto completo.
input_schema_sha256Hash SHA-256 del inputSchema de la tool. Los cambios de schema (nuevos parámetros, tipos, required) siempre modifican este hash, aunque la descripción no cambie.
{
"name": "search_products",
"description": "Search for products in a merchant store...",
"hashes": {
"description_sha256": "a3f2...c1d9",
"input_schema_sha256": "7b04...e82a"
}
}El "tool poisoning" (MCP-08 en la taxonomía MCP-38) consiste en modificar silenciosamente la descripción o el inputSchema de una tool para inducir al agente a escalar privilegios, filtrar datos o ejecutar acciones no autorizadas. La firma del manifiesto permite tres niveles de protección:
La firma JWS Ed25519 sobre el manifiesto completo garantiza que ningún contenido ha sido modificado en tránsito ni en el servidor. Un fallo de firma invalida todo el manifiesto.
Un cliente puede almacenar los hashes de las tools que usa y comparar en cada invocación. Si description_sha256 o input_schema_sha256 cambian sin un bump de versión, el cliente puede rechazar la llamada.
Hashes separados para descripción e inputSchema permiten políticas distintas: un operador puede tolerar cambios cosméticos en la descripción pero rechazar cualquier mutación de schema.
El campo version sigue el formato YYYY-MM-DD.N, donde N es un contador ordinal que se incrementa si se emite más de un manifiesto en el mismo día. El campo superseded_at indica cuándo una versión anterior deja de ser válida, permitiendo transiciones graduales.
{
"version": "2026-05-02.1",
"previous_version": "2026-04-15.1",
"superseded_at": "2026-05-09T00:00:00Z",
"tools": [ ... ]
}El siguiente snippet descarga el manifiesto y el JWKS, verifica la firma JWS, y comprueba los hashes de una tool específica. Requiere el paquete jose (v5+) y Node.js 18+.
import { createHash } from 'node:crypto';
import { compactVerify, createLocalJWKSet } from 'jose';
const MANIFEST_URL = 'https://trusteed.xyz/.well-known/mcp-tools-manifest.json';
const JWKS_URL = 'https://trusteed.xyz/.well-known/jwks.json';
async function fetchJson(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status} fetching ${url}`);
return res.json();
}
// 1. Fetch manifest and JWKS
const manifest = await fetchJson(MANIFEST_URL);
const jwks = await fetchJson(JWKS_URL);
const keySet = createLocalJWKSet(jwks);
// 2. Reconstruct compact JWS with the manifest body as detached payload
// The server provides the signature via X-JWS-Signature header (<kid>:<jws>)
// or the manifest body includes a top-level "_jws" field as fallback.
const rawJws = manifest._jws; // e.g. "eyJhbGciOiJFZERTQSIsImtpZCI6Ii4uLiJ9..eyJ..."
if (!rawJws) throw new Error('No _jws field found in manifest');
// 3. Verify Ed25519 signature — jose rejects tampered payloads automatically
const manifestBytes = Buffer.from(JSON.stringify(manifest, null, 0));
const { protectedHeader } = await compactVerify(rawJws, keySet, {
algorithms: ['EdDSA'],
});
// => Signature OK — kid: <opaque_key_id>
// => Manifest version: 2026-05-02.1
// 4. Verify per-tool hashes for a specific tool
const toolName = 'search_products';
const tool = manifest.tools?.find(t => t.name === toolName);
if (!tool) throw new Error(`Tool "${toolName}" not found in manifest`);
const descHash = createHash('sha256').update(tool.description, 'utf8').digest('hex');
const schemaHash = createHash('sha256')
.update(JSON.stringify(tool.inputSchema), 'utf8')
.digest('hex');
if (descHash !== tool.hashes.description_sha256) {
throw new Error('description_sha256 mismatch — possible tool poisoning!');
}
if (schemaHash !== tool.hashes.input_schema_sha256) {
throw new Error('input_schema_sha256 mismatch — possible schema mutation!');
}
// => Tool "search_products" hashes verified OK
// => description_sha256 : a1b2c3...
// => input_schema_sha256: d4e5f6...Para un script mínimo de curl + verificación de firma, ver también la página padre: Seguridad MCP.
Las claves públicas Ed25519 usadas para firmar el manifiesto se publican en el endpoint JWKS estándar RFC 7517. Usa los campos use y kid del header JWS para seleccionar la clave correcta.
{
"keys": [
{
"kty": "OKP",
"crv": "Ed25519",
"use": "sig",
"alg": "EdDSA",
"kid": "<opaque_key_id>",
"x": "<base64url_encoded_public_key>"
}
]
}https://trusteed.xyz/.well-known/jwks.json — Cache 3600s. Actualizado automáticamente durante la rotación de clave.