Skip to main content
Glama
stampchain-io

Stampchain MCP Server

Official

search_stamps

Search Bitcoin stamps using filters like creator, collection, or stamp type to find specific digital assets on the blockchain.

Instructions

Search for Bitcoin stamps with various filtering criteria including creator, collection, and stamp type

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryNoSearch query string
creatorNoFilter by creator address
collection_idNoFilter by collection ID
cpidNoFilter by CPID
is_btc_stampNoFilter for BTC stamps only
is_cursedNoFilter for cursed stamps only
sort_orderNoSort order by stamp IDDESC
pageNoPage number
page_sizeNoItems per page

Implementation Reference

  • The main handler function for the 'search_stamps' tool. It validates input parameters, constructs query params, calls the StampchainClient.searchStamps API, formats the results, and returns a multi-response with text summary and metadata.
    public async execute(params: SearchStampsParams, context?: ToolContext): Promise<ToolResponse> {
      try {
        context?.logger?.info('Executing search_stamps tool', { params });
    
        // Validate parameters
        const validatedParams = this.validateParams(params);
    
        // Build query parameters
        const queryParams = {
          query: validatedParams.query,
          creator: validatedParams.creator,
          collection_id: validatedParams.collection_id,
          cpid: validatedParams.cpid,
          is_btc_stamp: validatedParams.is_btc_stamp,
          is_cursed: validatedParams.is_cursed,
          sort_order: validatedParams.sort_order,
          page: validatedParams.page,
          page_size: validatedParams.page_size,
        };
    
        // Remove undefined values
        Object.keys(queryParams).forEach((key) => {
          if (queryParams[key as keyof typeof queryParams] === undefined) {
            delete queryParams[key as keyof typeof queryParams];
          }
        });
    
        // Use API client from context if available, otherwise use instance client
        const client = context?.apiClient || this.apiClient;
    
        // Search stamps
        const stamps: Stamp[] = await client.searchStamps(queryParams);
    
        if (!stamps || stamps.length === 0) {
          return textResponse('No stamps found matching the search criteria');
        }
    
        // Since the API returns an array, we need to handle pagination info differently
        const total = stamps.length;
        const page = validatedParams.page || 1;
        const limit = validatedParams.page_size || 20;
    
        // Format the response
        const formattedList = formatStampList(stamps, total, page, limit);
    
        // Include metadata about the search
        const metadata = {
          total_results: total,
          current_page: page,
          page_size: limit,
          total_pages: Math.ceil(total / limit),
          query_params: queryParams,
        };
    
        return multiResponse(
          { type: 'text', text: formattedList },
          { type: 'text', text: `\nSearch Metadata:\n${JSON.stringify(metadata, null, 2)}` }
        );
      } catch (error) {
        context?.logger?.error('Error executing search_stamps tool', { error });
    
        if (error instanceof ValidationError) {
          throw error;
        }
    
        if (error instanceof ToolExecutionError) {
          throw error;
        }
    
        // Pass through the original error message for API errors
        if (error instanceof Error) {
          throw new ToolExecutionError(error.message, this.name, error);
        }
    
        throw new ToolExecutionError('Failed to search stamps', this.name, error);
      }
    }
  • Zod schema defining the input parameters and validation rules for the search_stamps tool.
    export const SearchStampsParamsSchema = z.object({
      query: z.string().optional(),
      creator: z.string().optional(),
      collection_id: z.string().optional(),
      cpid: z.string().optional(),
      is_btc_stamp: z.boolean().optional(),
      is_cursed: z.boolean().optional(),
      sort_order: z.enum(['ASC', 'DESC']).optional().default('DESC'),
      page: z.number().int().min(1).optional().default(1),
      page_size: z.number().int().min(1).max(100).optional().default(20),
      limit: z.number().int().min(1).max(1000).optional(),
      // v2.3: New filtering parameters
      from_timestamp: z.number().int().positive().optional(),
      to_timestamp: z.number().int().positive().optional(),
      min_floor_price: z.number().positive().optional(),
      max_floor_price: z.number().positive().optional(),
      activity_level: z.enum(['HOT', 'WARM', 'COOL', 'DORMANT', 'COLD']).optional(),
      include_market_data: z.boolean().optional().default(false),
      include_dispenser_info: z.boolean().optional().default(false),
    });
  • Registration of the SearchStampsTool class in the stampTools object, which aggregates all stamp-related tools for export.
    export const stampTools = {
      get_stamp: GetStampTool,
      search_stamps: SearchStampsTool,
      get_recent_stamps: GetRecentStampsTool,
      get_recent_sales: GetRecentSalesTool,
      get_market_data: GetMarketDataTool,
      get_stamp_market_data: GetStampMarketDataTool,
    };
  • Central factory function that creates all tool instances, including search_stamps from createStampTools, for use in the MCP server.
    export function createAllTools(apiClient?: StampchainClient): Record<string, ITool> {
      const client = apiClient || new StampchainClient();
    
      const stamps = createStampTools(client);
      const collections = createCollectionTools(client);
      const tokens = createTokenTools(client);
      const analysis = createStampAnalysisTools(client);
    
      return {
        ...stamps,
        ...collections,
        ...tokens,
        ...analysis,
      };
    }
  • Factory function that instantiates the SearchStampsTool instance, which can then be registered in the ToolRegistry.
    export function createStampTools(apiClient?: StampchainClient) {
      return {
        get_stamp: new GetStampTool(apiClient),
        search_stamps: new SearchStampsTool(apiClient),
        get_recent_stamps: new GetRecentStampsTool(apiClient),
        get_recent_sales: new GetRecentSalesTool(apiClient),
        get_market_data: new GetMarketDataTool(apiClient),
        get_stamp_market_data: new GetStampMarketDataTool(apiClient),
      };
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions filtering capabilities but doesn't describe important behavioral aspects: whether this is a read-only operation, what the response format looks like (e.g., list of stamps with metadata), pagination behavior (implied by page/page_size parameters but not explained), rate limits, authentication requirements, or error conditions. For a search tool with 9 parameters, this leaves significant gaps in understanding how the tool behaves.

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 a single, well-structured sentence that efficiently communicates the core functionality. It's appropriately sized for a search tool and front-loads the main purpose. There's no unnecessary repetition or verbose explanations, though it could potentially benefit from a brief second sentence about typical use cases or limitations.

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 the tool's complexity (9 parameters, search functionality) and lack of both annotations and output schema, the description is insufficiently complete. It doesn't explain what constitutes a 'Bitcoin stamp' in this context, what data is returned, how results are structured, or any limitations on search scope. For a tool that likely returns complex data structures, the description should provide more context about the expected output and behavioral characteristics.

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%, meaning all parameters are documented in the schema itself. The description adds minimal value beyond the schema by mentioning 'creator, collection, and stamp type' as examples of filtering criteria, but doesn't provide additional context about parameter relationships, typical values, or usage patterns. The baseline score of 3 reflects adequate but not enhanced parameter documentation given the comprehensive 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 action ('Search for Bitcoin stamps') and resource ('Bitcoin stamps'), making the purpose immediately understandable. It specifies the filtering capabilities ('with various filtering criteria including creator, collection, and stamp type'), which helps distinguish it from simple retrieval tools. However, it doesn't explicitly differentiate from sibling tools like 'search_collections' or 'search_tokens' beyond mentioning 'Bitcoin stamps'.

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. It doesn't mention sibling tools like 'get_recent_stamps' (for recent items without filtering), 'search_collections' (for collections rather than stamps), or 'get_stamp' (for retrieving a specific stamp by ID). There's no indication of prerequisites, limitations, or typical use cases beyond the basic search functionality.

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

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/stampchain-io/stampchain-mcp'

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