ICP MCP
Un SDK de TypeScript amigable para desarrolladores y seguro en tipos para la API de ICP MCP.
Documentación
icpmcp
SDK de TypeScript amigable para desarrolladores y con seguridad de tipos, diseñado específicamente para aprovechar la API de icpmcp.
[!IMPORTANT] Este SDK aún no está listo para uso en producción. Para completar la configuración, sigue los pasos descritos en tu espacio de trabajo. Elimina esta sección antes de publicar en un gestor de paquetes.
Resumen
Rosetta: Construye una vez. Integra tu blockchain en todas partes.
Tabla de contenidos
Instalación del SDK
[!TIP] Para terminar de publicar tu SDK en npm y otros registros, debes ejecutar tu primera acción de generación.
El SDK se puede instalar con cualquiera de los gestores de paquetes npm, pnpm, bun o yarn.
NPM
npm add <UNSET>
PNPM
pnpm add <UNSET>
Bun
bun add <UNSET>
Yarn
yarn add <UNSET> zod
# Note that Yarn does not install peer dependencies automatically. You will need
# to install zod as shown above.
[!NOTE] Este paquete se publica con soporte para CommonJS y Módulos ES (ESM).
Servidor de Protocolo de Contexto de Modelo (MCP)
Este SDK también es un servidor MCP instalable donde los diversos métodos del SDK se exponen como herramientas que pueden ser invocadas por aplicaciones de IA.
Se requiere Node.js v20 o superior para ejecutar el servidor MCP desde npm.
Pasos de instalación para Claude
Añade la siguiente definición de servidor a tu archivo claude_desktop_config.json:
{
"mcpServers": {
"icpmcp-rosetta-api": {
"command": "npx",
"args": [
"-y", "--package", "icpmcp-rosetta-api",
"--",
"mcp", "start",
"--server-url", "..."
]
}
}
}
Pasos de instalación para Cursor
Crea un archivo .cursor/mcp.json en la raíz de tu proyecto con el siguiente contenido:
{
"mcpServers": {
"icpmcp-rosetta-api": {
"command": "npx",
"args": [
"-y", "--package", "icpmcp-rosetta-api",
"--",
"mcp", "start",
"--server-url", "..."
]
}
}
}
También puedes ejecutar servidores MCP como un binario independiente sin dependencias adicionales. Debes descargar estos binarios de las versiones disponibles en Github:
curl -L -o mcp-server \
https://github.com/{org}/{repo}/releases/download/{tag}/mcp-server-bun-darwin-arm64 && \
chmod +x mcp-server
Si el repositorio es privado, debes añadir tu PAT de Github para descargar una versión -H "Authorization: Bearer {GITHUB_PAT}".
{
"mcpServers": {
"Todos": {
"command": "./DOWNLOAD/PATH/mcp-server",
"args": [
"start"
]
}
}
}
Para obtener una lista completa de los argumentos del servidor, ejecuta:
npx -y --package icpmcp -- mcp start --help
Requisitos
Para conocer los entornos de ejecución de JavaScript compatibles, consulta RUNTIMES.md.
Ejemplo de uso del SDK
Ejemplo
import { Icpmcp } from "icpmcp-rosetta-api";
const icpmcp = new Icpmcp({
serverURL: "https://api.example.com",
});
async function run() {
const result = await icpmcp.network.networkList({});
console.log(result);
}
run();
Recursos y operaciones disponibles
Métodos disponibles
account
- accountBalance - Obtener el saldo de una cuenta
- accountCoins - Obtener las monedas no gastadas de una cuenta
block
- block - Obtener un bloque
- blockTransaction - Obtener una transacción de un bloque
call
- call - Realizar una llamada de procedimiento específica de la red
construction
- constructionDerive - Derivar un AccountIdentifier a partir de una PublicKey
- constructionPreprocess - Crear una solicitud para obtener metadatos
- constructionMetadata - Obtener metadatos para la construcción de transacciones
- constructionPayloads - Generar una transacción sin firmar y cargas útiles de firma
- constructionCombine - Crear una transacción de red a partir de firmas
- constructionParse - Analizar una transacción
- constructionHash - Obtener el hash de una transacción firmada
- constructionSubmit - Enviar una transacción firmada
events
- eventsBlocks - [INDEXADOR] Obtener un rango de BlockEvents
mempool
- mempool - Obtener todas las transacciones del mempool
- mempoolTransaction - Obtener una transacción del mempool
network
- networkList - Obtener la lista de redes disponibles
- networkStatus - Obtener el estado de la red
- networkOptions - Obtener las opciones de la red
search
- searchTransactions - [INDEXADOR] Buscar transacciones
Funciones independientes
Todos los métodos enumerados anteriormente están disponibles como funciones independientes. Estas funciones son ideales para aplicaciones que se ejecutan en el navegador, entornos serverless u otros entornos donde el tamaño del paquete de la aplicación es una preocupación principal. Al usar un bundler para construir tu aplicación, toda la funcionalidad no utilizada se excluirá del paquete final o se eliminará mediante tree-shaking.
Para obtener más información sobre las funciones independientes, consulta FUNCTIONS.md.
Funciones independientes disponibles
accountAccountBalance- Obtener el saldo de una cuentaaccountAccountCoins- Obtener las monedas no gastadas de una cuentablockBlock- Obtener un bloqueblockBlockTransaction- Obtener una transacción de un bloquecallCall- Realizar una llamada de procedimiento específica de la redconstructionConstructionCombine- Crear una transacción de red a partir de firmasconstructionConstructionDerive- Derivar un AccountIdentifier a partir de una PublicKeyconstructionConstructionHash- Obtener el hash de una transacción firmadaconstructionConstructionMetadata- Obtener metadatos para la construcción de transaccionesconstructionConstructionParse- Analizar una transacciónconstructionConstructionPayloads- Generar una transacción sin firmar y cargas útiles de firmaconstructionConstructionPreprocess- Crear una solicitud para obtener metadatosconstructionConstructionSubmit- Enviar una transacción firmadaeventsEventsBlocks- [INDEXADOR] Obtener un rango de BlockEventsmempoolMempool- Obtener todas las transacciones del mempoolmempoolMempoolTransaction- Obtener una transacción del mempoolnetworkNetworkList- Obtener la lista de redes disponiblesnetworkNetworkOptions- Obtener las opciones de la rednetworkNetworkStatus- Obtener el estado de la redsearchSearchTransactions- [INDEXADOR] Buscar transacciones
Reintentos
Algunos de los endpoints de este SDK admiten reintentos. Si usas el SDK sin configuración, se utilizará la estrategia de reintentos predeterminada proporcionada por la API. Sin embargo, la estrategia de reintentos predeterminada se puede anular por operación o en todo el SDK.
Para cambiar la estrategia de reintentos predeterminada para una sola llamada a la API, simplemente proporciona un objeto retryConfig a la llamada:
import { Icpmcp } from "icpmcp-rosetta-api";
const icpmcp = new Icpmcp({
serverURL: "https://api.example.com",
});
async function run() {
const result = await icpmcp.network.networkList({}, {
retries: {
strategy: "backoff",
backoff: {
initialInterval: 1,
maxInterval: 50,
exponent: 1.1,
maxElapsedTime: 100,
},
retryConnectionErrors: false,
},
});
console.log(result);
}
run();
Si deseas anular la estrategia de reintentos predeterminada para todas las operaciones que admiten reintentos, puedes proporcionar un retryConfig en la inicialización del SDK:
import { Icpmcp } from "icpmcp-rosetta-api";
const icpmcp = new Icpmcp({
serverURL: "https://api.example.com",
retryConfig: {
strategy: "backoff",
backoff: {
initialInterval: 1,
maxInterval: 50,
exponent: 1.1,
maxElapsedTime: 100,
},
retryConnectionErrors: false,
},
});
async function run() {
const result = await icpmcp.network.networkList({});
console.log(result);
}
run();
Manejo de errores
IcpmcpError es la clase base para todas las respuestas de error HTTP. Tiene las siguientes propiedades:
| Propiedad | Tipo | Descripción |
|---|---|---|
error.message | string | Mensaje de error |
error.statusCode | number | Código de estado de la respuesta HTTP, ej. 404 |
error.headers | Headers | Encabezados de la respuesta HTTP |
error.body | string | Cuerpo HTTP. Puede ser una cadena vacía si no se devuelve cuerpo. |
error.rawResponse | Response | Respuesta HTTP sin procesar |
error.data$ | Opcional. Algunos errores pueden contener datos estructurados. Ver clases de error. |
Ejemplo
import { Icpmcp } from "icpmcp-rosetta-api";
import * as errors from "icpmcp/models/errors";
const icpmcp = new Icpmcp({
serverURL: "https://api.example.com",
});
async function run() {
try {
const result = await icpmcp.network.networkList({});
console.log(result);
} catch (error) {
// The base class for HTTP error responses
if (error instanceof errors.IcpmcpError) {
console.log(error.message);
console.log(error.statusCode);
console.log(error.body);
console.log(error.headers);
// Depending on the method different errors may be thrown
if (error instanceof errors.ErrorT) {
console.log(error.data$.code); // number
console.log(error.data$.message); // string
console.log(error.data$.description); // string
console.log(error.data$.retriable); // boolean
console.log(error.data$.details); // models.Details
}
}
}
}
run();
Clases de error
Errores principales:
IcpmcpError: La clase base para respuestas de error HTTP.ErrorT: En lugar de utilizar códigos de estado HTTP para describir errores de nodo (que a menudo no tienen un análogo adecuado), se devuelven errores enriquecidos mediante este objeto. Tanto el campo code como el campo message se pueden usar individualmente para identificar correctamente un error. Las implementaciones DEBEN usar valores únicos para ambos campos. Código de estado500.
Errores menos comunes (6)
Errores de red:
ConnectionError: El cliente HTTP no pudo realizar una solicitud a un servidor.RequestTimeoutError: La solicitud HTTP expiró debido a una señal AbortSignal.RequestAbortedError: La solicitud HTTP fue abortada por el cliente.InvalidRequestError: Cualquier entrada utilizada para crear una solicitud no es válida.UnexpectedClientError: Error no reconocido o inesperado.
Hereda de IcpmcpError:
ResponseValidationError: Desajuste de tipo entre los datos devueltos por el servidor y la estructura esperada por el SDK. Consultaerror.rawValuepara el valor sin procesar yerror.pretty()para una cadena multilínea bien formateada.
Cliente HTTP personalizado
El SDK de TypeScript realiza llamadas a la API utilizando un HTTPClient que envuelve la API Fetch nativa. Este cliente es un envoltorio ligero alrededor de fetch y proporciona la capacidad de adjuntar hooks alrededor del ciclo de vida de la solicitud que se pueden usar para modificar la solicitud o manejar errores y respuestas.
El constructor de HTTPClient acepta un argumento opcional fetcher que se puede usar para integrar un cliente HTTP de terceros o al escribir pruebas para simular el cliente HTTP y proporcionar fixtures.
El siguiente ejemplo muestra cómo usar el hook "beforeRequest" para añadir un encabezado personalizado y un tiempo de espera a las solicitudes, y cómo usar el hook "requestError" para registrar errores:
import { Icpmcp } from "icpmcp-rosetta-api";
import { HTTPClient } from "icpmcp/lib/http";
const httpClient = new HTTPClient({
// fetcher takes a function that has the same signature as native `fetch`.
fetcher: (request) => {
return fetch(request);
}
});
httpClient.addHook("beforeRequest", (request) => {
const nextRequest = new Request(request, {
signal: request.signal || AbortSignal.timeout(5000)
});
nextRequest.headers.set("x-custom-header", "custom value");
return nextRequest;
});
httpClient.addHook("requestError", (error, request) => {
console.group("Request Error");
console.log("Reason:", `${error}`);
console.log("Endpoint:", `${request.method} ${request.url}`);
console.groupEnd();
});
const sdk = new Icpmcp({ httpClient });
Depuración
Puedes configurar tu SDK para emitir registros de depuración para las solicitudes y respuestas del SDK.
Puedes pasar un logger que coincida con la interfaz de console como una opción del SDK.
[!WARNING] Ten cuidado: los registros de depuración revelarán secretos, como tokens de API en los encabezados, en los mensajes impresos en una consola o archivos. Se recomienda usar esta función solo durante el desarrollo local y no en producción.
import { Icpmcp } from "icpmcp-rosetta-api";
const sdk = new Icpmcp({ debugLogger: console });
También puedes habilitar un logger de depuración predeterminado estableciendo la variable de entorno ICPMCP_DEBUG en true.
Desarrollo
Madurez
Este SDK está en beta, y puede haber cambios importantes entre versiones sin una actualización de versión principal. Por lo tanto, recomendamos fijar el uso a una versión específica del paquete. De esta manera, puedes instalar la misma versión cada vez sin cambios importantes, a menos que estés buscando intencionalmente la última versión.
Contribuciones
While we value open-source contributions to this SDK, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation. We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release.