base64 MCP tool: encode and decode Base64 from an AI agent
· 6 min read
Get the devtoolbox.cc MCP serverOpen the Base64 tool
Base64 is a mechanical transformation, and language models are surprisingly bad at it. Short ASCII strings usually come out right, because those examples are everywhere in training data. Longer strings drift: a character changes in the middle, padding goes missing, or a decoded word is “corrected” to something more likely. Non-ASCII text is worse, because Base64 works on UTF-8 bytes, and the model is reasoning about characters. And binary data such as an image or a certificate can’t be handled in the conversation at all.
The devtoolbox.cc MCP server includes base64, so an assistant can do the conversion exactly and work with files directly. It uses the same code as the Base64 encoder and decoder on this site. Setup is described on the MCP page.
What the tool does
- Encode text (as UTF-8) or any file’s bytes to Base64.
- Use the standard alphabet with
+and/, or the URL-safe alphabet with-and_and no padding, as used in JWTs and URLs. - Decode Base64 in either alphabet, with or without padding, ignoring line breaks and spaces.
- Return decoded data as text when it’s valid UTF-8, or write it to a file when it’s binary.
Invalid input is reported with a reason, not decoded into garbage.
Arguments
| Argument | Type | Meaning |
|---|---|---|
mode |
"encode" or "decode" |
Required. |
text |
string | Text to encode, or Base64 to decode. Use this or path. |
path |
string | A local file: its bytes to encode, or Base64 text to decode. |
url_safe |
boolean | Encode with the URL-safe alphabet and no padding. |
output_path |
string | Write the result to a file. Required for binary decode results. |
overwrite |
boolean | Allow output_path to replace an existing file. Default false. |
Examples
These examples were run against the real tool. Non-ASCII text is encoded from its UTF-8 bytes, which is where hand-made Base64 usually goes wrong:
{ "mode": "encode", "text": "Привет 👋" }
0J/RgNC40LLQtdGCIPCfkYs=
The URL-safe variant of a string whose standard encoding contains / and =:
{ "mode": "encode", "text": "subjects?_d", "url_safe": true }
c3ViamVjdHM_X2Q
In the standard alphabet the same bytes encode to c3ViamVjdHM/X2Q=. Decoding accepts both alphabets and missing padding:
{ "mode": "decode", "text": "c3ViamVjdHM_X2Q" }
subjects?_d
A Basic authentication header is Base64 of user:password, which is why the header protects nothing without HTTPS:
{ "mode": "decode", "text": "YWxpY2U6czNjcjN0LXRlc3Q=" }
alice:s3cr3t-test
Files are read as bytes. This one is a small text file, but a PDF or a ZIP works the same way:
Internal test CA, rotate before 2027.
{ "mode": "encode", "path": "/home/dev/certs/ca-note.txt" }
SW50ZXJuYWwgdGVzdCBDQSwgcm90YXRlIGJlZm9yZSAyMDI3Lgo=
When the decoded bytes aren’t text, the tool doesn’t print mojibake into the conversation. It asks for a file instead. This is the start of a PNG file:
{ "mode": "decode", "text": "iVBORw0KGgoAAAANSUhEUg==" }
The decoded 16 B are not UTF-8 text; pass "output_path" to save them as a file.
{ "mode": "decode", "text": "iVBORw0KGgoAAAANSUhEUg==", "output_path": "/home/dev/tmp/header.bin" }
Wrote 16 bytes to /home/dev/tmp/header.bin
And input that isn’t Base64 fails with a reason:
{ "mode": "decode", "text": "not base64!" }
Invalid Base64: Invalid Base64 character: "!"
Standard, URL-safe and padding
Base64 turns every 3 bytes into 4 characters from a 64-character alphabet, which is why encoded data is about a third larger. The standard alphabet from RFC 4648 uses A–Z, a–z, 0–9, + and /, and pads the output with = to a multiple of four characters. Both + and / mean something in URLs and file names, so the same RFC defines a URL-safe alphabet that uses - and _ instead. JWTs use the URL-safe alphabet without padding, which is why a JWT never contains +, / or =.
The difference shows up with bytes whose encoding lands on the last two characters of the alphabet:
{ "mode": "encode", "text": ">>>???" }
Pj4+Pz8/
{ "mode": "encode", "text": ">>>???", "url_safe": true }
Pj4-Pz8_
Padding carries no information, since a decoder can work out from the length how many bytes the last group holds. That’s why the tool decodes with or without it. Line breaks are ignored as well, so Base64 wrapped at 64 or 76 characters, as in PEM files and email, decodes as one block.
Where Base64 turns up
Most Base64 a developer meets comes from a handful of places, and the tool decodes all of them the same way:
- Data URIs in CSS and HTML:
data:image/png;base64,…. - JWT segments, in the URL-safe alphabet without padding.
- HTTP Basic authentication:
Authorization: Basicfollowed by Base64 ofuser:password. - Email attachments, where MIME wraps Base64 lines at 76 characters.
- Kubernetes Secrets, whose values under
data:are Base64-encoded, not encrypted. - Certificates and keys in PEM files, between the
-----BEGINand-----ENDlines.
For the last two, decoding with output_path is the right call: the content is binary or sensitive, and neither belongs in a chat transcript.
Things to ask your assistant
- “Decode the
Authorizationheader inrequest.logand tell me which user it is.” - “Base64-encode
service-account.jsonfor theGOOGLE_CREDENTIALSsecret.” - “The
datafield inwebhook.jsonis Base64. Decode it and save it asattachment.pdf.” - “Encode
logo.svgso I can inline it.”
For images in particular, the image_base64 tool goes further: it checks the image type from the bytes and produces a ready-made data URI. In the browser, the same is available as the Image to Base64 converter, and plain text or files can be converted with the Base64 tool.
Base64 is not encryption
Anyone can decode Base64. It exists to carry bytes through channels that only accept text, such as JSON, email or environment variables, and it makes data a third larger in the process. When a secret is stored “encrypted” as Base64 in a config file, it’s stored in plain text. Agents should treat decoded values with the same care as the original secret. If a value has to stay secret at rest, encrypt it or keep it in a secret manager, and treat its Base64 form as the secret itself.
Install
base64 is part of the devtoolbox.cc MCP server, which runs locally with no network access. The files and secrets it decodes stay on your machine. Setup for Claude Desktop, Claude Code, Cursor and VS Code is on the MCP install page.