iana-registries-mcp-server

v0.2.0 pre-1.0

Look up IANA ports, media types, HTTP status codes and fields, URI schemes, enterprise numbers, and BCP 47 language tags; check RFC status; search and read any IANA registry via MCP. STDIO or Streamable HTTP.

iana-registries.caseyjhand.com/mcp
claude mcp add --transport http iana-registries-mcp-server https://iana-registries.caseyjhand.com/mcp
codex mcp add iana-registries-mcp-server --url https://iana-registries.caseyjhand.com/mcp
{
  "mcpServers": {
    "iana-registries-mcp-server": {
      "url": "https://iana-registries.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http iana-registries-mcp-server https://iana-registries.caseyjhand.com/mcp
{
  "mcpServers": {
    "iana-registries-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://iana-registries.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "iana-registries-mcp-server": {
      "type": "http",
      "url": "https://iana-registries.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://iana-registries.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

10

iana_lookup_port

open-world

Look up IANA service name and transport protocol port assignments. Pass exactly one of `port` (a number, 0–65535), `service` (an exact service name such as "postgresql"), or `keyword` (words matched against service names and descriptions). Results list every transport (tcp, udp, sctp, dccp) separately, report the registry range row containing an unassigned port, and classify the port as System (0–1023), User (1024–49151), or Dynamic/Private (49152–65535). Service names registered without a port (DNS-SD names) appear with no port.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_port",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "port": {
      "description": "Port number, 0–65535 (a digit string such as \"443\" also works). Returns every row for that port plus the range row containing it. Pass exactly one of port, service, or keyword.",
      "type": "integer",
      "minimum": 0,
      "maximum": 65535
    },
    "service": {
      "description": "Exact service name, case-insensitive, up to 15 characters, e.g. \"postgresql\" or \"whois++\". Pass exactly one of port, service, or keyword.",
      "type": "string",
      "pattern": "^[A-Za-z0-9+*/._-]{1,15}$"
    },
    "keyword": {
      "description": "Words matched as whole tokens against service names and descriptions, e.g. \"network time\". Pass exactly one of port, service, or keyword.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "transport": {
      "description": "Keep only rows for this transport protocol. Rows without a transport (most range rows and every service name without a port) are always kept. Applies to every mode.",
      "type": "string",
      "enum": [
        "tcp",
        "udp",
        "sctp",
        "dccp"
      ]
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of keyword matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_media_type

open-world

Look up registered media (MIME) types. Pass exactly one of `type` (a full name such as "application/json"; parameters after ";" are ignored) or `keyword` (words matched against registered type names and status annotations, e.g. "geo json"; never against file extensions). An exact `type` lookup also reads the registration template and returns its file-extension, intended-usage, and deprecated-alias statements as written, each only when the template has it. Some registered types have no registration template (`template.available: false`); their references are the defining documents. Deprecated and obsoleted types are reported with their replacement when the registry names one. Unregistered "x-" types are not in the registry.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_media_type",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "type": {
      "description": "Full media type, case-insensitive, e.g. \"application/json\" (\"; charset=utf-8\" and other parameters are dropped). Pass this or keyword, not both.",
      "type": "string",
      "pattern": "^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$"
    },
    "keyword": {
      "description": "Words matched as whole tokens against registered type names and status annotations, e.g. \"geo json\". File extensions are not searched: look up the expected type with type to read its template's file-extension statement, when the template has one. Pass this or type, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "top_level": {
      "description": "Keep only types under this top-level type, e.g. \"image\". Keyword mode only.",
      "type": "string",
      "enum": [
        "application",
        "audio",
        "example",
        "font",
        "haptics",
        "image",
        "message",
        "model",
        "multipart",
        "text",
        "video"
      ]
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of keyword matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_http_status

open-world

Look up an HTTP status code in the IANA registry, or search reason phrases. Pass exactly one of `code` (100–599) or `keyword` (e.g. "too many"). Returns the registered phrase, its class, defining reference with section, and whether it is temporary, obsoleted, or unused; an unassigned code returns found: false with the unassigned range it falls in.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_http_status",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "code": {
      "description": "Status code to look up, 100–599 (a digit string such as \"429\" also works). Pass this or keyword, not both.",
      "type": "integer",
      "minimum": 100,
      "maximum": 599
    },
    "keyword": {
      "description": "Words matched as whole tokens against registered reason phrases, e.g. \"too many\" or \"gateway\". Pass this or code, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of keyword matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_http_field

open-world

Look up a registered HTTP field (header or trailer) name. Pass exactly one of `name` (case-insensitive, e.g. "Cache-Status") or `keyword` (words matched against field names and comments). Returns the registration status — permanent, provisional, deprecated, or obsoleted — the Structured Field type when registered, and the defining reference. Many widely used headers are unregistered; a miss means only that IANA has no entry.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_http_field",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "description": "Exact field name, case-insensitive, e.g. \"Content-Type\" (a trailing \":\" is ignored). Pass this or keyword, not both.",
      "type": "string",
      "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,100}$"
    },
    "keyword": {
      "description": "Words matched as whole tokens against field names and registry comments, e.g. \"cache\". Pass this or name, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "status": {
      "description": "Keep only fields with this registration status. Applies to both modes.",
      "type": "string",
      "enum": [
        "permanent",
        "provisional",
        "deprecated",
        "obsoleted"
      ]
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of keyword matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_uri_scheme

open-world

Look up a registered URI scheme. Pass exactly one of `scheme` (e.g. "mailto"; a trailing ":" or "://" is ignored) or `keyword` (words matched against scheme names and descriptions). Returns the status — permanent, provisional, or historical — description, references, and well-known URI support.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_uri_scheme",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "scheme": {
      "description": "Exact scheme name, case-insensitive, e.g. \"https\" (a trailing \":\" or \"://\" is ignored). Pass this or keyword, not both.",
      "type": "string",
      "pattern": "^[a-z][a-z0-9+.-]{0,63}$"
    },
    "keyword": {
      "description": "Words matched as whole tokens against scheme names and descriptions, e.g. \"websocket\". Pass this or scheme, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "status": {
      "description": "Keep only schemes with this registration status. Applies to both modes.",
      "type": "string",
      "enum": [
        "permanent",
        "provisional",
        "historical"
      ]
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of keyword matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_pen

open-world

Look up a Private Enterprise Number (PEN). Pass exactly one of `pen` (a number such as 32473, or an OID under 1.3.6.1.4.1 such as 1.3.6.1.4.1.32473.1.2) or `organization` (words matched against organization names). Returns the organization and its OID prefix. Arcs below the enterprise number are assigned by the enterprise, not IANA. Contact details are not returned.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_pen",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "pen": {
      "description": "Enterprise number, e.g. \"32473\", or an OID under 1.3.6.1.4.1 naming it, e.g. \"1.3.6.1.4.1.32473.1.2\" (a leading dot and the iso.org.dod.internet.private.enterprise prefix are accepted). Pass this or organization, not both.",
      "type": "string",
      "pattern": "^(?:\\d{1,9}|1\\.3\\.6\\.1\\.4\\.1\\.\\d{1,9}(?:\\.\\d{1,10}){0,64})$"
    },
    "organization": {
      "description": "Words matched as whole tokens against the names of assigned entries, e.g. \"cisco systems\"; look up a number with pen to see a reserved or unassigned one. Pass this or pen, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of organization matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_lookup_language_tag

open-world

Parse and validate a BCP 47 language tag against the IANA Language Subtag Registry, or search subtags by description. Pass exactly one of `tag` (e.g. "zh-Hant-TW", "sr-Latn", "en_US") or `description` (e.g. "Swiss German"). A tag is split into language, extlang, script, region, variant, extension, and private-use parts; each part is checked, deprecated subtags report their preferred value, and a canonical tag is returned when the tag is valid. A single subtag registered under several types (e.g. "TW") lists the other types.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_lookup_language_tag",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "tag": {
      "description": "A language tag to validate, e.g. \"zh-Hant-TW\", \"sr-Latn\", \"i-klingon\". Underscores are read as hyphens (\"en_US\" → \"en-US\"); matching ignores case. Pass this or description, not both.",
      "type": "string",
      "maxLength": 100,
      "pattern": "^[A-Za-z0-9]{1,8}(?:-[A-Za-z0-9]{1,8})*$"
    },
    "description": {
      "description": "Words matched as whole tokens against subtag descriptions, e.g. \"Swiss German\" or \"Cyrillic\". Pass this or tag, not both.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "subtag_type": {
      "description": "Description mode only: return only records of this Type.",
      "type": "string",
      "enum": [
        "language",
        "extlang",
        "script",
        "region",
        "variant",
        "grandfathered",
        "redundant"
      ]
    },
    "limit": {
      "description": "Maximum number of description matches to return, 1–100. Default 25. Tag mode always returns every part of the tag.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "description": "Number of description matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_get_rfc_status

open-world

Get the current status of up to 10 RFCs, Internet-Drafts, or BCP/STD/FYI series in one call. Accepts "RFC 9110", "rfc9110", "9110", draft names with or without a revision suffix ("draft-ietf-httpbis-semantics-19"), series numbers ("BCP 14"), RFC and draft file names ("rfc9110.txt"), the URL of an RFC or draft on datatracker.ietf.org, tools.ietf.org, or ietf.org or of an RFC on rfc-editor.org, and a series URL at rfc-editor.org/info/ or datatracker.ietf.org/doc/ ("https://datatracker.ietf.org/doc/bcp14/"). RFCs return current and as-published status, stream, working group, obsoletes/obsoleted-by and updates/updated-by relations, the series they belong to, and the errata page; drafts return their state, IESG state, intended status, expiry, the document that replaced them, and the RFC they became; a series returns its member RFCs. Unknown ids return found: false. A call makes at most 20 Datatracker requests, retries included (an RFC or a series needs one, plus one per call for the RFCs' series; a draft three, or four with a revision suffix): each id is taken in request order if its requests still fit, and the others come back in failed with reason request_limit, to pass in another call.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_get_rfc_status",
    "arguments": {
      "ids": "<ids>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "ids": {
      "description": "Up to 10 RFCs, Internet-Drafts, or series, e.g. [\"RFC 9110\", \"BCP 14\", \"draft-ietf-httpbis-semantics-19\"]. One comma-, semicolon-, or newline-separated string is also accepted.",
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200,
        "description": "One RFC number (\"RFC 9110\", \"9110\"), draft name, series number (\"BCP 14\"), RFC or draft file name, or a URL of a form the tool description lists. A URL's query and fragment are dropped before this 200-character limit applies."
      }
    }
  },
  "required": [
    "ids"
  ],
  "additionalProperties": false
}
view source ↗

iana_search_registries

open-world

Find IANA protocol registries and sub-registries by keyword over their titles and protocol categories, e.g. "tls cipher", "dns resource record", "protocol numbers". Returns the registry and sub-registry ids that iana_get_registry_records reads, with registration procedure and defining documents. Covers every registry linked from the IANA protocol registries index.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_search_registries",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "description": "Words matched as whole tokens, singular or plural, against registry titles, categories, and ids, e.g. \"tls cipher\". An exact registry or sub-registry id ranks first, then the closest titles.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "limit": {
      "description": "Maximum number of results to return, 1–50. Default 15.",
      "default": 15,
      "type": "integer",
      "minimum": 1,
      "maximum": 50
    },
    "offset": {
      "description": "Number of matches to skip; pass the next_offset of the previous response to get the next page. Default 0.",
      "default": 0,
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "query",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

iana_get_registry_records

open-world

Read records from any IANA XML registry by id, e.g. registry "tls-parameters" with subregistry "tls-parameters-4" (TLS Cipher Suites), "protocol-numbers", "http-methods", or "cbor-tags"; an iana.org/assignments URL also works. Filter with `value` (exact match on the key column, or on the column `field` names; digits compare by number with a cell of digits ("0443" finds "443") and one 0x token with a one-token 0x cell ("0x5" finds "0x05"), each also matching its own kind of range row ("105-199", "0x11-0xff"); other 0x forms compare their digits as written, in any comma, space, or brace spelling) and `contains` (words in any field; records with a field equal to the words come first). When a registry has several sub-registries and none is given, the response lists them instead of records; a table that nests tables lists them too. Field names are the registry's XML element names (e.g. "rec" is the Recommended column). Large registries page through `cursor`. Find ids with iana_search_registries.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "iana_get_registry_records",
    "arguments": {
      "registry": "<registry>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "registry": {
      "description": "Registry id, e.g. \"tls-parameters\", or its https://www.iana.org/assignments/<id> URL (a #fragment selects the sub-registry when subregistry is unset).",
      "type": "string",
      "maxLength": 200,
      "pattern": "^(?:[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}|https?:\\/\\/(?:www\\.)?iana\\.org\\/assignments\\/[A-Za-z0-9_][A-Za-z0-9_.-]{0,63}(?:\\/[^\\s#]*)?(?:#[A-Za-z0-9_][A-Za-z0-9_.-]{0,99})?)$"
    },
    "subregistry": {
      "description": "Sub-registry id, case-insensitive, e.g. \"tls-parameters-4\". Omit to read the only sub-registry, or to list them when there are several.",
      "type": "string",
      "pattern": "^[A-Za-z0-9_][A-Za-z0-9_.-]{0,99}$"
    },
    "value": {
      "description": "Exact match on the key column named by value_field (value, else number, else the first column), or on field when set; case and whitespace are ignored. A value of digits compares by number with a cell of digits, so \"0443\" finds \"443\", and also matches range rows such as \"105-199\"; it never matches a 0x cell. One 0x token compares by number with a one-token 0x cell, so \"0x5\" finds \"0x05\", and also matches range rows such as \"0x11-0xff\". Any other pair of 0x forms compares the digits as written: \"0x1301\", \"{0x13,0x01}\", and \"0x13 0x01\" all find \"0x13,0x01\", while \"0x13\" never finds \"0x00,0x13\".",
      "type": "string",
      "maxLength": 100
    },
    "field": {
      "description": "Column for value to match instead of the key column, case-insensitive, one of the names in columns: e.g. \"type\" for a DNS RR type mnemonic, or \"name\" for every row of a service name. Ignored without value.",
      "type": "string",
      "maxLength": 100
    },
    "contains": {
      "description": "Words matched as whole tokens against every field and reference id, e.g. \"chacha20\". Records with a field equal to the words come first.",
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "limit": {
      "description": "Maximum number of results to return, 1–100. Default 25.",
      "default": 25,
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "cursor": {
      "description": "next_cursor from the previous page; reuse it only with the same registry, subregistry, value, field, and contains.",
      "type": "string",
      "maxLength": 1000
    }
  },
  "required": [
    "registry",
    "limit"
  ],
  "additionalProperties": false
}
view source ↗