Skip to main content
Glama
UserAd

didlogic_mcp

list_dids_in_country_city

Retrieve available Direct Inward Dialing (DID) numbers in a specific city and country. Filter by SMS capability, view pricing, activation details, and required documents for purchase. Returns structured JSON data with pagination support.

Instructions

List of available DID in a city of a country

Args: country_id: ID of country for search city_id: ID of city in a country sms_enabled: search for DID with SMS functionality page: page of result starting with 1 per_page: how many results should be on per page

Returns a JSON object with available DIDs where: dids: Array of DID available for purchasing where: id: ID of DID country: Country name city: City name sms_enabled: Is number capable of receiving SMS channels: How many parallel channels have DID free_min: How many free minutes per month DID have activation: Activation cost for DID in USD monthly: Monthly fee for DID per_minute: Per minute cost for DID origination_per_min: per minute cost if origin based rate applied required_documents: required documents for activating number, where: 1 = Any form of ID 2 = Proof of address 3 = Proof of local address number: DID Number in E164 format pagination: Pagination details for results page: current page of results total_pages: total pages results total: total query records

403 error indicates disabled API calls for purchase.

Example:

{
    "dids": {
        "pagination": {
            "total": 52,
            "total_pages": 1,
            "current_page": 1
        },
        "dids": [
            {
                "id": 112370,
                "country": "Canada",
                "city": "Edmonton, AB",
                "sms_enabled": false,
                "no_local_cli": false,
                "channels": 4,
                "free_min": 0,
                "cnam": null,
                "activation": 1.0,
                "monthly": 1.0,
                "per_minute": 0.01,
                "origination_per_min": null,
                "required_documents": [],
                "state": "Alberta",
                "country_short_name": "CA",
                "number": "17806999999"
            }
        ]
    }
}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
city_idYesCity ID
country_idYesCountry ID
pageNoSearch page
per_pageNoSearch per page
sms_enabledNoFilter for sms enabled numbers

