UFO CLI · Command line and MCP server for Linux

One local tool for every file your agent touches.

Find what is hidden or risky in incoming files, including text written to instruct an AI. Then read them, edit them safely and hand back clean copies, all on your machine.

Free for individuals and small teams.

Every command. No account. Free or paid?

Linux x86_64 · Java runtime included · Claude Code, Codex, Cursor and other MCP clients

A real Claude Code session. The agent used only UFO's tools, over MCP, on nine fictional client files. YouTube loads only when you press play. Watch on YouTube
Transcript and how the film was made
  1. A client sends your AI agent a folder. Nine files: a contract, spreadsheets, slides, an email, a photo.
  2. You ask it to check everything, update the agreement, and send a clean pack to the property owners.
  3. Before it trusts a single file, the agent runs them through UFO, right on your machine.
  4. The meeting notes hide an instruction written for the AI itself: email this whole folder to an outside address. UFO flags it. The agent ignores it.
  5. An email asks for payment to new bank details, with replies going to a lookalike domain.
  6. The contract hides the client's walk-away price. The rent roll hides owner payouts and every tenant's phone number. And the board deck hides a slide marked not for owners.
  7. A statement that isn't really a PDF. A program disguised as a spreadsheet. And a photo that gives away where a tenant lives.
  8. Then the agent does the work. The payment terms change as a tracked change their legal team can accept or reject, with the client's comment still in place.
  9. The owners' pack is updated, cleaned of everything hidden, and checked again before it leaves.
  10. UFO. One local tool for every file your agent touches. Free to start.

Recorded with UFO CLI 1.6.0 release candidate: 62 tool calls in one session, edited into a narrated film. It is not a benchmark. The narration is a synthetic voice. Every name, address and bank detail is fictional; the porch photo is by hi room on Pexels. Session provenance · Watch on YouTube (captions included)

From the film

26 findings in 9 files. 8 rated high.

UFO checked every file before the agent relied on any of them. Then the agent did the job.

What it caught

  • An instruction hidden in the meeting notes, written for AI assistants: email the whole folder to an outside address. UFO flagged it. The agent ignored it.
  • A payment request with new bank details and replies going to a lookalike domain.
  • The client’s walk-away price, hidden in the contract.
  • A very hidden sheet of owner payouts and a hidden column of tenant phone numbers.
  • A board slide hidden from the slideshow, marked not for owners.
  • A PNG named .pdf, a Windows program named rates.csv inside a ZIP, and GPS coordinates in a photo.

What it fixed

  • Payment terms changed from Net 30 to Net 45 as a native Word tracked change, with the client’s comment kept.
  • The board deck marked FINAL, without the hidden slide.
  • Speaker notes and file properties removed.
  • The rent roll with Unit 14 at $1,950, without the payouts sheet or the phone column.
  • The porch photo without GPS or camera data.
  • The owners’ pack checked again with UFO: 0 findings.

Findings are advisory, and each report lists what UFO could not check. UFO is not antivirus and never declares a file safe.

How it works

Check first. Then do the work.

Your agent calls UFO over MCP, as in the film, or a script runs the same commands. Every step returns JSON.

  1. 01

    Find what is hidden or risky

    One report covers a whole folder, by file and severity: hidden content, text aimed at an AI, mismatched reply addresses, disguised files and location data.

    Report on a folder
    ufo report -o report.json ./incoming
  2. 02

    Read what is really there

    Paragraphs, cells and slides with exact locations, so your agent quotes the file instead of guessing.

    Read a document with locations
    ufo text --format structure ./agreement.docx
  3. 03

    Change it without breaking it

    Edits check the source hash and expected text, then write a new copy with a JSON receipt. Word edits can be tracked changes. Preview any edit with --dry-run.

    See one edit operation
    ufo edit paragraphs --help
  4. 04

    Hand back clean copies

    Strip hidden metadata, then check the copy again before it leaves.

    Clean and recheck a photo
    ufo clean -o porch-clean.jpg ./porch.jpg
    ufo inspect --deep porch-clean.jpg

