Skip to main content
Glama

search_near_fungible_tokens

Search NEAR blockchain for fungible token contract details using specific account ID, symbol, or name terms. Limit results to manage API load efficiently.

Instructions

Search for fungible token contract information for the NEAR blockchain, based on search terms. This tool works by 'grepping' through a list of contract information JSON objects. Be careful with this tool, it can return a lot of results. Ensure that your query is specific.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
accountIDSearchTermNoThe grep-like search term to use for finding fungible token contract information by account ID.
maxNumberOfResultsNoThe maximum number of results to return. This is a limit to the number of results returned by the API. Keep this number low to avoid overwhelming the API.
nameSearchTermNoThe grep-like search term to use for finding fungible token contract information by name.
symbolSearchTermNoThe grep-like search term to use for finding fungible token contract information by symbol.

Implementation Reference

  • Handler function that searches for fungible tokens using searchFungibleTokens helper, enriches results with contract info from getFungibleTokenContractInfo, and returns formatted content.
    async (args, __) => {
      const tokenContractsSearchResult = await searchFungibleTokens(
        args.accountIDSearchTerm,
        args.symbolSearchTerm,
        args.nameSearchTerm,
        args.maxNumberOfResults,
      );
      if (!tokenContractsSearchResult.ok) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${tokenContractsSearchResult.error}`,
            },
          ],
        };
      }
      const tokenContracts = tokenContractsSearchResult.value;
    
      // get the contract info for each contract
      const contractInfoResults = await mapSemaphore(
        tokenContracts,
        4,
        async (
          contract,
        ): Promise<[string, FungibleTokenContract, Result<object, Error>]> => {
          return [
            contract.contract,
            contract,
            await getFungibleTokenContractInfo(contract.contract),
          ];
        },
      );
    
      const contractInfos = contractInfoResults.map(
        ([_, contract, contractInfoResult]) => {
          if (contractInfoResult.ok) {
            return contractInfoResult.value;
          } else {
            return contract;
          }
        },
      );
    
      return {
        content: [
          {
            type: 'text',
            text: stringify_bigint(contractInfos),
          },
        ],
      };
    },
  • Zod input schema defining parameters for searching fungible tokens: optional search terms for account ID, symbol, name, and max results.
    {
      accountIDSearchTerm: z
        .string()
        .optional()
        .describe(
          'The grep-like search term to use for finding fungible token contract information by account ID.',
        ),
      symbolSearchTerm: z
        .string()
        .optional()
        .describe(
          'The grep-like search term to use for finding fungible token contract information by symbol.',
        ),
      nameSearchTerm: z
        .string()
        .optional()
        .describe(
          'The grep-like search term to use for finding fungible token contract information by name.',
        ),
      maxNumberOfResults: z
        .number()
        .min(1)
        .max(8)
        .default(4)
        .describe(
          'The maximum number of results to return. This is a limit to the number of results returned by the API. Keep this number low to avoid overwhelming the API.',
        ),
    },
  • MCP tool registration call including name, description, input schema, and handler function.
      'search_near_fungible_tokens',
      noLeadingWhitespace`
      Search for fungible token contract information for the NEAR blockchain, based on search terms.
      This tool works by 'grepping' through a list of contract information JSON objects. Be careful
      with this tool, it can return a lot of results. Ensure that your query is specific.`,
      {
        accountIDSearchTerm: z
          .string()
          .optional()
          .describe(
            'The grep-like search term to use for finding fungible token contract information by account ID.',
          ),
        symbolSearchTerm: z
          .string()
          .optional()
          .describe(
            'The grep-like search term to use for finding fungible token contract information by symbol.',
          ),
        nameSearchTerm: z
          .string()
          .optional()
          .describe(
            'The grep-like search term to use for finding fungible token contract information by name.',
          ),
        maxNumberOfResults: z
          .number()
          .min(1)
          .max(8)
          .default(4)
          .describe(
            'The maximum number of results to return. This is a limit to the number of results returned by the API. Keep this number low to avoid overwhelming the API.',
          ),
      },
      async (args, __) => {
        const tokenContractsSearchResult = await searchFungibleTokens(
          args.accountIDSearchTerm,
          args.symbolSearchTerm,
          args.nameSearchTerm,
          args.maxNumberOfResults,
        );
        if (!tokenContractsSearchResult.ok) {
          return {
            content: [
              {
                type: 'text',
                text: `Error: ${tokenContractsSearchResult.error}`,
              },
            ],
          };
        }
        const tokenContracts = tokenContractsSearchResult.value;
    
        // get the contract info for each contract
        const contractInfoResults = await mapSemaphore(
          tokenContracts,
          4,
          async (
            contract,
          ): Promise<[string, FungibleTokenContract, Result<object, Error>]> => {
            return [
              contract.contract,
              contract,
              await getFungibleTokenContractInfo(contract.contract),
            ];
          },
        );
    
        const contractInfos = contractInfoResults.map(
          ([_, contract, contractInfoResult]) => {
            if (contractInfoResult.ok) {
              return contractInfoResult.value;
            } else {
              return contract;
            }
          },
        );
    
        return {
          content: [
            {
              type: 'text',
              text: stringify_bigint(contractInfos),
            },
          ],
        };
      },
    );
  • Helper function that fetches token list from Ref Finance API and filters by account ID, symbol, or name using regex, limiting results.
    export const searchFungibleTokens = async (
      accountIDSearchTerm: string | undefined,
      symbolSearchTerm: string | undefined,
      nameSearchTerm: string | undefined,
      maxNumberOfResults: number,
    ): Promise<Result<FungibleTokenContract[], Error>> => {
      try {
        const url = 'https://api.ref.finance/list-token';
        const response = await fetch(url);
        const data = (await response.json()) as Record<
          string,
          {
            spec: string;
            name: string;
            symbol: string;
            icon: string;
            reference: string;
            reference_hash: string;
            decimals: number;
          }
        >;
        if (!Object.keys(data).length) {
          return {
            ok: false,
            error: new Error('No tokens found'),
          };
        }
    
        // Filter tokens based on search term
        const filteredTokens = Object.entries(data)
          .filter(([contractId, tokenInfo]) => {
            // filter by account ID
            if (
              accountIDSearchTerm &&
              !new RegExp(accountIDSearchTerm, 'i').test(contractId)
            ) {
              return false;
            }
    
            // filter by symbol
            if (
              symbolSearchTerm &&
              !new RegExp(symbolSearchTerm, 'i').test(tokenInfo.symbol)
            ) {
              return false;
            }
    
            // filter by name
            if (
              nameSearchTerm &&
              !new RegExp(nameSearchTerm, 'i').test(tokenInfo.name)
            ) {
              return false;
            }
    
            return true;
          })
          .slice(0, maxNumberOfResults)
          .map(([contractId, tokenInfo]) => ({
            contract: contractId,
            ...tokenInfo,
          }));
    
        if (filteredTokens.length === 0) {
          return {
            ok: false,
            error: new Error('No matching tokens found'),
          };
        }
    
        return {
          ok: true,
          value: filteredTokens,
        };
      } catch (error) {
        return { ok: false, error: error as Error };
      }
    };
  • Supporting helper that fetches additional fungible token contract details from NearBlocks API.
    export const getFungibleTokenContractInfo = async (
      contractId: string,
    ): Promise<Result<object, Error>> => {
      try {
        const url = `https://api.nearblocks.io/v1/fts/${contractId}`;
        const response = await fetch(url);
        const data = (await response.json()) as {
          contracts?: {
            contract: string;
            name: string;
            symbol: string;
            decimals: number;
            description: string;
            website: string;
          }[];
        };
        const contracts = data?.contracts;
        if (!contracts) {
          return {
            ok: false,
            error: new Error('No fungible token contracts found'),
          };
        }
        const contractInfo = contracts.map((contract) => ({
          contract: contract.contract,
          name: contract.name,
          symbol: contract.symbol,
          decimals: contract.decimals,
          description: contract.description,
          website: contract.website,
        }));
        return {
          ok: true,
          value: contractInfo,
        };
      } catch (error) {
        return { ok: false, error: error as Error };
      }
    };
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the tool works by 'grepping' through JSON objects and warns about potentially returning many results, which is useful behavioral context. However, it doesn't mention rate limits, authentication requirements, or what happens when no results are found.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized with three sentences that each serve a purpose: stating the tool's function, explaining the implementation method, and providing a usage caution. It's front-loaded with the core purpose and avoids unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with no annotations and no output schema, the description provides adequate context about what it searches for and implementation details. However, it lacks information about return format, error conditions, or how results are structured, which would be helpful given the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters thoroughly. The description doesn't add any additional parameter semantics beyond what's in the schema, maintaining the baseline score of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches for fungible token contract information on the NEAR blockchain using search terms. It specifies the resource (fungible token contracts) and action (searching), but doesn't differentiate from sibling tools since none appear to be similar search tools for tokens.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use it (searching for fungible tokens) and includes a caution about query specificity to avoid overwhelming results. However, it doesn't explicitly mention when NOT to use it or name specific alternatives among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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