Overview
aktar is a remote control for the Aktar app on the same computer. You hand it files, it passes them to Aktar on 127.0.0.1, and Aktar uploads them with the destinations, keys, path templates and link settings you already set up. The link comes back to your terminal.
What it is
- A small Node.js command for scripts, CI jobs on your own Mac or Windows machine, and editors like Typora
- A way to upload files and the clipboard, show QR codes, and read your destinations and upload history
- Free and open source (MIT), like the app
What it isn't
- Not standalone: without Aktar running, it can't upload anything. It never holds your storage keys
- Not for Linux servers or remote machines: it only talks to Aktar on the same computer. There, use your storage provider's own CLI
Requirements
- Aktar for Mac 0.18.0 or Aktar for Windows 0.11.0 or later, with at least one destination. aktar 0.5.0 and earlier work with Aktar for Mac 0.4.0 or later
- Node.js 18 or later (Homebrew installs it for you)
-
--name,--qrandaktar qrneed aktar 0.2.0 or later - Reusing the link of a file that's already uploaded needs aktar 0.2.0 and Aktar for Mac 0.10.0 or Aktar for Windows 0.3.0
-
aktar replaceneeds aktar 0.3.0 and Aktar for Mac 0.14.0 or Aktar for Windows 0.7.0 or later -
--short,--no-shortandaktar shortneed aktar 0.5.0 and Aktar for Mac 0.17.0 or Aktar for Windows 0.10.0, with a link shortener set up on the destination
Install
Install it once, with npm or Homebrew. Both put the aktar command on your path.
With npm (macOS and Windows)
npm install -g @getaktar/cliWith Homebrew (macOS)
brew install getaktar/tap/aktar-cliOr run it once without installing anything:
npx @getaktar/cli upload file.pngCheck which version you have:
aktar --version
0.6.0Connect to Aktar
- In Aktar for Mac or Windows, open Settings > Integrations and turn on Allow local connections. Aktar then listens on
127.0.0.1only, port 47913 unless you change it there. - Copy the token shown under it.
- Run
aktar loginand paste the token at theToken:prompt. It stays hidden while you type, and it's checked against Aktar before it's saved, so a typo isn't stored.
aktar login
Copy the token from Aktar: Settings > Integrations (turn on Allow local connections first).
Token:
Connected to Aktar 0.10.0. Saved to /Users/you/.config/aktar/cli.jsonWhere the token is kept
aktar login saves the token and port in ~/.config/aktar/cli.json on a Mac (or $XDG_CONFIG_HOME/aktar/cli.json if you set it) and in %APPDATA%\aktar\cli.json on Windows. Only your user can read it.
Before sending the token, aktar asks the app on the port to prove it has the same token, without sending it. So if Aktar isn't running and another program is listening on its port, that program gets neither the token nor your files. This needs Aktar for Mac 0.18.0 or Aktar for Windows 0.11.0 or later; with an older Aktar, aktar stops and asks you to update.
{
"token": "…",
"port": 47913
}aktar logout deletes that file. To lock out every client at once, click Regenerate next to the token in Aktar; then run aktar login again with the new one.
Scripts and CI
On a build machine, skip aktar login and set AKTAR_TOKEN (and AKTAR_PORT if you changed the port). They win over the saved file. Aktar has to be running on that machine, signed in to the same user session.
AKTAR_TOKEN="$AKTAR_SECRET" aktar upload dist/app.zip -d Builds| Variable | What it does |
|---|---|
AKTAR_TOKEN | The token from Aktar's Settings > Integrations. Used instead of the saved one. |
AKTAR_PORT | Aktar's local API port, if you changed it. --port wins over it. |
NO_COLOR | Draws QR codes with plain characters instead of terminal colors. |
XDG_CONFIG_HOME | Where the config folder is on macOS (default ~/.config). On Windows, %APPDATA% is used. |
Commands
All commands talk to Aktar, except aktar qr with plain text or a link. Without -d, uploads go to the destination selected in Aktar's menu bar, and they show up in Aktar's history like any other. aktar --help prints the same list. With Aktar for Mac 0.14.0 or Aktar for Windows 0.7.0 or later, an upload without -d follows the destinations' Use For rules first, so an image can go to your screenshots destination and a build to another.
aktar uploadaktar upload --clipboardaktar replaceaktar shortaktar qraktar loginaktar logoutaktar statusaktar destinationsaktar historyaktar mcpaktar skill
aktar upload
Uploads one or more files and prints one link per file, in order, as each one finishes.
Usage
aktar upload <file>... [options]Options
| Flag | Value | Description |
|---|---|---|
-d, --destination | <name|id> | Destination to upload to, by name or ID. Default: the one selected in Aktar. |
-f, --format | <format> | What to print: url (default), markdown, html or custom (your template in Aktar). |
--name | <name> | Upload one file under this name. Its extension is kept if the name has none. |
--folder | <path> | Keep the file name and upload into this folder. |
--expires | <days> | Let the bucket delete the file after 1, 7, 14 or 30 days. 0 keeps it. |
--short | Make a short link with the destination's link shortener, even if its rules would skip this upload. | |
--no-short | Don't make a short link this time. | |
--qr | Also print a QR code of each link. | |
--json | Print a JSON array with the full details of each upload, instead of links. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Every file is checked before anything is uploaded: if one doesn't exist, nothing is uploaded and
aktarexits with code 2. - If one upload fails, the others still go through. Each failure is reported on stderr, and the exit code is 1.
- Without
--folder, the destination's path template names the file, just like a drop on the menu bar. With--folder, the file keeps its name inside that folder. --nameworks with one file at a time. Slashes are removed, and the file's extension is added if the name has none:--name coveruploadsIMG_4021.jpgascover.jpg. With--folder, it's the name inside the folder.--expirestakes 1, 7, 14 or 30 (days), or 0 to keep the file. Without it, the file is kept, whatever Delete after is set to in Aktar. It needs Aktar's auto-delete rules on that destination, and it can't be combined with--folder.--qrcan't be combined with--json, and--pngonly works withaktar qr.- In a terminal, progress is shown on stderr while a file uploads. The file is streamed to Aktar, so its size doesn't matter, and there's no time limit.
- If the destination has a link shortener set up in Aktar, the short link is printed, and
--formatand--qruse it.--shortmakes one even if the destination's rules would skip this upload,--no-shortmakes none. If Aktar can't make it, the original link is printed and stderr says why.
Examples
aktar upload screenshot.png
https://files.example.com/2026/10/7f3c2a91.pngaktar upload *.png -f markdown

