Skip to main content
Glama

add_port_forward

Publish a container port on the node's public IP (TCP or UDP).

This is how inbound UDP reaches a container. There is no other way: the container's own address is private, and the IP allow/deny rules of add_firewall_rule cannot route anything.

PORT PRESERVATION MATTERS. Leave external_port at 0 and a port is allocated from 10000-19999 — your service becomes reachable, but on a DIFFERENT number. That is fine for HTTP or ssh and broken for every protocol that carries its own port inside the payload: STUN, TURN, RTP/WebRTC, SIP, WireGuard, QUIC. For those, pass external_port equal to internal_port.

A media server needs a contiguous span, not one port — pass internal_port_end. A span is always published unchanged and counts as ONE rule against your limit.

Some ports are refused because the host or its neighbours already answer on them: 22, 80, 443, 2222, 9201, 51820, and the bands 9210-9250, 9310-9350 and 20000-20099. The last one is why the "forward UDP 20000-20999 for Janus" recipe printed in most Nextcloud Talk guides will not work here — pick a span above it, e.g. 20100-20599.

Requires: API key with write scope.

Args: slug: Site identifier internal_port: Port your service listens on inside the container protocol: "tcp" or "udp". Default: "tcp" label: Free-text note shown in the panel external_port: Publish on this exact port; 0 allocates one from the pool internal_port_end: End of a contiguous range (inclusive); 0 means one port

Returns: {"id": "...", "external_port": 3478, "internal_port": 3478, "protocol": "udp", "status": "active", "public_address": "203.0.113.5:3478", "port_preserved": true}

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "slug": "<slug>",
      "internal_port": "<internal_port>"
    },
    "name": "add_port_forward"
  }
}

Input Schema

NameRequiredDescriptionDefault
slugYes
labelNo
protocolNotcp
external_portNo
internal_portYes
internal_port_endNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Added

TDQS

A5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden—and it delivers. It discloses the external port allocation pool, the fact that spans count as one rule, that refused ports exist and why, that the caller needs write-scope API key, and the exact response shape. This is exemplary behavioral disclosure for a mutation tool.

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 long but every section earns its place: purpose, critical behavioral caveats, refused port ranges, auth requirement, parameter list, and return example. Core purpose is front-loaded, and the structure makes complex information scannable without redundancy.

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 6 parameters, no annotations, and no output schema, this description covers everything an agent needs to select and invoke the tool correctly: when to use it, how ports are allocated, how to request ranges, what will fail, how to authenticate, and what the response contains. Nothing essential is missing.

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

Parameters5/5

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

Schema description coverage is 0%, but the 'Args' section gives every parameter a meaningful explanation beyond its title: external_port's zero-allocation behavior, internal_port_end's inclusive range semantics, and protocol's allowed values and default. The description fully compensates for the schema's lack of parameter documentation.

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 states a specific verb and resource: 'Publish a container port on the node's public IP'. It also explicitly differentiates itself from add_firewall_rule, explaining that firewall rules cannot route inbound traffic to a private container address. This leaves no ambiguity about what the tool does or how it differs from nearby siblings.

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 gives explicit when-to-use guidance: it is the only way inbound UDP reaches a container, port preservation is required for protocols carrying their own port in payload, and internal_port_end should be used for contiguous spans. It also warns against a common misuse (Janus UDP range recipe) and identifies which ports will be refused, making alternatives and exclusions clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.