Skip to main content
Glama

SendGrid MCP Server

by deyikong
contacts.ts20.5 kB
import { z } from "zod"; import { makeRequest } from "../shared/api.js"; import { ContactSchema, ToolResult } from "../shared/types.js"; import { checkReadOnlyMode } from "../shared/env.js"; export const contactTools = { list_email_lists: { config: { title: "List Email Lists", description: "List all email lists", inputSchema: { page_size: z.number().optional().default(1000).describe("Number of results to return"), }, }, handler: async ({ page_size }: { page_size: number }): Promise<ToolResult> => { const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/lists?page_size=${page_size}`); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, create_email_list: { config: { title: "Create Email List", description: "Create a new email list in your SendGrid account", inputSchema: { name: z.string().describe("Name of the email list"), }, }, handler: async ({ name }: { name: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/lists", { method: "POST", body: JSON.stringify({ name }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, update_email_list: { config: { title: "Update Email List", description: "Update the properties of an existing email list", inputSchema: { list_id: z.string().describe("ID of the email list to update"), name: z.string().describe("New name for the email list"), }, }, handler: async ({ list_id, name }: { list_id: string; name: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/lists/${list_id}`, { method: "PATCH", body: JSON.stringify({ name }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, delete_email_list: { config: { title: "Delete Email List", description: "Delete an existing email list from your SendGrid account", inputSchema: { list_id: z.string().describe("ID of the email list to delete"), }, }, handler: async ({ list_id }: { list_id: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/lists/${list_id}`, { method: "DELETE", }); return { content: [{ type: "text", text: `List ${list_id} deleted successfully.` }] }; }, }, list_segments: { config: { title: "List Segments", description: "List all segments with their parent list relationships", }, handler: async (): Promise<ToolResult> => { const result = await makeRequest("https://api.sendgrid.com/v3/marketing/segments"); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, open_segment_creator: { config: { title: "Open Segment Creator", description: "Open SendGrid segment creator in browser", }, handler: async (): Promise<ToolResult> => { return { content: [ { type: "text", text: "Please open this URL in your browser to create a new segment:\nhttps://mc.sendgrid.com/contacts/segments/create", }, ], }; }, }, create_contact: { config: { title: "Create Contact", description: "Create new contacts in your SendGrid account", inputSchema: { contacts: z.array(ContactSchema).describe("Array of contact objects"), }, }, handler: async ({ contacts }: { contacts: any[] }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/contacts", { method: "PUT", body: JSON.stringify({ contacts }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, create_contact_with_lists: { config: { title: "Create Contact with Lists", description: "Create new contacts and assign them to specific email lists", inputSchema: { contacts: z.array(ContactSchema).describe("Array of contact objects"), list_ids: z.array(z.string()).describe("Array of list IDs to add the contact to"), }, }, handler: async ({ contacts, list_ids }: { contacts: any[]; list_ids: string[] }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/contacts", { method: "PUT", body: JSON.stringify({ contacts, list_ids }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, open_csv_uploader: { config: { title: "Open CSV Uploader", description: "Open SendGrid CSV contact upload page in browser", }, handler: async (): Promise<ToolResult> => { return { content: [ { type: "text", text: "Please open this URL in your browser to upload contacts via CSV:\nhttps://mc.sendgrid.com/contacts/import/upload-csv", }, ], }; }, }, list_custom_fields: { config: { title: "List Custom Fields", description: "List all custom fields", }, handler: async (): Promise<ToolResult> => { const result = await makeRequest("https://api.sendgrid.com/v3/marketing/field_definitions"); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, create_custom_field: { config: { title: "Create Custom Field", description: "Create a new custom field for contacts", inputSchema: { name: z.string().describe("Name of the custom field"), field_type: z.enum(["Text", "Number", "Date"]).describe("Type of the field"), }, }, handler: async ({ name, field_type }: { name: string; field_type: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/field_definitions", { method: "POST", body: JSON.stringify({ name, field_type }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, update_custom_field: { config: { title: "Update Custom Field", description: "Update an existing custom field definition", inputSchema: { field_id: z.string().describe("ID of the custom field to update"), name: z.string().describe("New name for the custom field"), }, }, handler: async ({ field_id, name }: { field_id: string; name: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/field_definitions/${field_id}`, { method: "PUT", body: JSON.stringify({ name }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, delete_custom_field: { config: { title: "Delete Custom Field", description: "Delete a custom field definition", inputSchema: { field_id: z.string().describe("ID of the custom field to delete"), }, }, handler: async ({ field_id }: { field_id: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/field_definitions/${field_id}`, { method: "DELETE", }); return { content: [{ type: "text", text: `Custom field ${field_id} deleted successfully.` }] }; }, }, list_senders: { config: { title: "List Senders", description: "List all verified senders", }, handler: async (): Promise<ToolResult> => { const result = await makeRequest("https://api.sendgrid.com/v3/marketing/senders"); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, create_sender: { config: { title: "Create Sender", description: "Create a new sender identity", inputSchema: { nickname: z.string().describe("Nickname for the sender"), from: z.object({ email: z.string().describe("From email address"), name: z.string().describe("From name"), }), reply_to: z.object({ email: z.string().describe("Reply-to email address"), name: z.string().describe("Reply-to name"), }), address: z.string().describe("Street address"), city: z.string().describe("City"), state: z.string().describe("State"), zip: z.string().describe("ZIP code"), country: z.string().describe("Country"), }, }, handler: async (senderData: any): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/senders", { method: "POST", body: JSON.stringify(senderData), }); return { content: [ { type: "text", text: `Sender created successfully. ${JSON.stringify(result, null, 2)}\n\nIMPORTANT: Please verify the sender email address if the email's domain is not in the Sender Authentication settings.`, }, ], }; }, }, delete_contact: { config: { title: "Delete Contact", description: "Delete contacts by IDs", inputSchema: { contact_ids: z.array(z.string()).describe("Array of contact IDs to delete"), }, }, handler: async ({ contact_ids }: { contact_ids: string[] }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/contacts?ids=${contact_ids.join(',')}`, { method: "DELETE", }); return { content: [{ type: "text", text: `${contact_ids.length} contact(s) deleted successfully.\n\n${JSON.stringify(result, null, 2)}` }] }; }, }, remove_contact_from_lists: { config: { title: "Remove Contacts from a Specific List", description: "Remove contacts from a specific email list", inputSchema: { list_id: z.string().describe("ID of the list to remove contacts from"), contact_ids: z.array(z.string()).describe("Array of contact IDs to remove from the list"), }, }, handler: async ({ list_id, contact_ids }: { list_id: string; contact_ids: string[] }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/lists/${list_id}/contacts?contact_ids=${contact_ids.join(',')}`, { method: "DELETE", }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, get_contact: { config: { title: "Get Contact Details", description: "Get detailed information about a specific contact by ID", inputSchema: { contact_id: z.string().describe("ID of the contact to retrieve"), }, }, handler: async ({ contact_id }: { contact_id: string }): Promise<ToolResult> => { const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/contacts/${contact_id}`); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, update_contact: { config: { title: "Update Contact", description: "Update existing contact information", inputSchema: { contacts: z.array( z.object({ id: z.string().describe("Contact ID (required for updates)"), email: z.string().email().optional().describe("Email address"), first_name: z.string().optional().describe("First name"), last_name: z.string().optional().describe("Last name"), phone_number: z.string().optional().describe("Phone number"), address_line_1: z.string().optional().describe("Address line 1"), address_line_2: z.string().optional().describe("Address line 2"), city: z.string().optional().describe("City"), state_province_region: z.string().optional().describe("State/Province/Region"), postal_code: z.string().optional().describe("Postal code"), country: z.string().optional().describe("Country"), custom_fields: z.record(z.any()).optional().describe("Custom field values"), }) ).describe("Array of contact objects with updates"), }, }, handler: async ({ contacts }: { contacts: any[] }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest("https://api.sendgrid.com/v3/marketing/contacts", { method: "PUT", body: JSON.stringify({ contacts }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, search_contacts: { config: { title: "Search Contacts", description: "Search for contacts using query conditions without creating a segment", inputSchema: { query: z.string().describe("Search query using segment conditions (e.g., 'email LIKE \"@example.com\"')"), page_size: z.number().optional().default(50).describe("Number of results to return (max 100)"), page_token: z.string().optional().describe("Token for pagination"), }, }, handler: async ({ query, page_size, page_token }: { query: string; page_size?: number; page_token?: string }): Promise<ToolResult> => { const requestBody: any = { query: query }; if (page_size) requestBody.page_size = page_size; if (page_token) requestBody.page_token = page_token; const result = await makeRequest("https://api.sendgrid.com/v3/marketing/contacts/search", { method: "POST", body: JSON.stringify(requestBody), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, search_contacts_by_emails: { config: { title: "Search Contacts by Email Addresses", description: "Search for specific contacts by their email addresses", inputSchema: { emails: z.array(z.string().email()).describe("Array of email addresses to search for"), }, }, handler: async ({ emails }: { emails: string[] }): Promise<ToolResult> => { const result = await makeRequest("https://api.sendgrid.com/v3/marketing/contacts/search/emails", { method: "POST", body: JSON.stringify({ emails }), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, list_contacts: { config: { title: "List All Contacts", description: "List all contacts with optional pagination", inputSchema: { page_size: z.number().optional().default(100).describe("Number of contacts to return (max 1000)"), page_token: z.string().optional().describe("Token for pagination"), }, }, handler: async ({ page_size, page_token }: { page_size?: number; page_token?: string }): Promise<ToolResult> => { let url = `https://api.sendgrid.com/v3/marketing/contacts?page_size=${page_size || 100}`; if (page_token) url += `&page_token=${page_token}`; const result = await makeRequest(url); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, delete_sender: { config: { title: "Delete Sender Identity", description: "Delete a verified sender identity", inputSchema: { sender_id: z.string().describe("ID of the sender identity to delete"), }, }, handler: async ({ sender_id }: { sender_id: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/verified_senders/${sender_id}`, { method: "DELETE", }); return { content: [{ type: "text", text: `Sender identity ${sender_id} deleted successfully.` }] }; }, }, update_segment: { config: { title: "Update Segment", description: "Update an existing segment's name or query criteria", inputSchema: { segment_id: z.string().describe("ID of the segment to update"), name: z.string().optional().describe("New name for the segment"), query_dsl: z.string().optional().describe("New query criteria for the segment (JSON string)"), }, }, handler: async ({ segment_id, name, query_dsl }: { segment_id: string; name?: string; query_dsl?: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const updateData: any = {}; if (name) updateData.name = name; if (query_dsl) { try { updateData.query_dsl = JSON.parse(query_dsl); } catch (error) { return { content: [{ type: "text", text: "Error: query_dsl must be valid JSON. Please provide a properly formatted query." }] }; } } if (Object.keys(updateData).length === 0) { return { content: [{ type: "text", text: "Error: Please provide either 'name' or 'query_dsl' to update." }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/segments/2.0/${segment_id}`, { method: "PATCH", body: JSON.stringify(updateData), }); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }, }, delete_segment: { config: { title: "Delete Segment", description: "Delete an existing segment", inputSchema: { segment_id: z.string().describe("ID of the segment to delete"), }, }, handler: async ({ segment_id }: { segment_id: string }): Promise<ToolResult> => { const readOnlyCheck = checkReadOnlyMode(); if (readOnlyCheck.blocked) { return { content: [{ type: "text", text: readOnlyCheck.message! }] }; } const result = await makeRequest(`https://api.sendgrid.com/v3/marketing/segments/2.0/${segment_id}`, { method: "DELETE", }); return { content: [{ type: "text", text: `Segment ${segment_id} deleted successfully.` }] }; }, }, };

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/deyikong/sendgrid-mcp'

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