Skip to main content
Glama
itunified-io

mcp-opnsense

by itunified-io

opnsense_if_assign

Assigns a VLAN or NIC to a free optN interface slot via SSH; required when REST API lacks assignment endpoint.

Instructions

Assign an existing VLAN or NIC device to a free optN slot via SSH. Requires OPNSENSE_SSH_ENABLED=true and the opnsense-helpers/if_assign.php script installed on the target host. Fills the gap where the OPNsense REST API has no 'Interfaces → Assignments' endpoint.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
slotYesTarget slot (e.g. 'opt1', 'opt2'). Must be free.
ifYesDevice to assign (e.g. 'vlan10' for a VLAN or 'igb0' for a real NIC)
descrNoOptional friendly description (max 120 chars)

Implementation Reference

  • The handler function for the opnsense_if_assign tool. Parses args with IfAssignSchema, constructs CLI args (--slot, --if, --descr), and runs the remote PHP helper script 'if_assign.php' via SSH. Returns the helper's JSON response, exit code, and stderr.
    case "opnsense_if_assign": {
      const ssh = requireSshClient();
      const parsed = IfAssignSchema.parse(args);
      const cliArgs = [`--slot=${parsed.slot}`, `--if=${parsed.if}`];
      if (parsed.descr !== undefined) {
        cliArgs.push(`--descr=${parsed.descr}`);
      }
      const { response, exitCode, stderr } = await ssh.runHelper(
        "if_assign.php",
        cliArgs,
      );
      return renderHelperResult(response, exitCode, stderr);
    }
  • Zod schema for input validation of opnsense_if_assign. Validates slot (optN format), if (device name like vlanNN or igb0), and optional descr (up to 120 chars).
    const IfAssignSchema = z.object({
      slot: z.string().regex(SlotRegex, "slot must match /^opt\\d+$/ (e.g. opt1)"),
      if: z
        .string()
        .regex(DeviceRegex, "device must be a VLAN (vlanNN) or a real NIC (e.g. igb0)"),
      descr: z.string().regex(DescrRegex, "invalid description charset").optional(),
    });
  • Tool definition registration for opnsense_if_assign. Declares name, description, and inputSchema with properties slot, if, and descr.
    {
      name: "opnsense_if_assign",
      description:
        "Assign an existing VLAN or NIC device to a free optN slot via SSH. Requires OPNSENSE_SSH_ENABLED=true and the opnsense-helpers/if_assign.php script installed on the target host. Fills the gap where the OPNsense REST API has no 'Interfaces → Assignments' endpoint.",
      inputSchema: {
        type: "object" as const,
        properties: {
          slot: {
            type: "string",
            description: "Target slot (e.g. 'opt1', 'opt2'). Must be free.",
          },
          if: {
            type: "string",
            description:
              "Device to assign (e.g. 'vlan10' for a VLAN or 'igb0' for a real NIC)",
          },
          descr: {
            type: "string",
            description: "Optional friendly description (max 120 chars)",
          },
        },
        required: ["slot", "if"],
      },
    },
  • src/index.ts:62-62 (registration)
    Registration of all interface tool definitions (including opnsense_if_assign) into the tool handler map in the main server entrypoint.
    for (const def of interfacesToolDefinitions) toolHandlers.set(def.name, handleInterfacesTool);
  • The SSH runHelper method that executes the PHP helper script remotely. Used by the opnsense_if_assign handler to invoke if_assign.php on the OPNsense host.
    async runHelper(script: string, args: string[]): Promise<{
      response: HelperResponse;
      exitCode: number;
      stdout: string;
      stderr: string;
    }> {
      const remoteCommand = this.buildHelperCommand(script, args);
      const result = await this.runRemote(remoteCommand);
    
      let response: HelperResponse;
      try {
        response = JSON.parse(result.stdout.trim()) as HelperResponse;
      } catch {
        throw new SshClientError(
          `helper ${script} did not emit valid JSON on stdout (exit ${result.exitCode})`,
          result.exitCode,
          result.stdout,
          result.stderr,
        );
      }
    
      return {
        response,
        exitCode: result.exitCode,
        stdout: result.stdout,
        stderr: result.stderr,
      };
    }
Behavior3/5

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

With no annotations, the description discloses that the tool performs a write operation via SSH and requires specific setup. However, it does not describe side effects, error conditions, or return format, which are important for a network configuration change 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?

Three sentences covering action, prerequisites, and justification. No redundant information. All sentences earn their place.

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

Completeness4/5

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

Given the tool has 3 simple parameters and no output schema, the description provides sufficient context: what it does, prerequisites, and why it exists. It does not detail return values or error handling, but for a configuration assignment tool this is acceptable.

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?

Schema coverage is 100%, so the schema already describes each parameter. The tool description adds context (slot must be free, device can be vlan/nic) but does not significantly extend beyond the schema descriptions. Baseline 3 is appropriate.

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 action ('Assign an existing VLAN or NIC device'), the target ('a free optN slot'), and the method ('via SSH'). It also distinguishes itself by noting it fills a REST API gap, differentiating from sibling tools like opnsense_if_list.

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 explicitly lists prerequisites (OPNSENSE_SSH_ENABLED=true and the helper script) and the use case (filling a REST API gap). It does not provide explicit when-not-to-use or alternative tools, but the context is clear enough for an agent.

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/itunified-io/mcp-opnsense'

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