
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
@fectivnfy/minimax-code-sdk
Advanced tools
TypeScript SDK for the MiniMax Code CLI (mcode) — mirrors the skeleton of @anthropic-ai/claude-code while carrying mcode-native semantics.
@fectivnfy/minimax-code-sdkThe official TypeScript SDK for the MiniMax Code CLI (mcode).
The skeleton mirrors
@anthropic-ai/claude-code; the semantics are mcode-native. See docs/spec.md for the full design contract and docs/design-decisions.md for the rationale behind every choice.
import { query } from "@fectivnfy/minimax-code-sdk";
for await (const ev of query("Reply with the single word: ok")) {
if (ev.type === "delta" && ev.delta.content) {
process.stdout.write(ev.delta.content);
}
if (ev.type === "result") {
console.log(`\nstatus=${ev.result.status} duration=${ev.result.durationMs}ms`);
}
}
npm install @fectivnfy/minimax-code-sdk
Prerequisites: Node.js
>= 18, andmcodeonPATH(install vianpm i -g @minimax-ai/codeor the official installer). If anything is off, runnpx @fectivnfy/minimax-code-sdk doctor.
import { query } from "@fectivnfy/minimax-code-sdk";
const events = query("Explain stream-json in one sentence");
for await (const ev of events) {
// ev is one of 7 native mcode event types — see "Streaming" below.
}
The SDK passes the native mcode stream-json through unchanged.
Consumers see exactly the 7 event types that mcode exec --output-format stream-json emits:
| Event type | Carries |
|---|---|
heartbeat | turnId — liveness signal |
session-status | started | finished, turnId |
message | full message snapshot (role, content, thinking, usage, …) |
delta | streaming chunk (content or thinking, chunkIndex, finish) |
generic | forward-compat envelope for mcode internal events |
done | turn finished |
result | final aggregated exec.result (status, answer, durationMs, model, usage) |
By default each query() is a fresh session. To continue, pass either:
// continue the most recent session in this cwd
for await (const ev of query("Now add 7", { continue_conversation: true })) { /* … */ }
// or resume a specific one
for await (const ev of query("And divide by 2", { session_id: "mvs_…" })) { /* … */ }
// Read-only run: agent can read but not write or run shell.
for await (const ev of query("List files in ./src", { permission: "off" })) { /* … */ }
Values: "ask" | "smart" | "full" | "off" (mcode-native; not Claude's).
for await (const ev of query("Summarise these", {
files: ["./src/index.ts", "./README.md"],
})) { /* … */ }
const ac = new AbortController();
setTimeout(() => ac.abort(), 30_000);
try {
for await (const ev of query("…", { signal: ac.signal, timeout_ms: 25_000 })) { /* … */ }
} catch (e) {
if (e instanceof TimeoutError) console.error("timed out");
if (e instanceof AbortError) console.error("aborted");
}
For richer bidirectional integrations (IDE plugins, agent-of-agents):
import { acp } from "@fectivnfy/minimax-code-sdk";
const conn = acp.start({ model: "minimax/MiniMax-M3", permission: "ask" });
const off = conn.onMessage((msg) => console.log("[in]", msg.method, msg.params));
try {
const result = await conn.request("session/prompt", { prompt: "Hello" });
console.log("got:", result);
} finally {
off();
await conn.close();
}
ACP message names are passed through from the mcode acp protocol —
the SDK does not re-shape them. See examples/05-acp.ts.
import { MavisClient } from "@fectivnfy/minimax-code-sdk";
const client = new MavisClient();
console.log(await client.getVersion());
console.log(await client.getProviders());
console.log(await client.getPlugins());
console.log(await client.getActiveSessions());
console.log(await client.getBackgroundTasks());
console.log(await client.getCurrentAccount());
console.log(await client.getConfig());
MavisClient.sessionStore exposes a typed, programmatic surface over the
runtime's session data. The store reads the runtime's SQLite index
(~/.minimax/v2/sqlite/runtime-state.sqlite) directly — no mcode shell-out
needed.
import { MavisClient, SessionNotFoundError } from "@fectivnfy/minimax-code-sdk";
const client = new MavisClient();
const store = client.sessionStore(); // read-only by default
// List recent sessions, with filters
const recent = await store.list({ limit: 10, agentName: "mavis" });
// Drill into a single session
const detail = await store.get(recent[0]!.id);
console.log(detail.title, detail.status, detail.model);
// Walk the persisted message transcript (with tool calls)
const messages = await store.getMessages(detail.id, {
limit: 5,
includeThinking: false, // opt in to surface thinking_content
});
// Token usage, rolled up by model and turn
const usage = await store.getUsage(detail.id);
console.log(`${usage.totalTokens} tokens across ${usage.callCount} calls`);
// Free-text search across titles and message bodies
const hits = await store.search("OAuth device flow", { scope: "all" });
// Aggregate stats across the runtime
const stats = await store.getStats();
console.log(`${stats.total} sessions, ${stats.byStatus["idle"] ?? 0} idle`);
// Write operations — opt in explicitly.
const rws = client.sessionStore({ writable: true });
await rws.archive(detail.id);
await rws.rename(detail.id, "renamed-by-script");
await rws.unarchive(detail.id);
await rws.delete(detail.id); // DESTRUCTIVE — be sure.
See examples/07-session-store.ts for a runnable walk-through, and
docs/spec.md §2.1 for the full type surface.
Error handling:
import { SessionNotFoundError, SessionStoreError } from "@fectivnfy/minimax-code-sdk";
try {
await store.get("mvs_does_not_exist");
} catch (e) {
if (e instanceof SessionNotFoundError) {
console.error(`no such session: ${e.sessionId}`);
} else if (e instanceof SessionStoreError) {
console.error("store failure:", e.message, e.cause);
}
}
client.sessionStore().send(id, prompt, options?) resumes a session by
spawning mcode exec --session <id> and streaming events back. It
returns the same QueryHandle as query():
const handle = client.sessionStore().send(detail.id, "and add 7");
for await (const ev of handle) {
if (ev.type === "result") console.log("done:", ev.result.answer);
}
client.sessionStore().tailMessages(id, options?) is a polling
async-generator for "anything new since cursor" — useful for monitoring
sessions you don't own:
const ac = new AbortController();
setTimeout(() => ac.abort(), 60_000);
for await (const msg of client.sessionStore().tailMessages(detail.id, {
intervalMs: 1000,
includeThinking: false,
signal: ac.signal,
})) {
console.log(`[${msg.role}] ${msg.content.slice(0, 80)}`);
}
Four lazy properties on MavisClient for managing the runtime's
plugins, agents, cron tasks, and MCP servers:
// Plugins — wraps `mcode plugin …`
const plugins = await client.plugins.list();
await client.plugins.add("my-plugin@official");
await client.plugins.enable("my-plugin@official");
await client.plugins.remove("my-plugin@official");
// Agents — read-only (use the runtime UI to create)
const agents = await client.agents.list();
const def = await client.agents.getDefault();
const mavis = await client.agents.get("mavis");
// Cron — read-only (use the mavis native tool to create)
const crons = await client.cron.list();
const runs = await client.cron.listRuns(crons[0]!.cronId, { limit: 10 });
// MCP servers — read-only (edit `~/.minimax/mcp/mcp.json` to add)
const servers = await client.mcp.list();
const tv = await client.mcp.get("textvision");
The agents / cron / mcp surfaces are read-only because the runtime
exposes no public CLI for create / update. See examples/08-runtime-managers.ts
for a runnable walk-through.
Providers (v0.3.1) — the only manager with a full CRUD surface
(decision Q59). The mcode provider CLI is a complete one, so the
SDK wraps it 1:1.
// List — richer than `getProviders()` (also returns `minimaxModelSource` + per-provider `kind`/`models`)
const result = await client.providers.list();
console.log(result.minimaxModelSource, result.active?.providerId);
// Add a custom provider (api key is referenced by env-var, never stored)
await client.providers.add({
name: "OpenCodeGo",
baseUrl: "https://api.opencodego.example.com",
apiFormat: "openai-completions",
models: ["deepseek-v4-flash"],
apiKeyEnv: "OPENCODEGO_KEY",
use: true,
});
// Connectivity test
const t = await client.providers.test("custom_provider:opencodego", { model: "deepseek-v4-flash" });
if (!t.ok) console.error("provider test failed:", t.output);
// Switch minimax credential source
await client.providers.use("api-key");
await client.providers.setMinimaxKey({ apiKeyEnv: "MINIMAX_API_KEY" });
// Remove a custom provider (pass `{ yes: true }` to skip the confirm)
await client.providers.remove("custom_provider:opencodego", { yes: true });
All options are snake_case (matching mcode's CLI) and live on the
second argument to query() / MavisClient.query().
| Option | Type | CLI equivalent | Notes |
|---|---|---|---|
input | string | --input | mcode currently only accepts "-" |
input_format | "text" | "json" | --input-format | |
cwd | string | --cwd | defaults to process.cwd() |
files | string[] | --file (repeatable) | attachments |
model | "<provider>/<model>" | --model | |
session_id | string | --session | |
continue_conversation | boolean | --continue | |
config | string | --config | runtime config path |
permission | "ask" | "smart" | "full" | "off" | --permission | mcode-native |
max_steps | number | --max-steps | |
output_format | "text" | "json" | "stream-json" | --output-format | |
output_schema | string | --output-schema | JSON Schema |
signal | AbortSignal | (SDK-only) | cooperative cancel |
timeout_ms | number | (SDK-only) | numeric ms; throws TimeoutError |
The full public surface is exported from @fectivnfy/minimax-code-sdk:
MavisClient — main class with query(), getVersion(),
getCurrentAccount(), getConfig(), getProviders(),
getPlugins(), getActiveSessions(), getBackgroundTasks(),
sessionStore(overrides?).SessionStore — programmatic session management
(v0.2.0). list / get / getMessages / search / getUsage /
getAssets / getBackgroundTasks / getStats / archive /
unarchive / rename / delete. Also available as a subpath
import: @fectivnfy/minimax-code-sdk/session-store.query(prompt, options?) — convenience one-shot.StreamEvent types and QueryOptions.MavisError base + 7 subclasses: CLINotFoundError,
CLIConnectionError, ProcessError, StreamJsonError, AbortError,
TimeoutError, SessionNotFoundError, SessionStoreError).acp.start(options?) — Agent Client Protocol connection.resolveMcode() / whichMcodeInPath() — binary discovery helpers.parseStreamLine(line) — stream-json line parser (useful for
custom replayers).For exhaustive type-level documentation, generate dist/*.d.ts and
read the source.
import { MavisError, CLINotFoundError, ProcessError, TimeoutError, AbortError, StreamJsonError } from "@fectivnfy/minimax-code-sdk";
try {
for await (const ev of query("…")) { /* … */ }
} catch (e) {
if (e instanceof CLINotFoundError) { /* mcode is not on PATH or in known dirs */ }
if (e instanceof ProcessError) { /* mcode child exited non-zero; e.stderr */ }
if (e instanceof StreamJsonError) { /* bad line in mcode stdout */ }
if (e instanceof TimeoutError) { /* timeout_ms elapsed */ }
if (e instanceof AbortError) { /* AbortSignal fired */ }
if (e instanceof MavisError) { /* any other SDK error */ }
}
mavis-sdk is installed alongside the SDK. v0.1.0 shipped four
subcommands; v0.2.0 added four read-only sessions subcommands;
v0.3.0 added four manager groups (Decision Q25 / Q51 / Q57):
mavis-sdk doctor # verify mcode is installed and reachable
mavis-sdk info # print SDK + mcode state summary
mavis-sdk replay fixture.jsonl # replay a stream-json fixture
mavis-sdk login # proxy mcode login (status if no args)
mavis-sdk sessions list [--agent X] [--status idle] [--archived] [--limit N] [--json]
mavis-sdk sessions show <id> [--json]
mavis-sdk sessions messages <id> [--limit N] [--include-thinking] [--json]
mavis-sdk sessions stats
mavis-sdk plugins list [--available] [--marketplace official] [--json]
mavis-sdk plugins add/remove/enable/disable <plugin[@marketplace]>
mavis-sdk plugins marketplace
mavis-sdk agents list/get/default [--json]
mavis-sdk cron list/get/runs [--json]
mavis-sdk mcp list/get [--json]
sessions subcommands are read-only. Archive / rename / delete are
exposed only via the SDK and require { writable: true }.
Eight runnable examples live in examples/:
01-quickstart.ts — one prompt, one event stream02-streaming.ts — react to each of the 7 event types03-session.ts — multi-turn with continue_conversation04-permission.ts — permission: "off" for read-only runs05-acp.ts — Agent Client Protocol connection06-state-queries.ts — all seven state getters07-session-store.ts — SessionStore walk-through (v0.2.0)08-runtime-managers.ts — plugins / agents / cron / mcp / send (v0.3.0)Run any with npx tsx examples/0X-name.ts.
MIT — see LICENSE.
FAQs
TypeScript SDK for the MiniMax Code CLI (mcode) — mirrors the skeleton of @anthropic-ai/claude-code while carrying mcode-native semantics.
The npm package @fectivnfy/minimax-code-sdk receives a total of 80 weekly downloads. As such, @fectivnfy/minimax-code-sdk popularity was classified as not popular.
We found that @fectivnfy/minimax-code-sdk 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.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.