Skip to main content
Glama
monostate

Crossmint HR Airdrop MCP

by monostate

connect_crossmint_wallet

Link a Crossmint wallet to the HR Airdrop MCP server using an email and API key to enable Solana token distribution for employees.

Instructions

Connect a Crossmint wallet to the airdrop server

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
apiKeyYesCrossmint API key
emailYesEmail address associated with the Crossmint wallet

Implementation Reference

  • Main handler function for 'connect_crossmint_wallet' tool. Validates input with Zod, initializes Crossmint client with API key, retrieves custodial Solana wallet for the given email, extracts public key and sets default SOL balance, updates server state with connected wallet info. Includes fallback to simulation mode on connection error and prompts for API key if missing.
      private async handleConnectCrossmintWallet(args: any) {
        try {
          // Validate input
          const schema = z.object({
            email: z.string().email(),
            apiKey: z.string().optional(),
          });
          
          const { email, apiKey: providedApiKey } = schema.parse(args);
          
          // Check if API key is provided, if not, prompt the user
          if (!providedApiKey) {
            return {
              content: [
                {
                  type: 'text',
                  text: `To connect a Crossmint wallet, I need your Crossmint API key. You can get this from the Crossmint developer dashboard at https://www.crossmint.com/
    
    Please provide your Crossmint API key to continue.`,
                },
              ],
            };
          }
          
          const apiKey = providedApiKey;
          
          console.error(`Connecting Crossmint wallet for ${email}`);
          
          try {
            // In production mode, attempt to connect to the real Crossmint wallet
            console.error('PRODUCTION MODE: Attempting to connect to real Crossmint wallet');
            
            // Initialize Crossmint client
            const crossmintClient = crossmint(apiKey);
            
            // Get the wallet for this email
            const wallet = await crossmintClient.custodial({
              chain: "solana",
              connection: new Connection('https://api.mainnet-beta.solana.com', 'confirmed'),
              email
            });
            
            // Get the wallet address
            const publicKey = wallet.getAddress();
            
            // Get the SOL balance (in a real implementation, we would query the blockchain)
            // For now, we'll use a default value
            const solBalance = 1.0;
            
            console.error(`Successfully connected to real Crossmint wallet: ${publicKey}`);
            
            // Update state
            this.state.connectedWallet = {
              publicKey,
              solBalance,
            };
            
            return {
              content: [
                {
                  type: 'text',
                  text: `Crossmint wallet connected successfully for ${email}.\nPublic Key: ${publicKey}\nSOL Balance: ${solBalance} SOL`,
                },
              ],
            };
          } catch (error) {
            console.error('Error connecting to real Crossmint wallet, falling back to simulation:', error);
            
            // Generate a pseudo-random wallet address
            const publicKey = `crossmint_${Math.random().toString(36).substring(2, 10)}`;
            const solBalance = 1.0; // Default SOL balance for demo
            
            // Update state
            this.state.connectedWallet = {
              publicKey,
              solBalance,
            };
            
            return {
              content: [
                {
                  type: 'text',
                  text: `Crossmint wallet connected successfully for ${email}.\nPublic Key: ${publicKey}\nSOL Balance: ${solBalance} SOL\n\n(Note: Using simulation mode due to connection error)`,
                },
              ],
            };
          }
        } catch (error) {
          throw new McpError(
            ErrorCode.InternalError,
            `Failed to connect Crossmint wallet: ${error instanceof Error ? error.message : String(error)}`
          );
        }
      }
  • src/server.ts:134-150 (registration)
    Tool registration in ListToolsRequestSchema handler, including name, description, and input schema requiring 'email' and 'apiKey'.
      name: 'connect_crossmint_wallet',
      description: 'Connect a Crossmint wallet to the airdrop server',
      inputSchema: {
        type: 'object',
        properties: {
          email: {
            type: 'string',
            description: 'Email address associated with the Crossmint wallet',
          },
          apiKey: {
            type: 'string',
            description: 'Crossmint API key',
          },
        },
        required: ['email', 'apiKey'],
      },
    },
  • Zod schema for input validation inside the handler, requiring valid email and optional apiKey.
    const schema = z.object({
      email: z.string().email(),
      apiKey: z.string().optional(),
    });
  • src/server.ts:316-317 (registration)
    Dispatch case in CallToolRequestSchema switch statement that routes to the handler function.
    case 'connect_crossmint_wallet':
      return await this.handleConnectCrossmintWallet(args);
Behavior2/5

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

No annotations are provided, so the description carries the full burden. It states the action ('Connect') but does not disclose behavioral traits like authentication needs, side effects, or what happens upon connection (e.g., if it modifies server state or returns confirmation). This is a significant gap for a tool with no annotations.

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, clear sentence with no wasted words. It is appropriately sized and front-loaded, efficiently conveying the core purpose without unnecessary detail.

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. It lacks details on behavioral aspects (e.g., what the connection entails, error handling) and does not compensate for the absence of structured data, making it inadequate for a tool with potential state changes.

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 both parameters (apiKey and email) adequately. The description does not add any meaning beyond what the schema provides, such as format examples or usage context, meeting the baseline for high 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 ('Connect') and the resource ('Crossmint wallet to the airdrop server'), providing a specific purpose. However, it does not explicitly differentiate from the sibling tool 'connect_wallet', which might cause confusion about when to use each.

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?

No guidance is provided on when to use this tool versus alternatives, such as the sibling 'connect_wallet'. The description lacks context about prerequisites, timing, or exclusions, leaving usage unclear.

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/monostate/Employees-Airdrop-Rewards-MCP'

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