Skip to main content
Glama
lienhage

Blockchain MCP Server

by lienhage

Decode ABI Calldata

4byte-decode

Decode ABI-encoded calldata into readable formats using 4byte.directory for Ethereum blockchain transactions. Simplify contract interaction analysis.

Instructions

Decode ABI-encoded calldata using 4byte.directory

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
calldataYesABI-encoded calldata (hexadecimal string)

Implementation Reference

  • The core handler function for the '4byte-decode' tool. It processes ABI-encoded calldata by cleaning it, extracting the function selector, fetching matching signatures from the 4byte.directory API, and formats a response with possible function signatures and remaining parameter data.
       async ({ calldata }) => {
         try {
           const cleanCalldata = calldata.startsWith('0x') ? calldata.slice(2) : calldata;
           
           if (cleanCalldata.length < 8) {
             return {
               content: [{
                 type: "text",
                 text: "Error: Calldata must have at least 4 bytes for function selector"
               }],
               isError: true
             };
           }
    
           const selector = cleanCalldata.slice(0, 8);
           const signatures = await this.getFunctionSignatures(selector);
           
           if (signatures.length === 0) {
             return {
               content: [{
                 type: "text",
                 text: `No function signatures found for selector 0x${selector}, cannot decode`
               }]
             };
           }
    
           const decodingInfo = signatures.map((sig, index) => {
             return `${index + 1}. Possible function signature: ${sig.text_signature}
    Selector: 0x${selector}
    Parameter data: 0x${cleanCalldata.slice(8)}`;
           }).join('\n\n');
    
           return {
             content: [{
               type: "text",
               text: `Calldata decode result:\n\noriginal data: 0x${cleanCalldata}\n\n${decodingInfo}\n\nNote: Need specific ABI definition to fully decode parameter values.`
             }]
           };
         } catch (error) {
           return {
             content: [{
               type: "text",
               text: `error: ${error instanceof Error ? error.message : String(error)}`
             }],
             isError: true
           };
         }
       }
  • Input schema for the '4byte-decode' tool, specifying the 'calldata' parameter as a hexadecimal string using Zod validation.
    {
      title: "Decode ABI Calldata",
      description: "Decode ABI-encoded calldata using 4byte.directory",
      inputSchema: {
        calldata: z.string().describe("ABI-encoded calldata (hexadecimal string)")
      }
    },
  • The server.registerTool call that registers the '4byte-decode' tool with the MCP server, including its name, schema, and handler function.
     server.registerTool(
       "4byte-decode",
       {
         title: "Decode ABI Calldata",
         description: "Decode ABI-encoded calldata using 4byte.directory",
         inputSchema: {
           calldata: z.string().describe("ABI-encoded calldata (hexadecimal string)")
         }
       },
       async ({ calldata }) => {
         try {
           const cleanCalldata = calldata.startsWith('0x') ? calldata.slice(2) : calldata;
           
           if (cleanCalldata.length < 8) {
             return {
               content: [{
                 type: "text",
                 text: "Error: Calldata must have at least 4 bytes for function selector"
               }],
               isError: true
             };
           }
    
           const selector = cleanCalldata.slice(0, 8);
           const signatures = await this.getFunctionSignatures(selector);
           
           if (signatures.length === 0) {
             return {
               content: [{
                 type: "text",
                 text: `No function signatures found for selector 0x${selector}, cannot decode`
               }]
             };
           }
    
           const decodingInfo = signatures.map((sig, index) => {
             return `${index + 1}. Possible function signature: ${sig.text_signature}
    Selector: 0x${selector}
    Parameter data: 0x${cleanCalldata.slice(8)}`;
           }).join('\n\n');
    
           return {
             content: [{
               type: "text",
               text: `Calldata decode result:\n\noriginal data: 0x${cleanCalldata}\n\n${decodingInfo}\n\nNote: Need specific ABI definition to fully decode parameter values.`
             }]
           };
         } catch (error) {
           return {
             content: [{
               type: "text",
               text: `error: ${error instanceof Error ? error.message : String(error)}`
             }],
             isError: true
           };
         }
       }
     );
  • Helper method used by the '4byte-decode' (and '4byte') tool to query the 4byte.directory API for function signatures matching the given selector.
      private async getFunctionSignatures(selector: string): Promise<FourByteResult[]> {
        const response = await fetch(
          `${this.baseUrl}/signatures/?hex_signature=0x${selector}&format=json`
        );
    
        if (!response.ok) {
          throw new Error(`4byte API request failed: ${response.status} ${response.statusText}`);
        }
    
        const data = await response.json() as FourByteResponse;
        return data.results || [];
      }
    } 
  • TypeScript interfaces defining the structure of responses from the 4byte.directory API, used for type safety in the tool implementation.
    interface FourByteResult {
      id: number;
      created_at: string;
      text_signature: string;
      hex_signature: string;
      bytes_signature: string;
    }
    
    interface FourByteResponse {
      count: number;
      next: string | null;
      previous: string | null;
      results: FourByteResult[];
    }
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states what the tool does but doesn't mention any behavioral traits such as whether it's read-only, requires network access, has rate limits, or what happens with invalid input. For a tool with zero annotation coverage, this leaves significant gaps in understanding its operational characteristics.

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

Conciseness5/5

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

The description is a single, efficient sentence that directly states the tool's purpose and method. Every word earns its place with no wasted text, making it appropriately sized and front-loaded.

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

Completeness2/5

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

Given no annotations and no output schema, the description is incomplete for a decoding tool. It doesn't explain what the output looks like (e.g., decoded function signature and parameters), potential error conditions, or dependencies on external services like 4byte.directory. For a tool with this complexity and lack of structured data, the description should provide more context.

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?

The input schema has 100% description coverage, with the 'calldata' parameter clearly documented as 'ABI-encoded calldata (hexadecimal string)'. The description adds no additional parameter information beyond what's in the schema, so it meets the baseline of 3 where the schema does the heavy lifting.

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 action ('Decode') and target ('ABI-encoded calldata'), and specifies the method ('using 4byte.directory'). It distinguishes from sibling tools like 'abi-decode' by mentioning the specific service used. However, it doesn't explicitly contrast with 'abi-decode' in terms of functionality differences.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like 'abi-decode' or 'sig'. It mentions 'using 4byte.directory' which hints at the decoding method, but offers no explicit when/when-not instructions or comparisons with 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/lienhage/blockchain-mcp'

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