Skip to main content
Glama
monostate

Crossmint HR Airdrop MCP

by monostate

upload_csv

Process employee data from a CSV file to enable Solana token airdrops, role-based allocations, and automated email notifications for corporate HR teams.

Instructions

Process employee data from a CSV file

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
filePathYesPath to the CSV file

Implementation Reference

  • src/server.ts:221-234 (registration)
    Registers the 'upload_csv' tool in the ListToolsRequestSchema handler, including name, description, and inputSchema for filePath.
    { name: 'upload_csv', description: 'Process employee data from a CSV file', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the CSV file', }, }, required: ['filePath'], }, },
  • src/server.ts:326-327 (registration)
    Dispatches 'upload_csv' tool calls to the handleUploadCsv method in the CallToolRequestSchema handler.
    case 'upload_csv': return await this.handleUploadCsv(args);
  • The primary handler for the 'upload_csv' tool. Validates input, reads and parses CSV using csv-parse/sync, matches records to existing employee wallets by email, updates names and roles, validates roles, updates server state, and returns role distribution summary.
    private async handleUploadCsv(args: any) { // Validate input const schema = z.object({ filePath: z.string(), }); const { filePath } = schema.parse(args); try { // Read and parse CSV file const fileContent = fs.readFileSync(filePath, 'utf8'); const records = csvParse(fileContent, { columns: true, skip_empty_lines: true, }); // Validate records const validRoles = ['operational', 'developer', 'manager', 'VP', 'VIP']; if (!records.length) { throw new McpError(ErrorCode.InvalidParams, 'CSV file is empty.'); } // Check required columns const firstRecord = records[0]; if (!('email' in firstRecord)) { throw new McpError(ErrorCode.InvalidParams, 'CSV file must have an "email" column.'); } // Map existing emails to records const employeesByEmail = new Map( this.state.employees.map((e) => [e.email, e]) ); // Update or create employee records const updatedEmployees = records.map((record: any) => { if (!record.email) { throw new McpError(ErrorCode.InvalidParams, 'Every row must have an email.'); } const existingEmployee = employeesByEmail.get(record.email); if (!existingEmployee) { throw new McpError( ErrorCode.InvalidParams, `Email ${record.email} does not match any generated wallet. Please generate wallets first.` ); } if (record.role && !validRoles.includes(record.role.toLowerCase())) { throw new McpError( ErrorCode.InvalidParams, `Invalid role "${record.role}" for ${record.email}. Valid roles are: ${validRoles.join(', ')}.` ); } return { ...existingEmployee, name: record.name || undefined, role: record.role?.toLowerCase() || undefined, }; }); // Update state this.state.employees = updatedEmployees; return { content: [ { type: 'text', text: ` CSV data processed successfully. Updated ${updatedEmployees.length} employee records. Role distribution: - Operational: ${updatedEmployees.filter((e: any) => e.role === 'operational').length} - Developer: ${updatedEmployees.filter((e: any) => e.role === 'developer').length} - Manager: ${updatedEmployees.filter((e: any) => e.role === 'manager').length} - VP: ${updatedEmployees.filter((e: any) => e.role === 'vp').length} - VIP: ${updatedEmployees.filter((e: any) => e.role === 'vip').length} - No role: ${updatedEmployees.filter((e: any) => !e.role).length} Next step: Calculate token amounts for each employee. `.trim(), }, ], }; } catch (error) { if (error instanceof McpError) throw error; throw new McpError( ErrorCode.InternalError, `Failed to process CSV: ${error instanceof Error ? error.message : String(error)}` ); } }
  • Zod schema for input validation within the handler (filePath: string).
    const schema = z.object({ filePath: z.string(), });

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