Skip to main content
Glama
palhamel

46elks MCP Server

by palhamel

send_sms

Send SMS messages to phone numbers using the 46elks API. Specify recipient number, message content, and optional sender ID or flash SMS settings for immediate delivery.

Instructions

Send SMS message via 46elks

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dry_runNoTest mode - verify request without sending actual SMS (optional, defaults to environment setting)
flashsmsNoSet to "yes" for flash SMS that displays immediately and is not stored (optional)
fromNoSender phone number or name (optional, uses default if not specified)
messageYesSMS message content (max 160 characters for single SMS)
toYesRecipient phone number with country code - MUST be a real phone number, not a placeholder (e.g., +46XXXXXXXXX for Swedish numbers)

Implementation Reference

  • src/index.ts:36-64 (registration)
    Registration of the 'send_sms' MCP tool including input schema definition.
      name: 'send_sms',
      description: 'Send SMS message via 46elks',
      inputSchema: {
        type: 'object',
        properties: {
          to: {
            type: 'string',
            description: 'Recipient phone number with country code - MUST be a real phone number, not a placeholder (e.g., +46XXXXXXXXX for Swedish numbers)'
          },
          message: {
            type: 'string',
            description: 'SMS message content (max 160 characters for single SMS)'
          },
          from: {
            type: 'string',
            description: 'Sender phone number or name (optional, uses default if not specified)'
          },
          flashsms: {
            type: 'string',
            description: 'Set to "yes" for flash SMS that displays immediately and is not stored (optional)'
          },
          dry_run: {
            type: 'boolean',
            description: 'Test mode - verify request without sending actual SMS (optional, defaults to environment setting)'
          }
        },
        required: ['to', 'message']
      }
    },
  • MCP tool handler for 'send_sms': validates parameters, calls ElksClient.sendSms, formats and returns response.
    case 'send_sms':
      const { to, message, from, flashsms, dry_run } = args as {
        to: string;
        message: string;
        from?: string;
        flashsms?: string;
        dry_run?: boolean;
      };
    
      const isDryRunMode = dry_run !== undefined ? dry_run : config.dryRun;
    
      // Validate inputs
      handleValidationError('phone number', validatePhoneNumber(to));
      const messageValidation = validateSmsMessage(message);
      handleValidationError('message', messageValidation);
      if (from) {
        handleValidationError('sender ID', validateSenderId(from));
      }
    
      // Send SMS via 46elks
      const elksClient = new ElksClient();
      const response = await elksClient.sendSms(to, message, from, dry_run, flashsms);
      
      // Format response with validation warnings
      let responseText = formatSmsResponse(response, isDryRunMode);
      
      // Add validation warning if present
      if (messageValidation.warning) {
        responseText += `\n\n${messageValidation.warning}`;
      }
      
      
      return {
        content: [
          {
            type: 'text',
            text: responseText
          }
        ]
      };
  • Core implementation of SMS sending: constructs API request to 46elks /sms endpoint and handles response.
    async sendSms(to: string, message: string, from?: string, dryRun?: boolean, flashsms?: string): Promise<SendSmsResponse> {
      const formData = new URLSearchParams({
        to,
        message,
        from: from || this.phoneNumber
      });
    
      // Add dry run parameter if enabled
      const isDryRun = dryRun !== undefined ? dryRun : this.dryRun;
      if (isDryRun) {
        formData.append('dryrun', 'yes');
      }
    
      // Add flash SMS parameter if specified
      if (flashsms === 'yes') {
        formData.append('flashsms', 'yes');
      }
    
      const response = await fetch(`${this.baseUrl}/sms`, {
        method: 'POST',
        headers: {
          'Authorization': this.auth,
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: formData
      });
    
      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`Failed to send SMS: ${response.status} ${response.statusText} - ${errorText}`);
      }
    
      return await response.json();
    }
  • TypeScript interface defining the response structure from sendSms API call.
    export interface SendSmsResponse {
      id: string;
      to: string;
      from: string;
      message: string;
      created: string;
      status: string;
      cost?: number;
      estimated_cost?: number;
      parts?: number;
    }
  • Utility function to format the sendSms response into user-friendly text output for the MCP tool.
    export const formatSmsResponse = (response: SendSmsResponse, isDryRun: boolean): string => {
      const mode = isDryRun ? '🧪 DRY RUN' : '📱 SENT';
      const cost = response.estimated_cost ? 
        `Estimated cost: ${response.estimated_cost / 10000} SEK` : 
        response.cost ? `Cost: ${response.cost / 10000} SEK` : 'Cost: N/A';
    
      let output = `${mode} SMS Status: ${response.status}\n`;
      output += `To: ${response.to}\n`;
      output += `From: ${response.from}\n`;
      output += `Message: ${response.message}\n`;
      output += `${cost}\n`;
      
      if (response.parts) {
        output += `Message parts: ${response.parts}\n`;
      }
      
      if (response.id) {
        output += `Message ID: ${response.id}\n`;
      }
      
      if (isDryRun) {
        output += '\n⚠️  This was a test - no actual SMS was sent';
      }
    
      return output;
    };
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 but offers minimal information. It mentions the service provider ('46elks') but doesn't cover critical aspects like authentication requirements, rate limits, error handling, or what happens upon sending (e.g., confirmation, costs, delivery status). This is inadequate for a mutation tool with zero annotation coverage.

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 extremely concise with just four words ('Send SMS message via 46elks'), making it front-loaded and efficient. Every word contributes essential information (action, resource, provider), with no wasted sentences or redundant phrasing.

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 complexity of a mutation tool (sending SMS) with no annotations and no output schema, the description is incomplete. It lacks details on behavioral traits (e.g., costs, delivery guarantees), error scenarios, or what the tool returns, leaving significant gaps for an AI agent to understand the tool's full context and implications.

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?

The schema description coverage is 100%, meaning all parameters are documented in the input schema itself. The description adds no additional parameter semantics beyond what's already in the schema (e.g., it doesn't explain parameter interactions or provide examples), so it meets the baseline for high schema coverage without compensating with extra value.

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 ('Send SMS message') and specifies the service provider ('via 46elks'), which provides a specific verb+resource combination. However, it doesn't differentiate this tool from its siblings like 'check_sms_status' or 'get_sms_messages', which would require explicit comparison to achieve a perfect score.

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. There are no mentions of prerequisites, when-not-to-use scenarios, or comparisons with sibling tools like 'estimate_sms_cost' for planning or 'check_sms_status' for verification, leaving the agent without contextual usage instructions.

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/palhamel/46elks-mcp-server'

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