From 69c4c3bf391e1cb551f55926d1c5abe228e4090b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Claude?= Date: Tue, 20 May 2025 20:15:21 -0400 Subject: [PATCH 1/2] feat: creating MCP tool to add funds to escrow --- README.md | 72 ++++++++++++++++++++++++++++++++++++++++++ src/tools/add-funds.ts | 52 ++++++++++++++++++++++++++++++ src/tools/index.ts | 1 + 3 files changed, 125 insertions(+) create mode 100644 src/tools/add-funds.ts diff --git a/README.md b/README.md index 96447ce..3e04997 100644 --- a/README.md +++ b/README.md @@ -108,8 +108,10 @@ The server exposes a standard MCP interface that can be used by AI models to int The server provides the following tools for AI agents: - **GetAccountAddrTool**: Retrieve your Akash account address +- **GetBalancesTool**: Get the AKT (uakt) and other balances for a given Akash account address - **GetBidsTool**: Get bids for deployments - **CreateDeploymentTool**: Create a new deployment on Akash Network +- **AddFundsTool**: Deposit additional AKT (uakt) into a deployment escrow account - **GetSDLsTool**: Get a list of available SDLs (from awesome-akash repository) - **GetSDLTool**: Get a specific SDL by name - **SendManifestTool**: Send a manifest to a provider @@ -117,6 +119,76 @@ The server provides the following tools for AI agents: - **GetServicesTool**: Get information about active services - **UpdateDeploymentTool**: Update a deployment on Akash Network +### GetBalancesTool + +**Description:** + +Get the AKT (uakt) and other balances for a given Akash account address. + +**Input Schema:** + +```json +{ + "address": "akash1..." // Akash account address (string, required) +} +``` + +**Example Usage:** + +Request: + +```json +{ + "address": "akash1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +} +``` + +Response: + +```json +[ + { + "denom": "uakt", + "amount": "123456789" + } + // ...other tokens if present +] +``` + +### AddFundsTool + +**Description:** + +Deposit additional AKT (uakt) into a deployment escrow account. + +**Input Schema:** + +```json +{ + "address": "akash1...", // Akash account address (string, required) + "dseq": 123456, // Deployment sequence number (integer, required) + "amount": "1000000" // Amount to add in uakt (string, required) +} +``` + +**Example Usage:** + +Request: + +```json +{ + "address": "akash1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "dseq": 123456, + "amount": "1000000" +} +``` + +Response: + +```json +"...transaction raw log or error message..." +``` + ## Development ### Linting and Formatting diff --git a/src/tools/add-funds.ts b/src/tools/add-funds.ts new file mode 100644 index 0000000..11198d4 --- /dev/null +++ b/src/tools/add-funds.ts @@ -0,0 +1,52 @@ +import { z } from 'zod'; +import type { ToolDefinition, ToolContext } from '../types/index.js'; +import { createOutput } from '../utils/create-output.js'; +import { getTypeUrl } from '@akashnetwork/akashjs/build/stargate/index.js'; +import { MsgDepositDeployment } from '@akashnetwork/akash-api/akash/deployment/v1beta3'; +import { QueryClientImpl, QueryDeploymentRequest } from '@akashnetwork/akash-api/akash/deployment/v1beta3'; +import { getRpc } from '@akashnetwork/akashjs/build/rpc/index.js'; +import { SERVER_CONFIG } from '../config.js'; + +const parameters = z.object({ + address: z.string().min(1, 'Akash account address is required'), + dseq: z.number().int().positive(), + amount: z.string().min(1, 'Amount of uakt to add is required'), +}); + +export const AddFundsTool: ToolDefinition = { + name: 'add-funds', + description: 'Deposit additional AKT (uakt) into a deployment escrow account.', + parameters, + handler: async (params, context) => { + const { address, dseq, amount } = params; + try { + // 1. Validate deployment exists + const rpc = await getRpc(SERVER_CONFIG.rpcEndpoint); + const deploymentClient = new QueryClientImpl(rpc); + const queryReq = QueryDeploymentRequest.fromPartial({ + id: { owner: address, dseq }, + }); + const deploymentRes = await deploymentClient.Deployment(queryReq); + if (!deploymentRes.deployment) { + return createOutput({ error: `Deployment with owner ${address} and dseq ${dseq} not found.` }); + } + + // 2. Prepare MsgDepositDeployment + const depositMsg = MsgDepositDeployment.fromPartial({ + id: { owner: address, dseq }, + amount: { denom: 'uakt', amount: amount.toString() }, + depositor: address, + }); + const msg = { + typeUrl: getTypeUrl(MsgDepositDeployment), + value: depositMsg, + }; + + // 3. Sign and broadcast + const tx = await context.client.signAndBroadcast(address, [msg], 'auto'); + return createOutput(tx.rawLog); + } catch (error: any) { + return createOutput({ error: error.message || 'Failed to add funds to deployment.' }); + } + }, +}; \ No newline at end of file diff --git a/src/tools/index.ts b/src/tools/index.ts index 3fe016e..f40e316 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -7,3 +7,4 @@ export { GetBidsTool } from './get-bids.js'; export { CreateLeaseTool } from './create-lease.js'; export { GetAccountAddrTool } from './get-account-addr.js'; export { UpdateDeploymentTool } from './update-deployment.js'; +export { AddFundsTool } from './add-funds.js'; From df4b58cc910c2256a3085d30e8f33ae05a0b26eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Claude?= Date: Thu, 22 May 2025 08:25:27 -0400 Subject: [PATCH 2/2] feat: add tool registration to the AkashMCP class --- src/AkashMCP.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/AkashMCP.ts b/src/AkashMCP.ts index df052ab..745f174 100644 --- a/src/AkashMCP.ts +++ b/src/AkashMCP.ts @@ -13,6 +13,7 @@ import { GetServicesTool, CreateDeploymentTool, UpdateDeploymentTool, + AddFundsTool, } from './tools/index.js'; import type { ToolContext } from './types/index.js'; import type { CertificatePem } from '@akashnetwork/akashjs/build/certificates/certificate-manager/CertificateManager.js'; @@ -122,6 +123,13 @@ class AkashMCP extends McpServer { UpdateDeploymentTool.parameters.shape, async (args, extra) => UpdateDeploymentTool.handler(args, this.getToolContext()) ); + + this.tool( + AddFundsTool.name, + AddFundsTool.description, + AddFundsTool.parameters.shape, + async (args, extra) => AddFundsTool.handler(args, this.getToolContext()) + ); } public isInitialized(): boolean { return this.wallet !== null && this.client !== null && this.certificate !== null;