Skip to main content
Glama

tokens_send_ft

Send fungible tokens (FT) like USDC, USDT, or WNEAR between accounts on the NEAR blockchain. Specify sender, receiver, contract ID, and amount for secure token transfers following NEP-141 and NEP-148 standards.

Instructions

Send Fungible Tokens (FT) like USDC native, USDT, WNEAR, etc. based on the NEP-141 and NEP-148 standards to an account. The signer account is the sender of the tokens, and the receiver account is the recipient of the tokens. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.

Input Schema

NameRequiredDescriptionDefault
amountYesThe amount of tokens to send in the fungible token contract. e.g. 1 USDC, 0.33 USDT, 1.5 WNEAR, etc.
fungibleTokenContractAccountIdYesThe account id of the fungible token contract. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.
networkIdNomainnet
receiverAccountIdYesThe account that will receive the tokens.
signerAccountIdYesThe account that will send the tokens.

Input Schema (JSON Schema)

{ "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, "properties": { "amount": { "description": "The amount of tokens to send in the fungible token contract. e.g. 1 USDC, 0.33 USDT, 1.5 WNEAR, etc.", "type": "number" }, "fungibleTokenContractAccountId": { "description": "The account id of the fungible token contract. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.", "type": "string" }, "networkId": { "default": "mainnet", "enum": [ "mainnet" ], "type": "string" }, "receiverAccountId": { "description": "The account that will receive the tokens.", "type": "string" }, "signerAccountId": { "description": "The account that will send the tokens.", "type": "string" } }, "required": [ "signerAccountId", "receiverAccountId", "fungibleTokenContractAccountId", "amount" ], "type": "object" }

Implementation Reference

  • Handler function that performs the FT transfer: validates FT contract metadata, adjusts amount for decimals, calls ft_transfer on the token contract from the signer account.
    async (args, _) => { const connection = await connect({ networkId: args.networkId, keyStore: keystore, nodeUrl: getEndpointsByNetwork(args.networkId)[0]!, }); // check that the fungible token contract exists by getting // the metadata of the contract const fungibleTokenContractMetadataResult: Result< FungibleTokenMetadata, Error > = await getFungibleTokenContractMetadataResult( args.fungibleTokenContractAccountId, connection, ); if (!fungibleTokenContractMetadataResult.ok) { return { content: [ { type: 'text', text: `Error: ${fungibleTokenContractMetadataResult.error}`, }, ], }; } // convert the amount into the decimals of the fungible token const amountInDecimals = BigInt( args.amount * 10 ** fungibleTokenContractMetadataResult.value.decimals, ); // call the transfer function of the fungible token contract const transferResult: Result<FinalExecutionOutcome, Error> = await (async () => { try { const fungibleTokenContractResult = await getAccount( args.fungibleTokenContractAccountId, connection, ); if (!fungibleTokenContractResult.ok) { return fungibleTokenContractResult; } const fungibleTokenContract = fungibleTokenContractResult.value; const senderAccount = await connection.account( args.signerAccountId, ); const receiverAccount = await connection.account( args.receiverAccountId, ); return { ok: true, value: await senderAccount.functionCall({ contractId: fungibleTokenContract.accountId, methodName: 'ft_transfer', args: { receiver_id: receiverAccount.accountId, amount: amountInDecimals.toString(), }, gas: DEFAULT_GAS, attachedDeposit: NearToken.parse_yocto_near('1').as_yocto_near(), }), }; } catch (e) { return { ok: false, error: new Error(e as string) }; } })(); if (!transferResult.ok) { return { content: [{ type: 'text', text: `Error: ${transferResult.error}` }], }; } return { content: [ { type: 'text', text: `Transaction sent: ${stringify_bigint(transferResult.value)}`, }, ], }; },
  • Registration of the 'tokens_send_ft' MCP tool with description, input schema, and handler.
    mcp.tool( 'tokens_send_ft', noLeadingWhitespace` Send Fungible Tokens (FT) like USDC native, USDT, WNEAR, etc. based on the NEP-141 and NEP-148 standards to an account. The signer account is the sender of the tokens, and the receiver account is the recipient of the tokens. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.`, { signerAccountId: z .string() .describe('The account that will send the tokens.'), receiverAccountId: z .string() .describe('The account that will receive the tokens.'), networkId: z.enum(['mainnet']).default('mainnet'), fungibleTokenContractAccountId: z .string() .describe( 'The account id of the fungible token contract. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.', ), amount: z .number() .describe( 'The amount of tokens to send in the fungible token contract. e.g. 1 USDC, 0.33 USDT, 1.5 WNEAR, etc.', ), }, async (args, _) => { const connection = await connect({ networkId: args.networkId, keyStore: keystore, nodeUrl: getEndpointsByNetwork(args.networkId)[0]!, }); // check that the fungible token contract exists by getting // the metadata of the contract const fungibleTokenContractMetadataResult: Result< FungibleTokenMetadata, Error > = await getFungibleTokenContractMetadataResult( args.fungibleTokenContractAccountId, connection, ); if (!fungibleTokenContractMetadataResult.ok) { return { content: [ { type: 'text', text: `Error: ${fungibleTokenContractMetadataResult.error}`, }, ], }; } // convert the amount into the decimals of the fungible token const amountInDecimals = BigInt( args.amount * 10 ** fungibleTokenContractMetadataResult.value.decimals, ); // call the transfer function of the fungible token contract const transferResult: Result<FinalExecutionOutcome, Error> = await (async () => { try { const fungibleTokenContractResult = await getAccount( args.fungibleTokenContractAccountId, connection, ); if (!fungibleTokenContractResult.ok) { return fungibleTokenContractResult; } const fungibleTokenContract = fungibleTokenContractResult.value; const senderAccount = await connection.account( args.signerAccountId, ); const receiverAccount = await connection.account( args.receiverAccountId, ); return { ok: true, value: await senderAccount.functionCall({ contractId: fungibleTokenContract.accountId, methodName: 'ft_transfer', args: { receiver_id: receiverAccount.accountId, amount: amountInDecimals.toString(), }, gas: DEFAULT_GAS, attachedDeposit: NearToken.parse_yocto_near('1').as_yocto_near(), }), }; } catch (e) { return { ok: false, error: new Error(e as string) }; } })(); if (!transferResult.ok) { return { content: [{ type: 'text', text: `Error: ${transferResult.error}` }], }; } return { content: [ { type: 'text', text: `Transaction sent: ${stringify_bigint(transferResult.value)}`, }, ], }; }, );
  • Zod input schema for tokens_send_ft tool defining parameters: signerAccountId, receiverAccountId, networkId (mainnet only), fungibleTokenContractAccountId, amount (number).
    { signerAccountId: z .string() .describe('The account that will send the tokens.'), receiverAccountId: z .string() .describe('The account that will receive the tokens.'), networkId: z.enum(['mainnet']).default('mainnet'), fungibleTokenContractAccountId: z .string() .describe( 'The account id of the fungible token contract. Ensure the contract account id exists and is in the same network as the signer and receiver accounts.', ), amount: z .number() .describe( 'The amount of tokens to send in the fungible token contract. e.g. 1 USDC, 0.33 USDT, 1.5 WNEAR, etc.', ), },
  • Helper function to fetch and parse ft_metadata from FT contract, used to get decimals for amount conversion.
    export const getFungibleTokenContractMetadataResult = async ( fungibleTokenContractId: string, connection: Near, ): Promise<Result<FungibleTokenMetadata, Error>> => { try { const contractAccountResult = await getAccount( fungibleTokenContractId, connection, ); if (!contractAccountResult.ok) { return contractAccountResult; } const contractAccount = contractAccountResult.value; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const metadata = await contractAccount.viewFunction({ contractId: fungibleTokenContractId, methodName: 'ft_metadata', args: {}, gas: DEFAULT_GAS, attachedDeposit: NearToken.parse_yocto_near('1').as_yocto_near(), }); const parsedMetadata = FungibleTokenMetadataSchema.parse(metadata); return { ok: true, value: parsedMetadata }; } catch (e) { return { ok: false, error: new Error(e as string) }; } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nearai/near-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server