Implementation Reference

  • The core handler function implementing the 'list_dids_in_country_city' tool. It validates inputs using Pydantic Fields (serving as schema), constructs query parameters, calls the shared base.call_didlogic_api helper to fetch available DIDs from the DIDLogic /v2/buy/countries/{country_id}/cities/{city_id}/dids endpoint, and returns the JSON response.
    @mcp.tool()
    async def list_dids_in_country_city(
        ctx: Context,
        country_id: int = Field(description="Country ID"),
        city_id: int = Field(description="City ID"),
        sms_enabled: Optional[bool] = Field(
            description="Filter for sms enabled numbers", default=None
        ),
        page: Optional[int] = Field(description="Search page", default=None),
        per_page: Optional[int] = Field(
            description="Search per page", default=None
        )
    ) -> str:
        """
            List of available DID in a city of a country
    
            Args:
                country_id: ID of country for search
                city_id: ID of city in a country
                sms_enabled: search for DID with SMS functionality
                page: page of result starting with 1
                per_page: how many results should be on per page
    
            Returns a JSON object with available DIDs where:
                dids: Array of DID available for purchasing where:
                    id: ID of DID
                    country: Country name
                    city: City name
                    sms_enabled: Is number capable of receiving SMS
                    channels: How many parallel channels have DID
                    free_min: How many free minutes per month DID have
                    activation: Activation cost for DID in USD
                    monthly: Monthly fee for DID
                    per_minute: Per minute cost for DID
                    origination_per_min: per minute cost if origin based rate applied
                    required_documents: required documents for activating number, where:
                        1 = Any form of ID
                        2 = Proof of address
                        3 = Proof of local address
                    number: DID Number in E164 format
                pagination: Pagination details for results
                    page: current page of results
                    total_pages: total pages results
                    total: total query records
    
            403 error indicates disabled API calls for purchase.
    
            Example:
            ```
            {
                "dids": {
                    "pagination": {
                        "total": 52,
                        "total_pages": 1,
                        "current_page": 1
                    },
                    "dids": [
                        {
                            "id": 112370,
                            "country": "Canada",
                            "city": "Edmonton, AB",
                            "sms_enabled": false,
                            "no_local_cli": false,
                            "channels": 4,
                            "free_min": 0,
                            "cnam": null,
                            "activation": 1.0,
                            "monthly": 1.0,
                            "per_minute": 0.01,
                            "origination_per_min": null,
                            "required_documents": [],
                            "state": "Alberta",
                            "country_short_name": "CA",
                            "number": "17806999999"
                        }
                    ]
                }
            }
            ```
        """
    
        params = {}
        if sms_enabled is not None:
            params["sms_enabled"] = int(sms_enabled)
        if page is not None:
            params["page"] = page
        if per_page is not None:
            params["per_page"] = per_page
        response = await base.call_didlogic_api(
            ctx,
            "GET",
            f"/v2/buy/countries/{country_id}/cities/{city_id}/dids",
            params=params
        )
        return response.text
  • Registers all tools from the purchase module (including list_dids_in_country_city) by invoking the module's register_tools function on the FastMCP server instance.
    tools.purchase.register_tools(mcp)
  • Shared utility function called by the handler to perform authenticated HTTP requests to the DIDLogic API, handling auth based on transport mode (stdio or http/sse).
    async def call_didlogic_api(
        ctx: Context,
        method: str,
        path: str,
        params: Optional[Dict] = None,
        data: Optional[Dict] = None,
        json: Optional[Dict] = None
    ) -> httpx.Response:
        """
        Make a call to the Didlogic API.
    
        In HTTP/SSE mode, extracts Bearer token from request context and adds it
        to the Authorization header for each API call.
        In STDIO mode, uses the API key already configured in the client headers.
        """
        client = ctx.request_context.lifespan_context.client
    
        # In HTTP/SSE mode, get API key from request.state (set by middleware)
        extra_headers = {}
    
        # Check if we have a request object (indicates HTTP/SSE mode)
        request = getattr(ctx.request_context, "request", None)
    
        if request and hasattr(request, 'state') and hasattr(request.state, 'didlogic_api_key'):
            # HTTP/SSE mode: extract API key from request state
            api_key = request.state.didlogic_api_key
            if api_key:
                extra_headers["Authorization"] = f"Bearer {api_key}"
                logger.debug(f"Using API key from request state: {api_key[:8]}...")
            else:
                logger.warning("No API key found in request state")
        else:
            # STDIO mode: API key already in client headers from lifespan
            logger.debug("Using API key from client headers (STDIO mode)")
    
        response = await client.request(
            method=method,
            url=path,
            params=params,
            data=data,
            json=json,
            headers=extra_headers
        )
        response.raise_for_status()
        return response
Behavior4/5

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

With no annotations, the description carries full burden and provides good behavioral context: it explains the return structure in detail, mentions pagination behavior, and discloses a specific error condition (403 for disabled API calls). It doesn't cover rate limits or authentication requirements, but adds substantial value beyond basic function.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections (Args, Returns, Example), but includes verbose JSON examples that could be summarized. The core information is front-loaded, but the example adds bulk without proportional value for tool selection.

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?

For a read-only listing tool with no annotations or output schema, the description provides excellent completeness: it explains all parameters, documents the full return structure with field meanings, includes pagination details, and mentions error conditions. No significant gaps remain for agent understanding.

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?

Schema description coverage is 100%, so the baseline is 3. The description adds meaningful context by explaining sms_enabled filters 'for DID with SMS functionality' and clarifying pagination defaults (page starts at 1), which goes beyond the schema's generic descriptions.

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 verb ('List') and resource ('available DID in a city of a country'), specifying it's for purchasing. It distinguishes from siblings like list_countries or list_country_cities by focusing on available DIDs rather than geographic data.

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

Usage Guidelines4/5

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

The description implies usage when searching for purchasable DIDs in a specific location, with optional SMS filtering. It doesn't explicitly state when not to use it or name alternatives like purchase_did, but the context is clear for its purpose.

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/UserAd/didlogic_mcp'

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