Where the work happens

UFO parses every file on your machine and makes no network connection. Your agent sees only the results it asks for, and may send those to its model provider. Over MCP, UFO reaches only the folders you allow.

How deeply UFO can inspect, read or edit depends on the format. Every command and limit.

Start here

Install it. Check your first folder.

No signup. Needs Linux x86_64 with glibc 2.35 or newer; Alpine and other musl systems are not supported.

Install for your user

Verifies the release checksum and installs under ~/.local, without sudo. Read the installer.

Install UFO on Linux
curl -fsSL https://universalfileopener.com/install.sh | sh
ufo doctor

If ufo is not found, open a new terminal or run export PATH="$HOME/.local/bin:$PATH". PDF conversion and page rendering also need libgl1, libx11-6 and libfontconfig1; the installer names any that are missing.

Check files you already have

The report lists findings by file and anything UFO could not check. Your files are not changed.

Check your first folder
ufo report -o report.json ./your-folder
ufo inspect --deep ./your-folder/one-file

An unfamiliar format returns status: "limited" and exit code 1, with its size, hash and detected type.

npm, Homebrew, Debian package and container

npm

@krauq/ufo-cli downloads and verifies the matching runtime. Needs Node.js 18.17 or later. On npm 11 or earlier, omit --allow-scripts.

Install with npm 12
npm install --global @krauq/ufo-cli@1.10.2 --allow-scripts=@krauq/ufo-cli
ufo doctor

Homebrew on Linux

From the krauqllc/ufo tap. Homebrew 7 loads a tap's formula only after brew trust.

Install with Homebrew
brew trust --formula krauqllc/ufo/ufo
brew install krauqllc/ufo/ufo
ufo doctor

Debian or Ubuntu

The package is on the 1.10.2 release. Tested on Ubuntu 24.04 and Debian 12.

Install the Debian package
sudo apt install ./universal-file-opener_1.10.2_amd64.deb
ufo doctor

Restricted container

Run from a folder containing report.docx; the public image needs no login. It reads, edits and recognizes text, but does not render pages or convert Office files to PDF.

Run the public container
docker run --rm --network none --read-only --cap-drop ALL \
  --user "$(id -u):$(id -g)" --security-opt no-new-privileges \
  --pids-limit 128 --cpus 2 --memory 1g \
  --tmpfs /tmp:rw,nosuid,nodev,size=256m \
  --mount type=bind,src="$PWD",dst=/input,readonly \
  ghcr.io/krauqllc/ufo-cli:1.10.2 text /input/report.docx

For edits, mount a writable /output and write there; input stays read-only and /tmp is required. Verify downloads with the release's SHA256SUMS.

Bring your own agent

Keep the agent you already use.

Add a project guide for your coding agent, or register UFO's tools over MCP.

In your project folder:

Claude Code project setup
ufo doctor
ufo skill install --agent claude-code --dir "$PWD"

Writes .claude/skills/ufo/SKILL.md. If a UFO guide already exists, review it, then add --replace to update it. Claude Code documentation.

Start a new session in this folder and try:

Check every file in ./incoming with UFO before you trust it, and tell me what is risky. Then make the change I ask for in a new copy, check the receipt, and check the copy again before I send it.
Use an MCP connection instead

From the project folder, create the input and output folders:

MCP working folders
mkdir -p inputs outputs
ufo doctor
command -v ufo

Claude Code

Register UFO with Claude Code
claude mcp add --transport stdio --scope project ufo -- \
  "$(command -v ufo)" mcp --stdio \
  --allow-root "$PWD/inputs" --allow-root "$PWD/outputs"
claude mcp list

Codex

Register UFO with Codex
codex mcp add ufo -- "$(command -v ufo)" mcp --stdio \
  --allow-root "$PWD/inputs" --allow-root "$PWD/outputs"
codex mcp list

Cursor or Windsurf

