Skip to main content
Glama
bcharleson

Instantly MCP Server

list_accounts

Retrieve all valid sending email accounts from your workspace to use as sender addresses when creating email campaigns, ensuring campaign creation success.

Instructions

List all sending accounts in the workspace. PREREQUISITE FOR CAMPAIGN CREATION: You MUST call this tool first before creating any campaigns to obtain valid email addresses for the email_list parameter. The returned accounts are the only valid sending addresses that can be used in campaigns.

CRITICAL FOR SUCCESS: Campaign creation will fail if you use email addresses that are not returned by this endpoint. Always use the exact email addresses from this response.

COMPLETE PAGINATION: To get ALL accounts, use one of these approaches:

  1. Set limit=100 or higher (automatically triggers complete pagination)

  2. Set get_all=true (forces complete pagination)

  3. Use limit="all" (string triggers complete pagination)

PAGINATION ALGORITHM: When requesting all accounts, the tool will automatically:

  • Start with limit=100 per page

  • Continue fetching until next_starting_after is null or empty results

  • Report progress: "Retrieved 100... 200... 304 total accounts"

  • Return complete dataset with validation

ACCOUNT STATUS: Look for accounts with status=1, setup_pending=false, warmup_status=1 for campaign eligibility.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
get_allNoSet to true to force complete pagination and retrieve ALL accounts regardless of limit setting.
limitNoNumber of accounts to return (1-100, default: 20). Use limit=100+ or limit="all" to trigger complete pagination that retrieves ALL accounts automatically.
starting_afterNoID of the last item from previous page for manual pagination. Not needed when using complete pagination (limit=100+).

