Skip to content
devtoolbox.cc

url MCP tool: encode, decode and parse URLs from an AI agent

· 6 min read

Get the devtoolbox.cc MCP serverOpen the URL Encode tool

URL encoding has just enough rules to go wrong in generated code. A space can be %20 or + depending on where it appears. encodeURI and encodeURIComponent disagree about &, = and /. Non-ASCII characters become one %XX per UTF-8 byte, so é is two escapes and an emoji is four. A model writing a redirect URL or decoding a tracking link from memory usually gets the common case right and one of these details wrong.

The devtoolbox.cc MCP server includes url, a tool that encodes, decodes and parses URLs with the platform’s own URL implementation. It’s the logic behind two tools on this site, the URL encoder and decoder and the URL parser. Installation is on the MCP page.

What the tool does

The mode argument picks one of three jobs.

encode percent-encodes text. Three encodings are available:

encoding Behaves like Use it for
component encodeURIComponent (default) One query value or path segment
rfc3986 encodeURIComponent, plus !'()* APIs and OAuth signatures that follow RFC 3986 strictly
uri encodeURI A whole URL, keeping :/?#&= as they are

decode reverses percent-encoding and reports malformed sequences such as a lone % or invalid UTF-8 instead of guessing.

parse splits an absolute URL into protocol, credentials, host, port, path, fragment and the list of query parameters, each decoded, with repeated names kept in order.

With spaces_as_plus, encoding and decoding follow HTML form rules (application/x-www-form-urlencoded): a space is +, and a literal plus is %2B. With per_line, each line is handled separately, which is handy for a list of values.

Arguments

Argument Type Meaning
mode "encode", "decode" or "parse" Required.
text string The text, encoded string or URL. Required.
encoding "component", "rfc3986", "uri" For encode. Default "component".
spaces_as_plus boolean Form encoding: space ↔ +, plus ↔ %2B.
per_line boolean Encode or decode each line on its own.

Examples

These examples were run against the real tool. A query value with reserved characters and non-ASCII text:

{ "mode": "encode", "text": "price < 10 & café/bar" }
price%20%3C%2010%20%26%20caf%C3%A9%2Fbar

A whole URL keeps its structure with uri, and only the unsafe parts are escaped:

{ "mode": "encode", "text": "https://example.com/search?q=café au lait&page=2", "encoding": "uri" }
https://example.com/search?q=caf%C3%A9%20au%20lait&page=2

Form encoding, where a literal plus has to stay distinguishable from a space:

{ "mode": "encode", "text": "C++ & C#", "spaces_as_plus": true }
C%2B%2B+%26+C%23
{ "mode": "decode", "text": "C%2B%2B+%26+C%23", "spaces_as_plus": true }
C++ & C#

Without spaces_as_plus, a + is decoded as a plus sign, which is correct for paths and for APIs that don’t use form encoding. Decoding errors say where the problem is:

{ "mode": "decode", "text": "100%25 done, 50% left" }
Malformed percent-encoding at position 16

Parsing a URL with credentials, a port, a repeated parameter and an empty one:

{
  "mode": "parse",
  "text": "https://ci:token@builds.example.com:8443/api/v2/runs?branch=main&tag=a&tag=b&debug=#latest"
}
{
  "href": "https://ci:token@builds.example.com:8443/api/v2/runs?branch=main&tag=a&tag=b&debug=#latest",
  "protocol": "https:",
  "username": "ci",
  "password": "token",
  "hostname": "builds.example.com",
  "port": "8443",
  "pathname": "/api/v2/runs",
  "hash": "#latest",
  "params": [
    [
      "branch",
      "main"
    ],
    [
      "tag",
      "a"
    ],
    [
      "tag",
      "b"
    ],
    [
      "debug",
      ""
    ]
  ]
}

The query parameters come back as a list of pairs, not an object, so tag=a&tag=b keeps both values and debug with an empty value isn’t lost.

A URL inside a URL

Redirect and callback parameters carry a whole URL as one query value. That value must be encoded with component, so that its own ?, & and = don’t merge with the outer URL’s:

{ "mode": "encode", "text": "https://app.example.com/cb?state=xyz&next=/home" }
https%3A%2F%2Fapp.example.com%2Fcb%3Fstate%3Dxyz%26next%3D%2Fhome

With uri encoding, the reserved characters stay as they are:

{ "mode": "encode", "text": "https://app.example.com/cb?state=xyz&next=/home", "encoding": "uri" }
https://app.example.com/cb?state=xyz&next=/home

Put that second form after ?redirect= and the server sees redirect=https://app.example.com/cb?state=xyz and a separate next parameter. It’s a classic source of broken OAuth flows.

Double encoding

Logs and proxies sometimes encode a value twice. A space becomes %20, and then the % itself becomes %25, so the log shows %2520. Decoding once gives the intermediate form:

{ "mode": "decode", "text": "report%2520final.pdf" }
report%20final.pdf

A second decode gives report final.pdf. If a value still contains %25 after one decode, it was encoded twice somewhere along the way, which usually points at a client or proxy that encodes an already encoded URL.

Things to ask your assistant

  • “Decode the redirect_uri parameter in this OAuth URL and tell me where it sends the user.”
  • “Build the search URL for ‘Zürich Hauptbahnhof’ with the right encoding for the q parameter.”
  • “Parse every URL in access.log lines 1–50 and list the distinct values of the utm_source parameter.”
  • “Encode each line of keywords.txt as a query value.”

For working on one URL by hand, the URL parser shows the parts and lets you edit query parameters in a table, and the URL encoder converts both ways as you type.

Why exact encoding matters

An encoding mistake is rarely visible. a+b in a query string arrives at the server as “a b” if the client meant a literal plus. A redirect URL encoded with encodeURI instead of encodeURIComponent leaks its own & parameters into the outer URL. An OAuth signature computed over a string encoded slightly differently from the server’s version simply fails, with no hint why. These are exactly the details a tool gets right every time, and the reason the agent should call one instead of retyping escapes.

The URL encoding article covers the rules in more depth.

Install

url is part of the devtoolbox.cc MCP server. It runs locally and doesn’t make network requests; parsing a URL never fetches it. Setup for Claude Desktop, Claude Code, Cursor and VS Code is on the MCP install page.

← All posts