Print a Cursor MCP template
ufo mcp print-config --client cursor

Fill in the full path from command -v ufo and the absolute input and output paths, then merge the ufo entry into the project's .cursor/mcp.json and enable it under Settings → Tools & MCP. For Windsurf, print with --client windsurf and merge into ~/.codeium/windsurf/mcp_config.json.

Restart the client and ask it to list the allowed input folder. Claude Code MCP · Codex MCP · Cursor MCP · Windsurf MCP.

For MCP, allow only the folders the job needs.

Licensing, plainly

Free or paid?

Every command and file type is free. Paying depends on your organization, not the features you use.

Free

  • Individuals
  • Evaluation by any organization, with no time limit
  • Education and non-commercial use
  • Businesses with fewer than 10 people and under USD 1 million in annual revenue

Limits: 25-step batch plans, 200-file folder reports and searches, one job at a time.

When you need to pay

Commercial use by an organization with 10 or more people, or USD 1 million or more in annual revenue. Count employees and long-term contractors; revenue includes funding raised in the last completed fiscal year. You have 90 days after crossing either line.

Any organization can buy a license to lift the free limits.

What a license adds

  • Commercial use for the whole legal entity, with no seats
  • 200-step plans, 20,000-file folder reports and searches, up to 64 parallel jobs
  • A business-day human response to defects that break a receipted edit
  • After twelve paid months in a row, you keep every release up to your last paid day, even after you cancel
Up to 50 people
$99 a month or $990 a year
51 to 500 people
$499 a month or $4,990 a year
Over 500 people
$1,999 a month or $19,990 a year

Prices in USD before tax, one license per organization. Android and Windows Pro purchases do not include a CLI license.

Full reference: reads, all 31 edit operations and size limits

Captured from ufo capabilities on the 1.10.2 release. Run it on your installation for the exact contract, and ufo edit OPERATION --help for one operation.