aktar upload IMG_4021.jpg --name cover --folder blog/2026
https://files.example.com/blog/2026/cover.jpgaktar upload photo.jpg
aktar: photo.jpg: already uploaded, reused the existing link
https://files.example.com/2026/09/4d2a8c61.jpgaktar upload talk.pdf --short
https://s.example.com/k3Tq9aktar upload --clipboard
Uploads the file or image that's on the clipboard, like Aktar's own clipboard shortcut.
Usage
aktar upload --clipboard [options]Options
| Flag | Value | Description |
|---|---|---|
--clipboard | Upload what's on the clipboard instead of files. | |
-d, --destination | <name|id> | Destination to upload to, by name or ID. Default: the one selected in Aktar. |
-f, --format | <format> | What to print: url (default), markdown, html or custom (your template in Aktar). |
--expires | <days> | Let the bucket delete the file after 1, 7, 14 or 30 days. 0 keeps it. |
--short | Make a short link with the destination's link shortener, even if its rules would skip this upload. | |
--no-short | Don't make a short link this time. | |
--qr | Also print a QR code of each link. | |
--json | Print a JSON array with the full details of each upload, instead of links. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Pass files or
--clipboard, not both. --nameand--folderonly work with files.-d,-f,--expires,--qrand--jsonwork as with files.- With
--json, it still prints an array, with one entry.
Examples
aktar upload --clipboard
https://files.example.com/2026/10/9a4c03be.pngaktar upload --clipboard -f markdown -d Blog
aktar upload --clipboard --expires 1
https://files.example.com/tmp/1d/2026/10/38f0d7c2.pngaktar replace
Writes a new file over an upload, so its key and link stay the same. Everyone with the link sees the new file.
Usage
aktar replace <upload-id|link|key> <file> [options]Options
| Flag | Value | Description |
|---|---|---|
-d, --destination | <name|id> | For a key: the destination whose bucket it's in, by name or ID. Default: the one selected in Aktar. |
-f, --format | <format> | What to print: url (default), markdown, html or custom (your template in Aktar). |
--qr | Also print a QR code of each link. | |
--json | Print a JSON array with the full details of each upload, instead of links. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- The first argument is an upload ID or a link from
aktar history(Aktar's history entry is updated), or otherwise a key in the bucket of-d(the destination selected in Aktar when it's left out). A link that isn't in Aktar's history is refused: pass its key with-dinstead. - Aktar removes the file's metadata and resizes it as the destination says, but never converts it to another format, so the key's extension stays. A file under
tmp/{N}d/starts its N days again. - The key is never numbered and nothing else is uploaded.
--folder,--expires,--nameand--clipboarddon't apply and are refused. - Old copies can stay in a CDN's cache for a while. A destination's Short cache time or Cloudflare cache purge in Aktar takes care of that.
- Needs Aktar for Mac 0.14.0 or Aktar for Windows 0.7.0 or later.
Examples
aktar replace 0B6C2F8E-3D1A-4C55-9E2B-7A41D0C3E9F1 report-v2.pdf
https://files.example.com/2026/09/0e7d51b3.pdfaktar replace docs/guide.pdf guide.pdf -d Blog -f markdown
[guide.pdf](https://blog-assets.example.com/docs/guide.pdf)aktar short
Makes a short link for an upload in history with its destination's link shortener, and prints it. If the upload already has one, that's the one printed.
Usage
aktar short <upload-id|link> [--json | --qr]Options
| Flag | Value | Description |
|---|---|---|
--json | Print the short link's details as JSON: provider, status and clicks. | |
--qr | Also print the short link's QR code. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Pass an upload ID or a link from
aktar history; its short link works too.aktarlooks it up in the last 1,000 uploads. - The destination needs a link shortener in Aktar's Short Links section: Shlink, YOURLS, Kutt, Dub, Short.io or a custom request. The short link comes from that shortener, so your links and click data stay in your infrastructure.
--jsonprints the short link's details: provider, status, and clicks and last click when the shortener counts them.--qradds its QR code. The two can't be combined.- Needs Aktar for Mac 0.17.0 or Aktar for Windows 0.10.0. Older versions answer that they don't make short links yet.
Examples
aktar short 0B6C2F8E-3D1A-4C55-9E2B-7A41D0C3E9F1
https://s.example.com/Qm3xZaktar qr
Shows a QR code of a link or any text in the terminal, so you can open it on a phone. Given an upload ID, it shows that upload's link and its QR code.
Usage
aktar qr <link|text|upload-id> [--png <file>]Options
| Flag | Value | Description |
|---|---|---|
--png | <file> | Save the QR code as a PNG file instead of printing it. |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Pass exactly one argument, and quote text with spaces.
- An upload ID is the
idfromaktar history --jsonoraktar upload --json.aktarlooks it up in the last 1,000 uploads in Aktar's history; for plain text or a link, it doesn't need Aktar at all. - The code is drawn black on white in a terminal, whatever its theme. When the output isn't a terminal, or
NO_COLORis set, it's drawn without colors. --pngsaves the QR code as a PNG instead of printing it.- For an upload with a short link, it shows the short link.
Examples
aktar qr https://files.example.com/2026/10/demo.mp4aktar qr 0B6C2F8E-3D1A-4C55-9E2B-7A41D0C3E9F1 --png cover-qr.png
Saved to cover-qr.pngaktar login
Checks a token against Aktar and saves it, so the other commands can connect.
Usage
aktar login [--token <token>] [--port <port>]Options
| Flag | Value | Description |
|---|---|---|
--token | <token> | The token, instead of the prompt. |
--port | <port> | Aktar's port, saved along with the token. Default 47913. |
Good to know
- In a terminal, it asks for the token and hides what you type. When the input is piped, it reads the token from there.
--tokenskips the prompt, but other programs can see the token while the command runs, and it ends up in your shell history, soaktarwarns about it. Piping it in orAKTAR_TOKENavoids that.- A token Aktar rejects isn't saved, and the exit code is 3.
Examples
aktar login
Copy the token from Aktar: Settings > Integrations (turn on Allow local connections first).
Token:
Connected to Aktar 0.10.0. Saved to /Users/you/.config/aktar/cli.jsonpbpaste | aktar login
Connected to Aktar 0.10.0. Saved to /Users/you/.config/aktar/cli.jsonaktar warns that the token was visible.aktar login --token "$AKTAR_SECRET" --port 47920
aktar: warning: a token on the command line can be seen by other programs (ps) and stays in your shell history. Next time, run aktar login without --token and paste it, or pipe it in.
Connected to Aktar 0.10.0. Saved to /Users/you/.config/aktar/cli.jsonaktar logout
Deletes the saved token and port.
Usage
aktar logoutOptions
No options.
Good to know
AKTAR_TOKEN, if set, still works afteraktar logout.- It doesn't disconnect other clients. For that, regenerate the token in Aktar.
Examples
aktar logout
Logged out.aktar status
aktar: Not connected to Aktar yet. Run aktar login with the token from Aktar's Settings > Integrations.aktar status
Shows which Aktar you're connected to, on which port, the destination selected in Aktar, and where the config file is.
Usage
aktar status [--json]Options
| Flag | Value | Description |
|---|---|---|
--json | Print JSON instead of text. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- A quick way to check the connection in a script: it exits with code 3 when Aktar can't be reached or the token is wrong.
Examples
aktar status
Aktar 0.10.0 (build 28) on port 47913
Destination: Screenshots (Cloudflare R2, screenshots)
Config: /Users/you/.config/aktar/cli.jsonaktar status --json
{
"app": "Aktar",
"version": "0.10.0",
"build": "28",
"apiVersion": 1,
"defaultDestinationId": "5D1A9C3E-7B2F-4E61-8A0D-3C9B6F2E1A47",
"outputFormat": "url",
"port": 47913
}aktar destinations
Lists your destinations with their provider, bucket and ID. * marks the one selected in Aktar.
Usage
aktar destinations [--json]Options
| Flag | Value | Description |
|---|---|---|
--json | Print JSON instead of text. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Use a name or an ID with
-d. Names are matched without regard to case; an ID always works, even after a rename. --jsongivesid,name,provider,providerName,bucket,publicBaseURLandisDefaultfor each.
Examples
aktar destinations
* Screenshots Cloudflare R2 screenshots 5D1A9C3E-7B2F-4E61-8A0D-3C9B6F2E1A47
Builds Amazon S3 acme-builds A83F2C10-6D4B-4F7E-9C1A-2B5E8D0F3C66
Blog Backblaze B2 blog-assets E2C7B9A4-1F3D-4A8E-B6C0-9D5F2A7E4B13aktar destinations --json | jq -r '.[] | select(.isDefault) | .name'
Screenshotsaktar history
Lists recent uploads, newest first: date, file name and link. Words after history search the history.
Usage
aktar history [search] [options]Options
| Flag | Value | Description |
|---|---|---|
-n, --limit | <n> | How many uploads to list. Default 20. |
-d, --destination | <name|id> | Only uploads to this destination, by name or ID. |
--json | Print JSON instead of text. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- It lists 20 uploads unless you pass
-n. --jsongives the same fields asaktar upload --json, including each upload'sidforaktar qr.
Examples
aktar history -n 3
2026-10-01 screenshot.png https://files.example.com/2026/10/7f3c2a91.png
2026-10-01 cover.jpg https://files.example.com/blog/2026/cover.jpg
2026-09-30 invoice-september.pdf https://files.example.com/2026/09/0e7d51b3.pdfaktar history invoice -d Screenshots
2026-09-30 invoice-september.pdf https://files.example.com/2026/09/0e7d51b3.pdf
2026-08-29 invoice-august.pdf https://files.example.com/2026/08/a6c94f20.pdfaktar history -d Builds -n 1 --json | jq -r '.[0].url'
https://acme-builds.s3.amazonaws.com/2026/10/app-3f9c2e1.zipaktar mcp
Runs a Model Context Protocol (MCP) server, so AI agents such as Claude, Cursor, VS Code and Codex can upload files through Aktar, find past uploads and make links. Add it to your agent once; the agent starts it when it needs it.
Usage
aktar mcp [--root <folder>]... [--read-only | --allow-replace | --allow-delete] [--max-link-minutes <n>] [--log <file>]Options
| Flag | Value | Description |
|---|---|---|
--root | <folder> | Only upload files from this folder. Repeat for more folders. Default: the folder the server runs in, or none when that's your home folder or the top of the disk. |
--read-only | Only offer the tools that change nothing in a bucket: search, lists, temporary links and thumbnails. | |
--allow-replace | Also offer replace_file, which overwrites a file in a bucket. | |
--allow-delete | Also offer delete_upload, which deletes a file from its bucket, and replace_file. | |
--max-link-minutes | <n> | The longest a temporary link may work, in minutes. Default 60, at most 10080 (7 days). |
--log | <file> | Append each tool call (time, tool, arguments, result) to this file, readable only by you. |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Good to know
- Run
aktar loginfirst. The server reads the saved token on every call, so logging in again works without restarting the agent. - Uploading publishes a file: anyone with its link can open it. Agents ask before calling a tool unless you allow it.
- Files are only uploaded from the folders you give with
--root, or else from the folder the server runs in. If that's your home folder or the top of the disk, as some apps do, no local files are uploaded until you add--root.--root ~allows your whole home folder, if you really want that. Paths are resolved, symlinks included, before they're checked. - Secrets are never uploaded, wherever they are: SSH and private keys,
.envfiles, cloud and package manager credentials (~/.aws,~/.kube,~/.npmrcand others), Aktar's own config, the Keychain, browser profiles and password databases. Files with several hard links are refused too. To share one of these, upload it yourself withaktar upload. --read-onlyoffers only the tools that change nothing in a bucket.replace_fileoverwrites a file like a delete would, so it's only offered with--allow-replace, anddelete_uploadonly with--allow-delete(which also offersreplace_file).create_temporary_linkmakes links of at most 60 minutes, unless--max-link-minutesallows more.upload_clipboardis left out when you give--root, since the clipboard can hold anything.- Tool results start with a note that file names, keys and messages in them are data, not instructions, and
--logkeeps a record of every call. It runs at most 4 tool calls at once. - Without a global install, use
npx -y @getaktar/cli mcp --root ~/Projectsas the command. - It speaks the current MCP version (2026-07-28) and the earlier ones that start with
initialize(2024-11-05 to 2025-11-25), over stdio. Needs aktar 0.4.0; the limits above come with aktar 0.6.0.
Tools
| Tool | What it does |
|---|---|
upload_file | Uploads a file and returns its link, Markdown and HTML. Destination, name, folder and expiry are optional. short asks for a short link, or for none. |
upload_clipboard | Uploads the file or image on the clipboard. short asks for a short link, or for none. Left out when --root is given. |
replace_file | Writes a new file over an upload or any file in a bucket, keeping its link. Only with --allow-replace or --allow-delete. Needs Aktar for Mac 0.14.0 or Windows 0.7.0. |
create_short_link | Makes a short link for an upload with its destination's link shortener, or returns the one it has. Left out with --read-only. Needs Aktar for Mac 0.17.0 or Windows 0.10.0. |
search_uploads | Searches the upload history. |
list_destinations | Lists destinations and the file types each one is used for. |
list_bucket | Lists a bucket's folders and files, including files not uploaded with Aktar. |
create_temporary_link | Makes a link that stops working after a while (a presigned URL). Anyone with it can download the file until then, even from a private bucket. At most 60 minutes unless --max-link-minutes allows more. |
get_thumbnail | Shows the agent a preview of an upload. Needs Aktar for Mac 0.13.0 or Windows 0.6.0. |
list_watched_folders | Lists watched folders and their status. |
get_status | Checks the connection to Aktar. |
delete_upload | Deletes an upload from its bucket. Only with --allow-delete. |
Examples
claude mcp add aktar -- aktar mcp --root ~/Projects
codex mcp add aktar -- aktar mcp --root ~/Projectsclaude mcp add aktar -- aktar mcp --root ~/Projects --root ~/Desktop --allow-replaceclaude mcp add aktar -- aktar mcp --root ~/Projects --log ~/aktar-mcp.logaktar skill
Prints an agent skill (SKILL.md) that teaches agents to use the aktar command with --json: what to run, how to read the result, and to upload only what you asked to share. For agents that use skills but not MCP.
Usage
aktar skillOptions
No options.
Good to know
- Save it where your agent looks for skills, for example
~/.claude/skills/aktar/for Claude Code.
Examples
mkdir -p ~/.claude/skills/aktar
aktar skill > ~/.claude/skills/aktar/SKILL.mdOptions for every command
| Flag | Value | Description |
|---|---|---|
-h, --help | Show the list of commands and options. | |
-v, --version | Show the version of aktar. | |
--port | <port> | Aktar's local API port, for this command only. Wins over AKTAR_PORT and the saved port. |
Output
Formats
-f picks what's printed for each upload. Without it, aktar prints the plain URL, whatever format Aktar's menu bar copies. Markdown and HTML embed images and link everything else, the same way Aktar does.
| Format | Printed for photo.jpg |
|---|---|
-f url | https://files.example.com/2026/10/7f3c2a91.jpgThe link (default). |
-f markdown | A Markdown image, or a Markdown link for other files. |
-f html | <img src="https://files.example.com/2026/10/7f3c2a91.jpg" alt="">An <img> tag, or an <a> link for other files. |
-f custom | Your template from Aktar's settings, with {url}, {filename} and the other variables filled in. |
stdout and stderr
Standard output gets only the links, one per line, in the order of the files (and the QR codes, with --qr). Everything else goes to standard error: progress, errors, and notes such as aktar: photo.jpg: already uploaded, reused the existing link. So url=$(aktar upload file) and aktar upload *.png > links.txt always get clean links.
aktar upload photo.jpg
aktar: photo.jpg: already uploaded, reused the existing link
https://files.example.com/2026/09/4d2a8c61.jpgJSON
--json prints an array with one entry per uploaded file, after all of them are done. Failed uploads are left out (they're reported on stderr), so check the exit code too.
aktar upload photo.jpg --json
[
{
"id": "0B6C2F8E-3D1A-4C55-9E2B-7A41D0C3E9F1",
"filename": "photo.jpg",
"objectKey": "2026/10/7f3c2a91.jpg",
"url": "https://files.example.com/2026/10/7f3c2a91.jpg",
"shortUrl": null,
"destinationId": "5D1A9C3E-7B2F-4E61-8A0D-3C9B6F2E1A47",
"destinationName": "Screenshots",
"mimeType": "image/jpeg",
"size": 482113,
"createdAt": "2026-10-01T12:00:00Z",
"expiresAt": null,
"formats": {
"url": "https://files.example.com/2026/10/7f3c2a91.jpg",
"markdown": "",
"html": "<img src=\"https://files.example.com/2026/10/7f3c2a91.jpg\" alt=\"\">",
"custom": ""
},
"reused": false
}
]| Field | Meaning |
|---|---|
id | The upload's ID in Aktar's history. aktar qr takes it. |
filename | The file name Aktar knows it by: the file's own, or --name. |
objectKey | Where the file is in the bucket. |
url | The link. |
shortUrl | The short link, or null when there's none. formats already use it. |
destinationId | The destination's ID. |
destinationName | The destination's name. |
mimeType | The file's type, after any conversion by Aktar. |
size | Size in bytes, as stored. |
createdAt | When it was uploaded (ISO 8601, UTC). |
expiresAt | When the bucket deletes it, or null if it's kept. |
replacedAt | When the file was last replaced (ISO 8601, UTC). Left out until it's replaced, and by Aktar versions before Mac 0.14.0 and Windows 0.7.0. |
formats | The link in all four formats: url, markdown, html and custom. |
reused | true when nothing was uploaded because the same file was already there. Left out by Aktar versions before Mac 0.10.0 and Windows 0.3.0. |
shortLinkError | Why Aktar couldn't make the short link; url is then the original link. Left out when nothing went wrong. |
Exit codes
| Code | Meaning |
|---|---|
0 | Everything worked. |
1 | At least one upload or request failed; the others still went through. Aktar's own errors, such as auto-delete not being set up, also end here. |
2 | Bad arguments, a file that doesn't exist, or a destination name Aktar doesn't have. Nothing was uploaded. |
3 | Not logged in, Aktar isn't running, its local API is off, the token is wrong, or the app on the port couldn't prove it's Aktar (or is too old to). |
Recipes
Copy, adjust the file names, done. Every recipe uses only what's documented above.
Keep the link in a variable
Only the link reaches standard output, so command substitution gets exactly the URL. || exit 1 stops the script if the upload failed.
url=$(aktar upload build/report.pdf) || exit 1
echo "Report: $url"
Report: https://files.example.com/2026/10/0e7d51b3.pdfUpload a build and post the link
Zip a build, upload it to a destination named Builds under the commit's short hash, and post the link to any webhook that takes JSON (a chat channel, an issue tracker, your own endpoint). set -e stops before posting if the upload fails.
#!/bin/sh
set -e
zip -qr app.zip dist
url=$(aktar upload app.zip -d Builds --name "app-$(git rev-parse --short HEAD)")
curl -fsS -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-d "{\"text\": \"New build: $url\"}"A Makefile target
make share uploads the report under today's date and keeps the link in .last-link. In a Makefile, $$ passes a $ to the shell, and the command line starts with a tab.
share: dist/report.pdf
aktar upload dist/report.pdf --name "report-$$(date +%F)" | tee .last-linkTypora image uploader
In Typora, open Settings > Image, choose Custom Command as the image uploader and enter the full path to aktar (the one which aktar prints) followed by upload. Typora passes the image paths and reads one link per line.
/opt/homebrew/bin/aktar uploadStep by step, with the When Insert… setting: Upload Typora images to S3.
Upload from Finder or Shortcuts
On a Mac, add a Run Shell Script action to a Shortcut, or to an Automator Quick Action that receives files in Finder, and set it to pass input as arguments. Shortcuts and Automator don't load your shell's PATH, hence the first line. Select files, run it, and the links are on the clipboard.
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
aktar upload "$@" | pbcopy
osascript -e 'display notification "Link copied" with title "aktar"'It uploads files, not folders. Several files give several links, one per line.
Temporary files
For a log, a screen recording or anything that shouldn't stay around, let the bucket delete it. The destination needs Aktar's auto-delete rules first: set them up once from Delete after in Aktar's menu bar or the destination's settings.
aktar upload crash.log --expires 1
aktar upload screen-recording.mov --expires 7 --qrExpiring files go under tmp/1d/, tmp/7d/ and so on in the bucket, and the bucket deletes them even when Aktar isn't running.
Open a link on your phone
--qr prints a QR code under the link; point your phone's camera at the terminal. To show it again later, pass an upload's ID to aktar qr, here the latest upload matching "demo".
aktar upload demo.mp4 --qr
aktar qr "$(aktar history demo -n 1 --json | jq -r '.[0].id')"Windows PowerShell
The same works in PowerShell. $LASTEXITCODE holds the exit code, and ConvertFrom-Json reads --json.
$url = aktar upload .\dist\app.zip -d Builds
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Set-Clipboard $url
$upload = aktar upload .\report.pdf --json | Out-String | ConvertFrom-Json
$upload.formats.markdownAktar in Claude Desktop, Cursor or VS Code
Apps that take a JSON config for MCP servers (Claude Desktop, Cursor, Windsurf and others) need this entry. VS Code uses the same entry under servers in .vscode/mcp.json. Then ask your agent to upload a file, find last week's screenshots or make a temporary link.
{
"mcpServers": {
"aktar": { "command": "aktar", "args": ["mcp", "--root", "/Users/you/Projects"] }
}
}If the app can't find aktar, use its full path (which aktar), or npx with ["-y", "@getaktar/cli", "mcp", "--root", "/Users/you/Projects"] as the arguments. Put the folder your agent may upload from after --root (on Windows, like C:\\Users\\you\\Projects).
What Aktar does for you
The CLI only passes files on; Aktar does the rest, with each destination's settings. So everything you set up in the app applies to aktar upload too, without any extra options, and the link you get is the one for the file as stored.
-
Path templates
The destination's object path names the file, with
{year},{uuid},{filename}and the rest.{md5}and{sha256}name files by their contents. -
Image processing
If the destination converts images to WebP or AVIF, compresses or resizes them, CLI uploads get the same treatment, and the link points to the converted file.
-
Photo metadata
Image metadata in the destination's upload defaults removes the location from photos, or all metadata, before they leave your computer.
-
Same file, same link
With Reuse links for duplicate files on, the same contents in the same destination get the existing link instead of a second upload.
aktarnotes it on stderr. -
Big files
Large files go up in parts, with no 5 GB limit, are retried after a dropped connection and resume where they stopped.
aktarstreams the file to Aktar, so it never loads it into memory. -
Public or temporary links
Whether the link is public or a temporary (presigned) one that also works for a private bucket is the destination's choice, as in the app.
Duplicate links, image processing, {md5} and {sha256} and uploads in parts came with Aktar for Mac 0.10.0 and Windows 0.3.0: what's new in 0.10.0.
Troubleshooting
Error messages from aktar start with aktar: and go to stderr. The exit code tells you what kind of problem it is.
Aktar isn't running, or its local API is turned off
Open Aktar and check that Allow local connections is on in Settings > Integrations. If you changed the port there, pass it with --port or AKTAR_PORT, or run aktar login --port again. Exit code 3.
Not connected to Aktar yet
There's no saved token and no AKTAR_TOKEN. Run aktar login with the token from Aktar's Settings > Integrations. Exit code 3.
The token doesn't match Aktar's anymore
The token was regenerated in Aktar, or it's mistyped. Run aktar login again with the current one. If AKTAR_TOKEN is set, it wins over the saved token, so update or unset it too. Exit code 3.
The app on port … couldn't prove it's Aktar
Something answered on Aktar's port but couldn't show it has your token, so the token wasn't sent. If Aktar is running, its token has probably changed: run aktar login again. If Aktar isn't running, open it. Exit code 3.
This version of Aktar can't prove it's Aktar
aktar 0.6.0 and later check the app before sending the token, which needs Aktar for Mac 0.18.0 or Aktar for Windows 0.11.0 or later. Update Aktar (it offers updates itself), and the command works again. Exit code 3.
MCP: This server doesn't upload local files
The agent started aktar mcp in your home folder or at the top of the disk, and there's no --root. Add --root with the folder files may come from to the server's command or config, for example aktar mcp --root ~/Projects, and restart the agent.
Auto-delete isn't set up for this destination
--expires needs the bucket's auto-delete rules. Set them up once from Delete after in Aktar's menu bar or the destination's settings, or upload without --expires. Exit code 1.
No destination named "…"
The message lists the names Aktar has. Check the spelling, quote names with spaces (-d "Client work"), or use the ID from aktar destinations. Exit code 2.
A big upload takes a long time
That's the storage provider's speed: aktar has no time limit for uploads and shows progress on stderr in a terminal. Keep Aktar running until it's done. If the connection drops or Aktar quits (Aktar closed the connection before the request finished), upload the same file again: Aktar for Mac 0.10.0 and Windows 0.3.0 continue from the last part.
aktar won't start: SyntaxError or parseArgs
Your Node.js is older than 18. Check with node --version and update it, or install aktar with Homebrew, which brings its own Node.js.
PowerShell says running scripts is disabled
PowerShell's execution policy blocks the script npm installs for aktar. Run aktar.cmd instead, or allow local scripts once with Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.