Skip to main content
Glama
OpenSIPS

OpenSIPS MCP Server

Official
by OpenSIPS

dlg_end

Terminate active SIP dialogs by providing Call-ID, From-tag, and To-tag. Use to tear down unwanted or stuck calls.

Instructions

End (tear down) an active dialog.

Parameters

callid: The Call-ID of the dialog to terminate. from_tag: The From-tag of the dialog. to_tag: The To-tag of the dialog.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
callidYes
from_tagYes
to_tagYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The actual MCP tool handler for 'dlg_end'. Decorated with @mcp.tool(), @audited('dlg_end'), and @require_permission('mi.write'). Accepts callid, from_tag, and to_tag parameters, builds a dialog_id, then executes the 'dlg_end_dlg' MI command via mi_client.execute().
    @mcp.tool()
    @audited("dlg_end")
    @require_permission("mi.write")
    async def dlg_end(
        ctx: Context,
        callid: str,
        from_tag: str,
        to_tag: str,
    ) -> dict[str, Any]:
        """End (tear down) an active dialog.
    
        Parameters
        ----------
        callid:
            The Call-ID of the dialog to terminate.
        from_tag:
            The From-tag of the dialog.
        to_tag:
            The To-tag of the dialog.
        """
        app = ctx.request_context.lifespan_context
        result = await app.mi_client.execute(
            "dlg_end_dlg",
            {"dialog_id": f"{callid}:{from_tag}:{to_tag}"},
        )
        return result
  • MI command registry entry for 'dlg_end_dlg' — declares its module ('dialog'), description, required params (dialog_id, extra_hdrs), permission ('mi.write'), and category ('dialog'). This is the schema/definition of the underlying MI command that dlg_end invokes.
    _r("dlg_end_dlg", "dialog", "End (tear down) a dialog", ["dialog_id", "extra_hdrs"], "mi.write", "dialog")
    _r("profile_get_size", "dialog", "Get number of dialogs in a profile", ["profile", "value"], category="dialog")
    _r("profile_list_dlgs", "dialog", "List dialogs in a profile", ["profile", "value"], category="dialog")
    _r("profile_get_values", "dialog", "Get values in a dialog profile", ["profile"], category="dialog")
    _r("profile_end_dlgs", "dialog", "End all dialogs in a profile", ["profile", "value"], "mi.write", "dialog")
  • The @mcp.tool() decorator on line 40 registers 'dlg_end' as an MCP tool with the FastMCP server instance.
    @mcp.tool()
    @audited("dlg_end")
    @require_permission("mi.write")
    async def dlg_end(
        ctx: Context,
        callid: str,
        from_tag: str,
        to_tag: str,
    ) -> dict[str, Any]:
        """End (tear down) an active dialog.
    
        Parameters
        ----------
        callid:
            The Call-ID of the dialog to terminate.
        from_tag:
            The From-tag of the dialog.
        to_tag:
            The To-tag of the dialog.
        """
        app = ctx.request_context.lifespan_context
        result = await app.mi_client.execute(
            "dlg_end_dlg",
            {"dialog_id": f"{callid}:{from_tag}:{to_tag}"},
  • The _is_idempotent() helper function. For dlg_end_dlg, it returns False (non-idempotent) because the command has 'mi.write' permission, which means the MI client will not retry dlg_end_dlg on 5xx errors.
    def _is_idempotent(method: str | None) -> bool:
        """Return True if it is safe to retry *method* on a server 5xx.
    
        Reads the per-command permission from the MI registry as a proxy for
        idempotency: anything labelled ``mi.read``, ``stats.read``,
        ``health.read``, ``db.read``, ``config.read``, ``docs.read``,
        or ``resource.read`` is read-only and therefore safe to retry. Any
        write / execute / reload / process.manage permission is treated as
        non-idempotent and will NOT be retried on 5xx.
    
        Unknown methods default to **non-idempotent** — the safe choice when
        we cannot verify the command's effect.
        """
        if not method:
            return False
        # Lazy import to avoid a circular at module load time.
        from opensips_mcp.mi.commands import MI_COMMANDS
    
        cmd = MI_COMMANDS.get(method)
        if cmd is None:
            return False
        perm = (cmd.permission or "").lower()
        return perm.endswith(".read") or perm in {"health.read", "docs.read"}
Behavior2/5

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

No annotations are provided, so the description must fully disclose behavior. It only says 'tear down' without explaining side effects (e.g., SIP messages sent, dialog state changes, or whether the dialog must be active). This lacks sufficient transparency for a destructive operation.

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 very concise: a clear one-liner followed by a parameter list. However, the parameter list essentially duplicates the schema, which could be omitted if not adding value. Otherwise, it is well-structured and front-loaded.

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 that an output schema exists (though not shown), the description need not explain return values. However, for a SIP dialog termination tool, it lacks context about prerequisites (e.g., dialog must be active) and does not indicate behavior in error cases. Sibling tools suggest a rich ecosystem, but no cross-references are provided.

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

Parameters2/5

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

Schema description coverage is 0%, and the description merely lists parameter names (callid, from_tag, to_tag) without adding any meaning beyond the schema. It does not explain what these tags represent or how to obtain them, failing to compensate for the lack of schema 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 'End (tear down) an active dialog,' specifying the action (end/tear down) and the resource (active dialog). This distinguishes it from sibling tools like dlg_list or dlg_get_profiles, which have different purposes.

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, such as using b2b_terminate for B2B sessions or other termination methods. It does not mention prerequisites or when not to use it.

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/OpenSIPS/opensips-mcp-server'

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