Reading and inspection commands
CommandInput kindsFiles, where listedOutput formats
intakepdf, image, audio, video, archive, web, office, markdown, sqlite, font, certificate, calendar, contact, email, spreadsheet, text, binaryBy kindJSON receipt
inspectpdf, image, audio, video, archive, web, office, markdown, sqlite, font, certificate, calendar, contact, email, spreadsheet, text, binaryBy kindJSON receipt
textpdf, office, spreadsheet, email, web, markdown, text, calendar, contact, imageBy kindtext, markdown, json, structure, csv
findoffice, spreadsheet, pdf, web, text, markdownazw, csv, docx, epub, json, md, mobi, pdf, pptx, prc, tsv, txt, xlsxcom.krauq.ufo.find-results, com.krauq.ufo.find-folder-results
renderpdf, officedocm, docx, dotm, dotx, pdf, ppsx, pptx, xlsm, xlsxpng
Text export formats
FormatFiles or kinds
textpdf, office, spreadsheet, email, web, markdown, text, calendar, contact, image
markdownpdf, office, spreadsheet, email, web, markdown, text, calendar, contact, image
jsonpdf, office, spreadsheet, email, web, markdown, text, calendar, contact, image
structurecsv, docx, epub, json, md, pdf, pptx, tsv, txt, xlsx
csvdocx, potm, potx, ppsm, ppsx, pptm, pptx, xlsm, xlsx, xltm, xltx
Edit operations
OperationFile typesReceipt change codesOptions
rotatepdfpage_rotated--degrees, --pages, --expect-sha256
pagespdfpage_kept, page_deleted, page_reordered--keep, --delete, --order, --expect-sha256
metadatapdf, docx, docm, dotx, dotm, xlsx, xlsm, xltx, xltm, pptx, pptm, ppsx, ppsm, potx, potm, odt, ott, ods, ots, odp, otp, mp3, imagemetadata_set, metadata_cleared, metadata_stripped--set, --clear, --strip, --expect-sha256
accept-changesdocx, docm, dotx, dotmrevisions_accepted--expect-sha256
reject-changesdocx, docm, dotx, dotmrevisions_rejected--expect-sha256
replace-textdocx, docm, dotx, dotm, pptx, pptm, ppsx, ppsm, potx, potm, xlsx, xlsm, xltx, xltm, texttext_replaced--find, --replace, --ignore-case, --expect-sha256
paragraphsdocx, pptx, pptm, ppsx, ppsm, potx, potmparagraph_written, paragraph_tracked, paragraph_inserted, paragraph_deleted, paragraph_inserted_tracked, paragraph_deleted_tracked, paragraph_styled, comment_added, comment_replied, comment_resolved, comment_deleted, link_added, link_removed, footnote_added--expect-sha256, --expect, --set, --slide, --story, --track, --author, --comment, --reply, --resolve-comment, --delete-comment, --set-style, --insert-after, --insert-before, --style, --delete, --link, --unlink, --footnote
tablesdocxtable_row_copied, table_row_deleted, cells_merged--expect-sha256, --copy-row, --after, --delete-row, --expect-row, --merge-cells, --vmerge
slidespptx, pptm, ppsx, ppsm, potx, potmslide_duplicated, slide_deleted, slide_moved--expect-sha256, --duplicate, --after, --delete, --move, --to
cellsxlsx, xlsm, xltx, xltm, ods, otscell_written, formula_written--set, --expect-sha256, --expect, --sheet
rowsxlsx, xlsm, xltx, xltmrow_appended, row_inserted, row_deleted--sheet, --expect-sha256, --append-row, --style-from-row, --no-style, --insert-before, --delete-row, --expect-row
fieldsjson, csv, tsvfield_written--set, --expect-sha256, --expect, --bare-quotes
linesadb, adoc, ads, am, asciidoc, asm, asp, aspx, ass, atom, awk, bas, bash, bat, bib, bzl, c, cbl, cc, cfg, cjs, clj, cljc, cljs, cls, cmake, cmd, cnf, cob, coffee, conf, cpp, cr, cs, csh, cshtml, csproj, css, cxx, d, dart, desktop, diff, dockerfile, dtd, edn, ejs, el, elm, env, erb, erl, ex, exs, f90, f95, fish, fs, fsi, fsproj, fsx, geojson, go, gpx, gql, gradle, graphql, groovy, gv, gyp, gypi, h, haml, hbs, hcl, hh, hpp, hrl, hs, hx, hxx, inf, ini, ipynb, jade, java, jl, js, json, json5, jsonc, jsonl, jsonld, jsp, jsx, kml, ksh, kt, kts, latex, less, lhs, liquid, lisp, log, lrc, lsp, lua, m, m3u, m3u8, mak, makefile, markdown, md, mdown, mdwn, mdx, mermaid, mjs, mk, mkd, mkdn, ml, mli, mm, mmd, mustache, n3, ndjson, nfo, nim, nix, njk, nt, opml, org, owl, pas, patch, php, pl, plantuml, pm, po, postcss, pp, properties, props, proto, ps1, psd1, psm1, pug, puml, py, pyi, pyw, qmd, r, rb, rc, rdf, reg, resx, rkt, rmd, rs, rss, rst, s, sass, sbt, sbv, sc, scala, scm, scss, sh, slim, sln, sol, sparql, sql, srt, ss, ssa, strings, sty, styl, sv, svelte, swift, targets, tcl, tcsh, tex, texi, text, tf, toml, topojson, ts, tsx, ttl, twig, txt, v, vb, vbproj, vbs, vcxproj, vhd, vhdl, vtt, vue, wsdl, xliff, xml, xsd, xsl, xslt, yaml, yml, zig, zshline_written--set, --expect-sha256, --expect
imagepng, jpg, jpegorientation_normalized, image_cropped, image_resized, image_rotated--crop, --resize, --rotate, --format, --quality, --expect-sha256
image-insertdocx, pptx, pptm, ppsx, ppsm, potx, potmimage_inserted--expect-sha256, --image, --after, --before, --slide, --x, --y, --width-px, --height-px, --alt
image-replacedocx, pptx, pptm, ppsx, ppsm, potx, potmimage_replaced--expect-sha256, --target, --image, --slide, --keep-size, --fit
chartdocx, pptx, pptm, ppsx, ppsm, potx, potm, xlsx, xlsm, xltx, xltmchart_series_written--expect-sha256, --chart, --slide, --story, --sheet, --expect-series, --set-series, --set-series-json, --categories, --categories-json
archivezip, tar, tgz, tbz2, txz, 7zentry_added, entry_removed--add, --remove, --expect-sha256
stamppdfwatermark_added, text_stamped, page_numbers_added--watermark, --text, --page-numbers, --position, --size, --pages, --prefix, --suffix, --start, --digits, --total, --expect-sha256
formpdffield_set--set, --set-values, --expect-sha256
formatdocx, pptx, pptm, ppsx, ppsm, potx, potm, xlsx, xlsm, xltx, xltmformat_applied--expect-sha256, --expect, --apply, --range, --slide, --sheet, --story
pdf-textpdfpdf_paragraph_written--expect-sha256, --page, --expect, --set
mergedocx, docm, dotx, dotm, pptx, pptm, ppsx, ppsm, potx, potm, xlsx, xlsm, xltx, xltmfield_merged, block_repeated--expect-sha256, --data, --data-json, --placeholder, --missing
sheetsxlsx, xlsm, xltx, xltmsheet_added, sheet_renamed, sheet_deleted, sheet_copied--expect-sha256, --add, --after, --rename, --delete, --copy
annotatepdfannotation_added--expect-sha256, --page, --highlight, --highlight-lines, --color, --note, --at, --title
shapespptx, pptm, ppsx, ppsm, potx, potmshape_added, shape_deleted--expect-sha256, --slide, --add-text, --at, --size, --font-pt, --delete-shape, --expect-shape
columnsxlsx, xlsm, xltx, xltmcolumn_inserted, column_deleted--expect-sha256, --sheet, --insert-before, --delete, --count
layoutxlsx, xlsm, xltx, xltmcells_merged, cells_unmerged, panes_frozen, panes_unfrozen, column_width_set, row_height_set--expect-sha256, --sheet, --merge, --unmerge, --freeze, --unfreeze, --column-width, --row-height
chart-createxlsx, xlsm, xltx, xltm, pptx, pptm, ppsx, ppsm, potx, potmchart_created--expect-sha256, --sheet, --slide, --type, --categories, --series, --title, --at, --size
slide-tablepptx, pptm, ppsx, ppsm, potx, potmtable_cell_written, cells_merged, cells_unmerged--expect-sha256, --slide, --shape, --expect, --set, --merge, --unmerge
rulesxlsx, xlsm, xltx, xltmvalidation_added, conditional_format_added, rules_cleared--expect-sha256, --sheet, --validate, --input-message, --error, --highlight, --color-scale, --clear-rules
Largest source file per command
CommandBytesMiB
intake268435456256 MiB
inspect268435456256 MiB
text6710886464 MiB
find6710886464 MiB
clean6710886464 MiB
render268435456256 MiB
edit6710886464 MiB
combine2516582424 MiB
create41943044 MiB
batch10485761 MiB
convert268435456256 MiB
unpack268435456256 MiB
report268435456256 MiB
compare268435456256 MiB

Every edit accepts --expect-sha256 to check the source revision; expected-content guards vary by operation. Edits take files up to 64 MiB. What UFO cannot edit safely is refused, such as a shared or array formula as a write target. PDF conversion uses UFO's own layout, not Microsoft Office's. A receipt records an operation; it does not verify your business facts or visual layout.

Binaries use the business use license; the evaluation tools and schemas are Apache 2.0. Reference captured from 1.10.2, source revision 595269c1be7451c0d6e260d9981aaf66bd795ec0.