
Company News
Jerod Santo Joins Socket as Head of Media
Allow myself to introduce... myself.
@mafdet/cli
Advanced tools
Mafdet AI command line — model calls, account queries, and a permissioned local agent.
The official Mafdet AI command line: model calls, account queries, and a permissioned local agent.
0.4.13. 中文版见 README.zh-CN.md. The CLI never advertises a command it cannot serve, so
mafdet helpalways lists exactly what works.macOS and Windows are not yet verified. On Windows the command timeout uses
taskkill /T, which is written but has never been run on a real Windows machine - so whether every grandchild process is reached there is unverified rather than fixed.
Mafdet AI is an OpenAI-compatible AI gateway: one API key and one base URL reach models from several providers, billed by usage. Any tool or SDK that speaks the OpenAI API works by pointing its base URL and key at Mafdet AI.
https://api.mafdet.ai/v1/chat/completions, /embeddings, /audio/speechmodels.jsonNode.js 20 or newer, and a Mafdet API key.
npm install -g @mafdet/cli
Or build it from this repository:
pnpm --filter @mafdet/cli build
cd packages/cli && npm pack # -> mafdet-cli-0.4.13.tgz
npm install -g ./mafdet-cli-0.4.13.tgz
Run mafdet with no arguments in a terminal and it opens a session: pick how
to authenticate, choose a model, then talk to the agent.
mafdet # read-only
mafdet --allow-write # changes are shown as a diff and confirmed first
mafdet --allow-command "pnpm test"
It is the same agent as mafdet agent, drawn differently - the same tools, the
same approvals, the same cost accounting. The flags mean exactly what they mean
there, and a session given neither has no write or command tool loaded at all.
mafdet in a pipeline, under --json, in CI, or with --no-tui behaves
exactly as it did in 0.3: usage on stderr, exit 2. Nothing that reads the
CLI's output will start receiving a drawing.
export MAFDET_API_KEY="sk-mafdet-live-..." # never passed as a flag
export MAFDET_MODEL="deepseek-v4-flash"
mafdet doctor # check key, endpoints, model, balance
mafdet models list # what this key can actually call
mafdet chat "Explain TypeScript decorators"
mafdet account balance
$env:MAFDET_API_KEY = "sk-mafdet-live-..."
$env:MAFDET_MODEL = "deepseek-v4-flash"
mafdet doctor
mafdet chat "Explain TypeScript decorators"
Everything the CLI prints is ASCII, so output stays readable on a console
running a non-UTF-8 code page (the Windows PowerShell 5.1 default). Piping a
prompt works too, but PowerShell pipes UTF-16 by default — prefer passing the
prompt as an argument, or use --input <file>.
| Command | What it does |
|---|---|
mafdet doctor | One pass over key, endpoints, model, tool-calling, balance, workspace, git |
mafdet models list [--surface chat|embeddings|speech] [--agent] | Models this key can call, joined with catalogue metadata |
mafdet models show <id> | One model in detail, including whether the agent may drive it |
mafdet chat [prompt] [--model] [--system <file>] [--input <file>] [--no-stream] [--quiet] [--save] | Send a prompt; streams by default |
mafdet agent "<goal>" [--allow-write] [--allow-command "<prefix>"] | Local agent; read-only unless told otherwise |
mafdet agent (no goal, needs a terminal) | Interactive session |
mafdet embed [text|<file>] --model <id> [--output <file>] | Text to vector |
mafdet speech [text|<file>] --model <id> --output <file> --voice <name> | Text to an audio file |
mafdet account balance|usage|subscription | Wallet, spend and plan (needs the account:read scope) |
mafdet sessions list|show|usage|delete | Conversations saved on this computer (never calls a model) |
mafdet sessions usage <id> --refresh | Show settled ledger figures alongside the local estimate |
mafdet config list | The resolved settings and where each came from |
--json on any query command emits one complete JSON document; --plain
emits tab-separated rows with no header, for cut and awk.
Read-only by default: list, search, read files, and git status / git diff.
It cannot change anything.
--allow-write adds edit_file and create_file, and then:
--allow-command "<prefix>" adds run_command, unprompted for exactly those
prefixes: pnpm test permits pnpm test --filter web but never pnpm publish.
There is no shell - the command is split into argv, so pipes, redirects,
;, &&, backticks and $( ) are refused with an explanation rather than
sanitised.
What approving a command means. It means allowing that program to run on
your machine, as you. The workspace bounds which files the agent's own tools
may touch; it is not a sandbox, and it does not bound the program. pnpm test
can read your home directory, reach the network, or start something that
outlives the run - because that is what running a program is. A short list of
obviously destructive names is refused (sudo, su, doas, chown,
shutdown, reboot, and invoking a program by path), but treat that as a
guard against slips rather than as containment. Approve prefixes the way you
would run the command yourself.
In a session: /model, /permissions, /diff, /cost, /compact, /exit.
Resolution order: --model > MAFDET_MODEL > project config > user config >
default. mafdet config list shows which one won.
| Variable | Default |
|---|---|
MAFDET_API_KEY | (required) |
MAFDET_MODEL | none |
MAFDET_BASE_URL | https://api.mafdet.ai/v1 |
MAFDET_BACKEND_URL | https://backend.mafdet.ai |
User config lives at ~/.config/mafdet/config.json (Linux),
~/Library/Application Support/mafdet/config.json (macOS) or
%APPDATA%\mafdet\config.json (Windows).
A project may carry .mafdet.json with model — and nothing else.
Credentials and endpoints in a project file
are rejected outright: cloning a repository must never change where your key
is sent.
Scripts may branch on these; a value never changes meaning once released.
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General failure (including doctor reporting a failed check) |
| 2 | Bad command line or configuration |
| 3 | Authentication or permission failure |
| 4 | Model or API unavailable |
| 5 | Local permission denied |
| 6 | Cancelled by the user |
| 7 | Cost, time, or loop ceiling reached |
If you build a script on this, here is what will and will not move.
Within a major version:
--json output keeps its name, type and meaning; new fields may
be added, so parse by name and ignore what you do not know;--plain keeps its column order and stays tab-separated with no header.This is a 0.x release, so semver still permits a break in a minor bump. The intent is not to use that latitude, and any change will be listed in CHANGELOG.md; the promise becomes binding at 1.0.0.
Money is always an integer count of micro-USD, sent as a string in --json so
that no parser rounds it. Do not read the human-formatted dollar figure.
Results and machine-readable JSON go to stdout. Progress, warnings, summaries
and diagnostics go to stderr, so mafdet chat ... > answer.txt captures the
answer alone and mafdet models list --json | jq always parses.
The key is read from MAFDET_API_KEY. There is deliberately no --api-key
flag: it would put the key into shell history and the process list. Keys are
never written to a config file and never printed in full — only as a
fingerprint like sk-mafdet-live-<redacted>.
Interactive sessions are saved on this computer, and only on this computer. They are not uploaded, and Mafdet holds no copy of them.
That is a statement about the transcript, not about the model. The messages you send are still sent to the API to be answered and still appear in your usage records; what stays local is the saved copy.
Where they live:
| Platform | Path |
|---|---|
| Linux / WSL | ${XDG_STATE_HOME:-~/.local/state}/mafdet/sessions |
| macOS | ~/Library/Application Support/mafdet/sessions |
| Windows | %LOCALAPPDATA%\mafdet\sessions |
The files are plain text. A transcript contains your messages, the model's
replies, and any source the agent read while working — so treat a session
directory the way you would treat the project it came from. API keys are the
one exception: everything is passed through redaction on the way to disk, so a
key you paste into a prompt is stored as <redacted>. Files are created
0600 and directories 0700 on Linux and macOS; Windows has no equivalent
mode bits and inherits the ACL of %LOCALAPPDATA%.
The agent cannot read these directories, even when you run mafdet from your
home directory and the store is technically inside the workspace. Otherwise an
agent working on one project could read another project's transcript in full.
Turning it off and cleaning up:
mafdet --no-history # this run is not recorded at all
mafdet chat "..." --save # a one-shot chat is saved only when asked
mafdet sessions list # what is saved, and the path when nothing is
mafdet sessions delete <id> --yes
A single mafdet chat is not a conversation anyone resumes, so it is not
recorded unless --save is given. --no-history still wins over --save, and
a chat cancelled with Ctrl+C is not saved at all — half a reply is a worse
record than none.
--no-history writes nothing — not an empty directory, not an index entry.
Deleting removes the local messages and this session's usage mapping. It does not remove API usage, billing records or charges: those belong to the API key, not to the transcript. And it is an ordinary file delete, not a secure erase — backups, snapshots and the filesystem itself may still hold copies.
mafdet sessions usage <id> adds up what a conversation used from the local
record. Those charges are estimates, computed with the gateway's own
arithmetic but computed here.
--refresh asks the billing ledger for settled figures. It pages through the
current API key's usage events for the session's time window; request IDs stay
local and are used only to match returned rows. No messages, title, workspace
or session ID are sent. Requests paid for by a different API key are left
alone and reported, so you know to run it again with that key.
A request that the ledger has not caught up with stays pending, and a request
that never returned an ID stays unknown. Neither is ever shown as 0, which
would read as "it was free".
chat prints tokens and an estimated charge to stderr, computed with the same
arithmetic the gateway bills with. The wallet remains the authority.
Cancelling with Ctrl+C closes the connection. In testing against production a
cancelled stream produced no charge, but that is an observation, not a
guarantee: if the upstream has already finished generating, a charge can still
land. The summary after a cancel is labelled partial: for that reason.
FAQs
Mafdet AI command line — model calls, account queries, and a permissioned local agent.
The npm package @mafdet/cli receives a total of 19 weekly downloads. As such, @mafdet/cli popularity was classified as not popular.
We found that @mafdet/cli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Company News
Allow myself to introduce... myself.

Research
/Security News
A Twitch browser extension on Chrome and Firefox forwards users’ live OAuth session tokens through proxies controlled by a Russian bot service.

Security News
Anthropic found biased reasoning and recklessness drove Claude Mythos 5 to publish malware on PyPI and compromise a security vendor.