ICP MCP
Um SDK TypeScript amigável para desenvolvedores e type-safe para a API ICP MCP.
Documentação
icpmcp
SDK TypeScript amigável para desenvolvedores e type-safe, projetado especificamente para aproveitar a API icpmcp.
[!IMPORTANT] Este SDK ainda não está pronto para uso em produção. Para concluir a configuração, siga os passos descritos no seu workspace. Exclua esta seção antes de publicar em um gerenciador de pacotes.
Resumo
Rosetta: Construa uma Vez. Integre sua Blockchain em Qualquer Lugar.
Índice
Instalação do SDK
[!TIP] Para concluir a publicação do seu SDK no npm e em outros registros, você deve executar sua primeira ação de geração.
O SDK pode ser instalado com os gerenciadores de pacotes npm, pnpm, bun ou 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 pacote é publicado com suporte a CommonJS e ES Modules (ESM).
Servidor Model Context Protocol (MCP)
Este SDK também é um servidor MCP instalável, onde os vários métodos do SDK são expostos como ferramentas que podem ser invocadas por aplicações de IA.
Node.js v20 ou superior é necessário para executar o servidor MCP a partir do npm.
Passos de instalação para Claude
Adicione a seguinte definição de servidor ao seu arquivo claude_desktop_config.json:
{
"mcpServers": {
"icpmcp-rosetta-api": {
"command": "npx",
"args": [
"-y", "--package", "icpmcp-rosetta-api",
"--",
"mcp", "start",
"--server-url", "..."
]
}
}
}
Passos de instalação para Cursor
Crie um arquivo .cursor/mcp.json na raiz do seu projeto com o seguinte conteúdo:
{
"mcpServers": {
"icpmcp-rosetta-api": {
"command": "npx",
"args": [
"-y", "--package", "icpmcp-rosetta-api",
"--",
"mcp", "start",
"--server-url", "..."
]
}
}
}
Você também pode executar servidores MCP como um binário independente, sem dependências adicionais. Você deve baixar esses binários das releases disponíveis no Github:
curl -L -o mcp-server \
https://github.com/{org}/{repo}/releases/download/{tag}/mcp-server-bun-darwin-arm64 && \
chmod +x mcp-server
Se o repositório for privado, você deve adicionar seu PAT do Github para baixar uma release -H "Authorization: Bearer {GITHUB_PAT}".
{
"mcpServers": {
"Todos": {
"command": "./DOWNLOAD/PATH/mcp-server",
"args": [
"start"
]
}
}
}
Para uma lista completa dos argumentos do servidor, execute:
npx -y --package icpmcp -- mcp start --help
Requisitos
Para runtimes JavaScript suportados, consulte RUNTIMES.md.
Exemplo de Uso do SDK
Exemplo
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 e Operações Disponíveis
Métodos disponíveis
account
- accountBalance - Obter o Saldo de uma Conta
- accountCoins - Obter Moedas Não Gasta de uma Conta
block
- block - Obter um Bloco
- blockTransaction - Obter uma Transação de Bloco
call
- call - Fazer uma Chamada de Procedimento Específica da Rede
construction
- constructionDerive - Derivar um AccountIdentifier de uma PublicKey
- constructionPreprocess - Criar uma Solicitação para Buscar Metadados
- constructionMetadata - Obter Metadados para Construção de Transações
- constructionPayloads - Gerar uma Transação Não Assinada e Payloads de Assinatura
- constructionCombine - Criar Transação de Rede a partir de Assinaturas
- constructionParse - Analisar uma Transação
- constructionHash - Obter o Hash de uma Transação Assinada
- constructionSubmit - Enviar uma Transação Assinada
events
- eventsBlocks - [INDEXER] Obter um intervalo de BlockEvents
mempool
- mempool - Obter Todas as Transações do Mempool
- mempoolTransaction - Obter uma Transação do Mempool
network
- networkList - Obter Lista de Redes Disponíveis
- networkStatus - Obter Status da Rede
- networkOptions - Obter Opções da Rede
search
- searchTransactions - [INDEXER] Buscar Transações
Funções Independentes
Todos os métodos listados acima estão disponíveis como funções independentes. Essas funções são ideais para uso em aplicações executadas no navegador, runtimes serverless ou outros ambientes onde o tamanho do pacote da aplicação é uma preocupação principal. Ao usar um bundler para construir sua aplicação, toda funcionalidade não utilizada será excluída do pacote final ou removida por tree-shaking.
Para saber mais sobre funções independentes, consulte FUNCTIONS.md.
Funções independentes disponíveis
accountAccountBalance- Obter o Saldo de uma ContaaccountAccountCoins- Obter Moedas Não Gasta de uma ContablockBlock- Obter um BlocoblockBlockTransaction- Obter uma Transação de BlococallCall- Fazer uma Chamada de Procedimento Específica da RedeconstructionConstructionCombine- Criar Transação de Rede a partir de AssinaturasconstructionConstructionDerive- Derivar um AccountIdentifier de uma PublicKeyconstructionConstructionHash- Obter o Hash de uma Transação AssinadaconstructionConstructionMetadata- Obter Metadados para Construção de TransaçõesconstructionConstructionParse- Analisar uma TransaçãoconstructionConstructionPayloads- Gerar uma Transação Não Assinada e Payloads de AssinaturaconstructionConstructionPreprocess- Criar uma Solicitação para Buscar MetadadosconstructionConstructionSubmit- Enviar uma Transação AssinadaeventsEventsBlocks- [INDEXER] Obter um intervalo de BlockEventsmempoolMempool- Obter Todas as Transações do MempoolmempoolMempoolTransaction- Obter uma Transação do MempoolnetworkNetworkList- Obter Lista de Redes DisponíveisnetworkNetworkOptions- Obter Opções da RedenetworkNetworkStatus- Obter Status da RedesearchSearchTransactions- [INDEXER] Buscar Transações
Tentativas
Alguns dos endpoints deste SDK suportam tentativas. Se você usar o SDK sem qualquer configuração, ele usará a estratégia de tentativas padrão fornecida pela API. No entanto, a estratégia de tentativas padrão pode ser substituída por operação ou em todo o SDK.
Para alterar a estratégia de tentativas padrão para uma única chamada de API, basta fornecer um objeto retryConfig para a chamada:
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();
Se você quiser substituir a estratégia de tentativas padrão para todas as operações que suportam tentativas, você pode fornecer um retryConfig na inicialização do 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();
Tratamento de Erros
IcpmcpError é a classe base para todas as respostas de erro HTTP. Ela tem as seguintes propriedades:
| Propriedade | Tipo | Descrição |
|---|---|---|
error.message | string | Mensagem de erro |
error.statusCode | number | Código de status da resposta HTTP, ex.: 404 |
error.headers | Headers | Cabeçalhos da resposta HTTP |
error.body | string | Corpo HTTP. Pode ser uma string vazia se nenhum corpo for retornado. |
error.rawResponse | Response | Resposta HTTP bruta |
error.data$ | Opcional. Alguns erros podem conter dados estruturados. Veja Classes de Erro. |
Exemplo
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();
Classes de Erro
Erros primários:
IcpmcpError: A classe base para respostas de erro HTTP.ErrorT: Em vez de usar códigos de status HTTP para descrever erros de nó (que muitas vezes não têm um análogo bom), erros ricos são retornados usando este objeto. Tanto os campos code quanto message podem ser usados individualmente para identificar corretamente um erro. As implementações DEVEM usar valores únicos para ambos os campos. Código de status500.
Erros menos comuns (6)
Erros de rede:
ConnectionError: O cliente HTTP não conseguiu fazer uma solicitação a um servidor.RequestTimeoutError: A solicitação HTTP expirou devido a um sinal AbortSignal.RequestAbortedError: A solicitação HTTP foi abortada pelo cliente.InvalidRequestError: Qualquer entrada usada para criar uma solicitação é inválida.UnexpectedClientError: Erro não reconhecido ou inesperado.
Herda de IcpmcpError:
ResponseValidationError: Incompatibilidade de tipo entre os dados retornados do servidor e a estrutura esperada pelo SDK. Vejaerror.rawValuepara o valor bruto eerror.pretty()para uma string multilinha bem formatada.
Cliente HTTP Personalizado
O SDK TypeScript faz chamadas de API usando um HTTPClient que envolve a
Fetch API nativa. Este
cliente é um wrapper fino em torno de fetch e fornece a capacidade de anexar hooks
ao redor do ciclo de vida da solicitação que podem ser usados para modificar a solicitação ou lidar
com erros e respostas.
O construtor de HTTPClient aceita um argumento opcional fetcher que pode ser
usado para integrar um cliente HTTP de terceiros ou ao escrever testes para simular o
cliente HTTP e fornecer fixtures.
O exemplo a seguir mostra como usar o hook "beforeRequest" para adicionar um
cabeçalho personalizado e um timeout às solicitações e como usar o hook "requestError"
para registrar erros:
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 });
Depuração
Você pode configurar seu SDK para emitir logs de depuração para solicitações e respostas do SDK.
Você pode passar um logger que corresponda à interface de console como uma opção do SDK.
[!WARNING] Cuidado: os logs de depuração revelarão segredos, como tokens de API em cabeçalhos, nas mensagens de log impressas em um console ou arquivos. Recomenda-se usar este recurso apenas durante o desenvolvimento local e não em produção.
import { Icpmcp } from "icpmcp-rosetta-api";
const sdk = new Icpmcp({ debugLogger: console });
Você também pode habilitar um logger de depuração padrão definindo a variável de ambiente ICPMCP_DEBUG como true.
Desenvolvimento
Maturidade
Este SDK está em beta, e pode haver mudanças que quebram a compatibilidade entre versões sem uma atualização de versão principal. Portanto, recomendamos fixar o uso a uma versão específica do pacote. Dessa forma, você pode instalar a mesma versão todas as vezes sem mudanças que quebram a compatibilidade, a menos que você esteja intencionalmente procurando pela versão mais recente.
Contribuições
Embora valorizemos contribuições de código aberto para este SDK, esta biblioteca é gerada programaticamente. Quaisquer alterações manuais adicionadas aos arquivos internos serão sobrescritas na próxima geração. Estamos ansiosos para ouvir seu feedback. Sinta-se à vontade para abrir um PR ou uma issue com uma prova de conceito e faremos o nosso melhor para incluí-la em uma versão futura.