<?xml version="1.0" encoding="UTF-8"?>
<!-- xml2rfc v3  -->
<rfc category="std" docName="draft-zeng-mcp-network-mgmt-01"
     ipr="trust200902" submissionType="IETF" consensus="true"
     xml:lang="en" version="3" xmlns:xi="http://www.w3.org/2001/XInclude">

  <front>
    <title abbrev="MCP-NET">
      Model Context Protocol (MCP) Extensions for Network Equipment Management
    </title>

    <author fullname="Zeng Guanming" initials="Z." surname="Guanming">
      <organization>Huawei Technology</organization>
      <address><email>zengguanming@huawei.com</email></address>
    </author>

    <date year="2025" month="October" day="16"/>

    <abstract>
      <t>The Model Context Protocol (MCP) provides a JSON-RPC 2.0 framework
      for interaction between AI applications and external context sources.
      This document specifies minimal extensions that allow network equipment
      (routers, switches, etc.) to act as MCP servers while controllers act
      as MCP clients.  New capability tokens, tools, resources, prompts,
      and error codes are defined without breaking existing MCP
      implementations.</t>
    </abstract>
  </front>

  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>Network controllers today need to speak CLI, YANG/NETCONF, SNMP,
      gNMI, and vendor-private APIs.  Implementing a separate adapter for
      each protocol is expensive and error-prone.</t>

      <t>The Model Context Protocol (MCP) already defines a JSON-RPC 2.0
      based framing, capability negotiation, and extensible tool/resource
      model.  By adding a small set of network-specific capability flags
      and tool names, a device can expose its CLI, YANG datastores, and
      event streams through the same MCP channel that AI applications use
      for retrieving context.</t>

      <t>This document specifies those extensions.  All new elements live
      in their own capability namespace and can be ignored by generic MCP
      clients, preserving backward compatibility.</t>

      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY",
      and "OPTIONAL" in this document are to be interpreted as described
      in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when,
      and only when, they appear in all capitals, as shown here.</t>
    </section>

    <section anchor="term">
      <name>Terminology</name>
      <t>MCP        Model Context Protocol</t>
      <t>Server     MCP server running on the network device</t>
      <t>Client     MCP client running on the controller</t>
      <t>Datastore  Conventional YANG datastore (running, candidate, operational)</t>
    </section>

    <section anchor="cap">
      <name>Capability Advertisement</name>
      <t>Servers that implement this specification MUST include the following
      object inside serverCapabilities in the initialize response:</t>

      <figure>
        <sourcecode type="json"><![CDATA[
"network": {
  "yangModules": ["ietf-interfaces", "openconfig-interfaces"],
  "cliDialect": "cisco-iosxr",
  "configDatastore": ["running", "candidate", "operational"],
  "notificationStream": ["syslog", "netconf-stream", "snmp-trap"],
  "maxBulkEdit": 1000,
  "supportsRollback": true,
  "rollbackTimeout": 300
}
        ]]></sourcecode>
      </figure>

      <section anchor="cap-rationale">
        <name>Rationale for Each Field</name>
        <t>yangModules: Lists YANG modules the server can serve.  Clients use
        this to decide whether to invoke network.yang.* tools or fall back
        to CLI.</t>

        <t>cliDialect: Identifies CLI syntax (cisco-iosxr, huawei-vrp, etc.).
        Controllers can adjust prompt regex and command sequences accordingly.</t>

        <t>configDatastore: Bit-mask hint—running = editable live config;
        candidate = two-phase commit; operational = read-only state DB.
        Avoids unnecessary NETCONF hello round-trips.</t>

        <t>notificationStream: Tells the client which async event streams
        the server can translate into MCP notifications.  Client can
        subscribe only to available types.</t>

        <t>maxBulkEdit: Device-level limit to avoid oversized edit-config
        requests.  Controllers can chunk large changes.</t>

        <t>supportsRollback / rollbackTimeout: Boolean plus numeric seconds.
        Lets client know a confirmed-commit can be rolled back automatically
        if not confirmed within the window.</t>
      </section>
    </section>

    <section anchor="tools">
      <name>Tools</name>
      <t>Seven new tool names are defined.  All reuse the standard MCP
      tools/call request and MUST be listed by tools/list.</t>

      <table anchor="tooltab">
    <thead>
      <tr>
        <th align="left">Name</th>
        <th align="left">Description</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>network.cli.exec</td>
        <td>Execute operational CLI show commands</td>
      </tr>
      <tr>
        <td>network.cli.configure</td>
        <td>Enter config mode and send commands</td>
      </tr>
      <tr>
        <td>network.yang.get</td>
        <td>Retrieve YANG data node</td>
      </tr>
      <tr>
        <td>network.yang.edit</td>
        <td>Edit candidate datastore</td>
      </tr>
      <tr>
        <td>network.commit</td>
        <td>Commit candidate to running</td>
      </tr>
      <tr>
        <td>network.rollback</td>
        <td>Rollback to previous commit</td>
      </tr>
      <tr>
        <td>network.file.pull</td>
        <td>Backup config file</td>
      </tr>
      <tr>
        <td>network.file.push</td>
        <td>Restore config file</td>
      </tr>
    </tbody>
  </table>

      <t>Arguments are described by JSON Schema inside tool metadata, so SDKs
      can auto-generate bindings.  If a device only supports CLI, it
      advertises network.yang.* tools with available=false; controllers
      automatically downgrade.</t>
    </section>

    <section anchor="res">
      <name>Resources</name>
      <t>Network state is exposed as read-only resources with URI scheme
      <tt>network:///</tt>.  Examples:</t>
      <sourcecode type="text"><![CDATA[
network:///interface/TenGigE0/0/0/0
network:///routing/ipv4/route-table
network:///file/startup-config
      ]]></sourcecode>
      <t>MIME type MUST match the encoding (application/yang-data+json,
      text/plain, etc.).  Large data can be paginated using the native
      MCP resource/subscribe cursor mechanism.</t>
    </section>

    <section anchor="prompts">
      <name>Prompts</name>
      <t>Interactive assistants MAY expose prompt templates such as</t>
      <t><tt>network.troubleshoot.ping-fail</tt>,
      <tt>network.config.add-vlan</tt>, <tt>network.security.audit</tt>.</t>
      <t>Arguments are implementation specific but SHOULD use the same
      JSON Schema style as tools for consistency.</t>
    </section>

    <section anchor="err">
      <name>Error Codes</name>
      <t>New JSON-RPC error codes (registered in IANA section):</t>
      <table anchor="errtab">
    <thead>
      <tr>
        <th align="right">Code</th>
        <th align="left">Message</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td align="right">-32081</td>
        <td>Network.Timeout</td>
      </tr>
      <tr>
        <td align="right">-32082</td>
        <td>Network.Unreachable</td>
      </tr>
      <tr>
        <td align="right">-32083</td>
        <td>Network.AccessDenied</td>
      </tr>
      <tr>
        <td align="right">-32084</td>
        <td>Network.ConfigIncompatible</td>
      </tr>
      <tr>
        <td align="right">-32085</td>
        <td>Network.RollbackFailed</td>
      </tr>
      <tr>
        <td align="right">-32086</td>
        <td>Network.ConfirmedCommitTimeout</td>
      </tr>
    </tbody>
  </table>
      <t>These codes allow controllers to distinguish transport failures
      from authorization or device-level errors without parsing free-text
      messages.</t>
    </section>

    <section anchor="sec">
      <name>Security Considerations</name>
      <t>All operations run with the privileges of the authenticated MCP
      session.  Servers MUST enforce role-based access control for
      configuration commands.  Commit confirmed SHOULD be used for
      potentially disruptive changes.  Transport security is provided by
      the underlying MCP transport (TLS for HTTP, SSH port-forward for
      stdio).  Sensitive data (passwords, SNMP communities) MUST be
      redacted in logs and MCP traces.</t>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>

      <section anchor="iana-cap">
        <name>MCP Capability Tokens Registry</name>
        <t>IANA is requested to register the following value:</t>
        <ul spacing="normal">
          <li>Token: network</li>
          <li>Description: Network equipment extensions for MCP</li>
          <li>Reference: this document</li>
        </ul>
      </section>

      <section anchor="iana-err">
        <name>JSON-RPC Error Codes Registry</name>
        <t>IANA is requested to register the error codes -32081 to -32086
        in the "JSON-RPC Application-Specific Error Codes" registry,
        all pointing to this document.</t>
      </section>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <reference anchor="RFC2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="Scott Bradner">
            <organization>Harvard University</organization>
          </author>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
      </reference>

      <reference anchor="RFC8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="Barry Leiba">
            <organization>Huawei Technologies</organization>
          </author>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
      </reference>

      <reference anchor="RFC7950">
        <front>
          <title>The YANG 1.1 Data Modeling Language</title>
          <author initials="M." surname="Bjorklund" fullname="Martin Bjorklund">
            <organization>Tail-f Systems</organization>
          </author>
          <date year="2016" month="August"/>
        </front>
        <seriesInfo name="RFC" value="7950"/>
      </reference>

      <reference anchor="RFC8259">
        <front>
          <title>The JavaScript Object Notation (JSON) Data Interchange Format</title>
          <author initials="T." surname="Bray" fullname="Tim Bray">
            <organization>Textuality</organization>
          </author>
          <date year="2017" month="December"/>
        </front>
        <seriesInfo name="STD" value="90"/>
        <seriesInfo name="RFC" value="8259"/>
      </reference>
    </references>

    <references title="Informative References">
      <reference anchor="MCP">
        <front>
          <title>Model Context Protocol Specification 2025-06-18</title>
          <author><organization>Anthropic</organization></author>
          <date year="2025"/>
        </front>
        <seriesInfo name="URL" value="https://modelcontextprotocol.io/specification/2025-06-18/basic"/>
      </reference>
    </references>

    <section anchor="app-schema">
      <name>Appendix A.  JSON Schema Examples</name>
      <t>Example tool metadata snippet (pretty printed):</t>
      <sourcecode type="json"><![CDATA[
{
  "name": "network.yang.get",
  "description": "Retrieve a YANG data node",
  "inputSchema": {
    "type": "object",
    "properties": {
      "path": { "type": "string" },
      "datastore": { "enum": ["running", "operational"] }
    },
    "required": ["path"]
  }
}
      ]]></sourcecode>
    </section>
  </back>
</rfc>