Implementation Reference

  • Main handler execution logic for 'list_accounts' tool: validates parameters, calls getAllAccounts service, handles pagination, and returns formatted MCP response.
    case 'list_accounts': {
      console.error('[Instantly MCP] 📊 Executing list_accounts (sequential pagination)...');
    
      try {
        // Build pagination and filter parameters
        const paginationParams = {
          limit: args?.limit || 100,
          ...(args?.starting_after && { starting_after: args.starting_after }),
          ...(args?.search && { search: args.search }),
          ...(args?.status !== undefined && { status: args.status }),
          ...(args?.provider_code !== undefined && { provider_code: args.provider_code }),
          ...(args?.tag_ids && { tag_ids: args.tag_ids })
        };
    
        // Validate parameters
        const validatedData = validateListAccountsData(paginationParams);
        console.error('[Instantly MCP] 📊 Parameters validated:', validatedData);
    
        // Fetch ONE page of accounts
        const result = await getAllAccounts(apiKey, paginationParams);
    
        // Return single page with clear pagination metadata
        // Using TOON format for token efficiency (30-60% reduction for tabular data)
        return createMCPResponse({
          data: result.data,
          pagination: result.pagination,
          metadata: result.metadata,
          success: true
        });
      } catch (error: any) {
        console.error('[Instantly MCP] ❌ Error in list_accounts:', error.message);
        throw error;
      }
    }
  • Zod runtime validation schema for list_accounts input parameters.
    export const ListAccountsSchema = z.object({
      limit: PaginationLimitSchema, // Already optional in the schema definition
      starting_after: z.string().optional(),
      get_all: z.boolean().optional()
    });
  • Tool registration/definition including metadata, description, and inputSchema for MCP protocol.
    {
      name: 'list_accounts',
      title: 'List Accounts',
      description: 'List email accounts with pagination. Filter by status, provider, or tags.',
      annotations: { readOnlyHint: true },
      inputSchema: {
        type: 'object',
        properties: {
          limit: { type: 'number', description: '1-100, default: 100' },
          starting_after: { type: 'string', description: 'Cursor from pagination.next_starting_after' },
          search: { type: 'string', description: 'Search by email domain' },
          status: { type: 'number', description: '1=Active, 2=Paused, -1/-2/-3=Errors', enum: [1, 2, -1, -2, -3] },
          provider_code: { type: 'number', description: '1=IMAP, 2=Google, 3=Microsoft, 4=AWS', enum: [1, 2, 3, 4] },
          tag_ids: { type: 'string', description: 'Comma-separated tag IDs' }
        }
      }
    },
  • Core service function getAllAccounts that performs the actual API call to Instantly.ai /accounts endpoint, handles pagination and filtering, and returns structured data used by the handler.
    export async function getAllAccounts(apiKey?: string, params?: any): Promise<any> {
      console.error('[Instantly MCP] 📊 Retrieving accounts (sequential pagination)...');
    
      try {
        const startTime = Date.now();
    
        // Build query parameters for single page request
        const queryParams: any = {
          limit: params?.limit || 100, // Default to 100 items per page (API maximum)
        };
    
        // Add cursor if provided (for subsequent pages)
        if (params?.starting_after) {
          queryParams.starting_after = params.starting_after;
          console.error(`[Instantly MCP] 📄 Fetching page with cursor: ${params.starting_after}`);
        } else {
          console.error('[Instantly MCP] 📄 Fetching first page');
        }
    
        // Add API filter parameters (sent to Instantly API)
        if (params?.search) {
          queryParams.search = params.search;
          console.error(`[Instantly MCP] 🔍 Filtering by search: ${params.search}`);
        }
        if (params?.status !== undefined) {
          queryParams.status = params.status;
          console.error(`[Instantly MCP] 🔍 Filtering by status: ${params.status}`);
        }
        if (params?.provider_code !== undefined) {
          queryParams.provider_code = params.provider_code;
          console.error(`[Instantly MCP] 🔍 Filtering by provider_code: ${params.provider_code}`);
        }
        if (params?.tag_ids) {
          queryParams.tag_ids = params.tag_ids;
          console.error(`[Instantly MCP] 🔍 Filtering by tag_ids: ${params.tag_ids}`);
        }
    
        // Make single API call to /accounts endpoint
        const response = await makeInstantlyRequest(ENDPOINTS.ACCOUNTS, {
          method: 'GET',
          params: queryParams
        }, apiKey);
    
        const elapsed = Date.now() - startTime;
    
        // Extract data and pagination info from response
        const data = Array.isArray(response) ? response : (response.items || response.data || []);
        const nextCursor = response.next_starting_after || null;
        const hasMore = !!nextCursor;
    
        console.error(`[Instantly MCP] ✅ Retrieved ${data.length} accounts in ${elapsed}ms (has_more: ${hasMore})`);
    
        // Return single page with clear pagination metadata
        return {
          data,
          pagination: {
            returned_count: data.length,
            has_more: hasMore,
            next_starting_after: nextCursor,
            limit: queryParams.limit,
            current_page_note: hasMore
              ? `Retrieved ${data.length} accounts. More results available. To get next page, call list_accounts again with starting_after='${nextCursor}'`
              : `Retrieved all available accounts (${data.length} items).`
          },
          metadata: {
            request_time_ms: elapsed,
            success: true,
            filters_applied: {
              ...(params?.search && { search: params.search }),
              ...(params?.status !== undefined && { status: params.status }),
              ...(params?.provider_code !== undefined && { provider_code: params.provider_code }),
              ...(params?.tag_ids && { tag_ids: params.tag_ids })
            }
          }
        };
      } catch (error) {
        console.error('[Instantly MCP] ❌ Error retrieving accounts:', error);
        throw error;
      }
    }
  • Central tools registry where accountTools (including list_accounts) is imported and included in TOOLS_DEFINITION array used by MCP server for tool listing and registration.
    export const TOOLS_DEFINITION = buildToolsDefinition();
Behavior5/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 and does so comprehensively. It explains the pagination algorithm, progress reporting, validation behavior, and account status filtering for campaign eligibility. It also details the three different approaches to trigger complete pagination, which goes well beyond what the input schema provides.

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 well-structured with clear sections (prerequisite, critical note, pagination approaches, algorithm, account status) and uses bold headings effectively. While it contains multiple paragraphs, each sentence earns its place by providing essential information. The front-loaded purpose statement is clear, though some technical details could potentially be streamlined.

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

Completeness5/5

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

Given the complexity of pagination behavior, campaign prerequisites, and account eligibility requirements, the description provides complete context despite having no annotations and no output schema. It explains the tool's role in the workflow, how to use it effectively, what to expect from its behavior, and how to interpret the results for downstream operations like campaign creation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so the baseline is 3. However, the description adds significant value by explaining the interaction between parameters (e.g., how 'limit' interacts with 'get_all' and 'starting_after'), the practical implications of different limit values, and the three different approaches to trigger complete pagination. This provides context beyond the individual parameter descriptions in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('List all sending accounts') and resource ('in the workspace'), distinguishing it from sibling tools like 'get_account_details' which retrieves details for a specific account. It explicitly identifies the resource as 'sending accounts' rather than generic accounts.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool: 'PREREQUISITE FOR CAMPAIGN CREATION: You MUST call this tool first before creating any campaigns.' It also explains the consequence of not using it: 'Campaign creation will fail if you use email addresses that are not returned by this endpoint.' This gives clear context for when this tool is necessary versus alternatives.

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/bcharleson/Instantly-MCP'

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