Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ jobs:
with:
context: .
push: true
tags: |
iexechub/mcp-server:latest
iexechub/mcp-server:v${{ steps.version.outputs.version }}
tags: iexechub/mcp-server:v${{ steps.version.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max

Expand Down
19 changes: 10 additions & 9 deletions src/tools/dataProtectorCore/getUserVoucher.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
import { getIexecProvider } from "../../utils/provider.js";
import { readWalletPrivateKey } from "../../utils/readWalletKeystore.js";
import { Wallet } from "ethers";

export const getUserVoucher = {
name: "get_user_voucher",
description: "Get the user's iExec voucher information (balance, expiration, sponsors, etc.)",
inputSchema: {
type: "object",
properties: {
wallet: { type: "string" }
query: { type: "string" },
},
required: ["wallet"],
required: [],
},
handler: async (params: any) => {
const { wallet } = params;
handler: async () => {

if (!wallet || !wallet.match(/^0x[a-fA-F0-9]{40}$/)) {
throw new McpError(ErrorCode.InvalidParams, "Invalid or missing wallet address");
}
const privateKey = await readWalletPrivateKey();
const wallet = new Wallet(privateKey);

try {

const iexecResponse = await getIexecProvider();
if (!iexecResponse.success || !iexecResponse.data) {
throw new Error(iexecResponse.error || "Failed to initialize iExec SDK");
}

const iexec = iexecResponse.data.iexec;

const userVoucher = await iexec.voucher.showUserVoucher(wallet);
const userVoucher = await iexec.voucher.showUserVoucher(wallet.address);

return {
address: userVoucher.address,
Expand All @@ -41,7 +42,7 @@ export const getUserVoucher = {
} catch (error: any) {
if (error.message.includes("No Voucher found")) {
return {
message: `No voucher found for wallet ${wallet}. Go to iExec discord to claim your voucher: https://discord.com/invite/aXH5ym5H4k`
message: `No voucher found for wallet ${wallet.address}. Go to iExec discord to claim your voucher: https://discord.com/invite/aXH5ym5H4k`
};
}
throw new McpError(ErrorCode.InternalError, error.message);
Expand Down
21 changes: 10 additions & 11 deletions src/tools/dataProtectorCore/getWalletBalance.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
import { getIexecProvider } from "../../utils/provider.js";
import { readWalletPrivateKey } from "../../utils/readWalletKeystore.js";
import { Wallet } from "ethers";

export const getWalletBalance = {
name: "get_wallet_balance",
description: "Get the RLC balance of a wallet address using iExec SDK",
inputSchema: {
type: "object",
properties: {
wallet: { type: "string" }
query: { type: "string" }
},
required: ["wallet"],
required: [],
},
handler: async (params: any) => {
const { wallet } = params;

if (!wallet || !wallet.match(/^0x[a-fA-F0-9]{40}$/)) {
throw new McpError(ErrorCode.InvalidParams, "Invalid or missing wallet address");
}
handler: async () => {
const privateKey = await readWalletPrivateKey();
const wallet = new Wallet(privateKey);

try {
const iexecResponse = await getIexecProvider();
Expand All @@ -26,15 +25,15 @@ export const getWalletBalance = {

const iexec = iexecResponse.data.iexec;

const balance = await iexec.account.checkBalance(wallet);
const balance = await iexec.account.checkBalance(wallet.address);
const stakeRLC = Number(balance.stake) * 1e-9;
const lockedRLC = Number(balance.locked) * 1e-9;

const { nRLC } = await iexec.wallet.checkBalances(wallet);
const { nRLC } = await iexec.wallet.checkBalances(wallet.address);
const onChainRLC = Number(nRLC) * 1e-9;

return {
wallet,
wallet: wallet.address,
onChainRLC,
stakeRLC,
lockedRLC
Expand Down
2 changes: 2 additions & 0 deletions src/tools/web3mail/fetchMyContacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ export const fetchMyContacts = {
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
},
required: [],
},
handler: async () => {
try {
Expand Down
12 changes: 1 addition & 11 deletions src/tools/web3mail/sendEmail.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
import { getWeb3Provider, IExecWeb3mail, WorkflowError } from '@iexec/web3mail';
import { getWeb3Provider, IExecWeb3mail } from '@iexec/web3mail';
import { readWalletPrivateKey } from '../../utils/readWalletKeystore.js';

export const sendEmail = {
Expand Down Expand Up @@ -58,21 +58,11 @@ export const sendEmail = {
if (contentType !== undefined) sendEmailParams.contentType = contentType;
if (label !== undefined) sendEmailParams.label = label;
if (useVoucher !== undefined) sendEmailParams.useVoucher = useVoucher;
console.error("Send email params:", sendEmailParams);
const response = await web3mail.sendEmail(sendEmailParams);

return response;
} catch (error: any) {
console.error("Error sending email:", error);
throw new McpError(ErrorCode.InternalError, error);
if (error instanceof WorkflowError) {
if (error.isProtocolError) {
throw new McpError(ErrorCode.InternalError, error.message);
} else {
throw new McpError(ErrorCode.InvalidParams, error.message);
}
}
throw new McpError(ErrorCode.InternalError, error.message);
}
},
};