diff --git a/crates/buzz-agent/README.md b/crates/buzz-agent/README.md
index a2504db451..307f93e96f 100644
--- a/crates/buzz-agent/README.md
+++ b/crates/buzz-agent/README.md
@@ -55,6 +55,13 @@ BUZZ_AGENT_PROVIDER=databricks \
 DATABRICKS_HOST=https://dbc-...cloud.databricks.com \
 DATABRICKS_MODEL=goose-claude-4-6-sonnet \
   ./target/release/buzz-agent
+
+# Or MiniMax (global endpoint; use minimax-cn for the mainland-China host).
+# MINIMAX_MODEL is optional and defaults to MiniMax-M3.
+BUZZ_AGENT_PROVIDER=minimax \
+MINIMAX_API_KEY=... \
+MINIMAX_MODEL=MiniMax-M3 \
+  ./target/release/buzz-agent
 ```
 
 That's the whole setup. The agent reads JSON-RPC frames from stdin, writes them to stdout, and logs to stderr.
@@ -129,7 +136,7 @@ Everything is environment variables. No flags, no config files. (We are a subpro
 
 | Variable | Default | Notes |
 |---|---|---|
-| `BUZZ_AGENT_PROVIDER` | — | Required. `anthropic`, `openai`, `databricks`, or `databricks_v2`. No implicit fallback — the agent errors at startup when this is unset. |
+| `BUZZ_AGENT_PROVIDER` | — | Required. `anthropic`, `openai`, `databricks`, `databricks_v2`, `minimax`, or `minimax-cn`. No implicit fallback — the agent errors at startup when this is unset. |
 | `ANTHROPIC_API_KEY` | — | Required when provider=anthropic. |
 | `ANTHROPIC_MODEL` | — | Required when provider=anthropic. |
 | `ANTHROPIC_BASE_URL` | `https://api.anthropic.com` | |
@@ -138,6 +145,9 @@ Everything is environment variables. No flags, no config files. (We are a subpro
 | `OPENAI_COMPAT_MODEL` | — | Required when provider=openai. |
 | `OPENAI_COMPAT_BASE_URL` | `https://api.openai.com/v1` | Point at vLLM, llama.cpp, OpenRouter, Ollama, etc. |
 | `OPENAI_COMPAT_API` | `auto` | `auto` \| `chat` \| `responses`. `auto` picks Responses for `*.openai.com`, Chat Completions everywhere else. |
+| `MINIMAX_API_KEY` | — | Required when provider=minimax or provider=minimax-cn. |
+| `MINIMAX_MODEL` | `MiniMax-M3` | Optional. Defaults to the current flagship; `BUZZ_AGENT_MODEL` overrides it. |
+| `MINIMAX_BASE_URL` | region default | Optional override. Defaults to `https://api.minimax.io/v1` for `minimax` and `https://api.minimaxi.com/v1` for `minimax-cn`. |
 | `DATABRICKS_HOST` | — | Required when provider=databricks or provider=databricks_v2. |
 | `DATABRICKS_MODEL` | — | Required when provider=databricks or provider=databricks_v2. |
 | `DATABRICKS_TOKEN` | — | Optional static bearer escape hatch. If unset, Databricks uses browser OAuth + refresh cache. |
@@ -171,9 +181,13 @@ Everything is environment variables. No flags, no config files. (We are a subpro
 | Block Gateway | `openai` | `POST {base}/chat/completions` | gpt-5, claude |
 | Databricks | `databricks` | `POST {host}/serving-endpoints/{model}/invocations` | goose-claude-4-6-sonnet |
 | Databricks AI Gateway v2 | `databricks_v2` | `POST {host}/ai-gateway/{provider}/v1/...` | databricks-gpt-5-5, databricks-claude-opus-4-7 |
+| MiniMax (global) | `minimax` | `POST {base}/chat/completions` | MiniMax-M3, MiniMax-M2.7 |
+| MiniMax (China) | `minimax-cn` | `POST {base}/chat/completions` | MiniMax-M3, MiniMax-M2.7 |
 
 If `BUZZ_AGENT_PROVIDER=anthropic` is selected without `ANTHROPIC_API_KEY`, or `BUZZ_AGENT_PROVIDER=openai` is selected without `OPENAI_COMPAT_API_KEY`, the agent returns an error — there is no implicit fallback to another provider.
 
+`minimax` and `minimax-cn` are the same OpenAI-compatible Chat Completions transport pointed at MiniMax's global (`api.minimax.io`) and mainland-China (`api.minimaxi.com`) hosts; the region is just the default base URL and is overridable with `MINIMAX_BASE_URL`. Both require `MINIMAX_API_KEY` (sent as a bearer token) and default to the `MiniMax-M3` model. MiniMax also publishes an Anthropic-compatible Messages endpoint — reach it with `BUZZ_AGENT_PROVIDER=anthropic` and `ANTHROPIC_BASE_URL=https://api.minimax.io/anthropic` (or the `api.minimaxi.com` host for China).
+
 `provider=openai` speaks two HTTP dialects: the [Responses API](https://platform.openai.com/docs/api-reference/responses) (`/v1/responses`, required for GPT-5 / o-series tool-calling on OpenAI's own service) and the [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) (`/chat/completions`, the broadly-supported OpenAI-compatible wire format).
 
 By default (`OPENAI_COMPAT_API=auto`) the agent picks **Responses** when `OPENAI_COMPAT_BASE_URL` points at an `*.openai.com` host and **Chat Completions** everywhere else. Pin the choice explicitly with `OPENAI_COMPAT_API=chat` or `OPENAI_COMPAT_API=responses` for providers that diverge from the default (e.g. a Responses-compatible self-hosted gateway).
diff --git a/crates/buzz-agent/src/config.rs b/crates/buzz-agent/src/config.rs
index 037b67b3cb..b48e7563cd 100644
--- a/crates/buzz-agent/src/config.rs
+++ b/crates/buzz-agent/src/config.rs
@@ -660,6 +660,30 @@ pub const HANDOFF_MAX_TOOL_NAMES: usize = 20;
 const DEFAULT_SYSTEM_PROMPT: &str =
     "You are buzz-agent. Use the provided tools to act. Tool calls are your only output.";
 
+/// Default MiniMax text model when neither `BUZZ_AGENT_MODEL` nor
+/// `MINIMAX_MODEL` is set — the current flagship (1M-token context window).
+const DEFAULT_MINIMAX_MODEL: &str = "MiniMax-M3";
+/// MiniMax OpenAI-compatible base URLs. The global service and the
+/// mainland-China service share the same Chat Completions wire format and
+/// differ only by host, so the region is expressed purely as the base URL.
+const MINIMAX_GLOBAL_BASE_URL: &str = "https://api.minimax.io/v1";
+const MINIMAX_CN_BASE_URL: &str = "https://api.minimaxi.com/v1";
+
+/// Pick the default MiniMax OpenAI-compatible base URL for the requested
+/// provider spelling. `minimax-cn` (aliases `minimaxi`, `minimax_cn`) selects
+/// the mainland-China host; everything else — including the bare `minimax` —
+/// selects the global host. Always overridable with `MINIMAX_BASE_URL`.
+fn minimax_default_base_url(requested: Option<&str>) -> &'static str {
+    match requested
+        .map(str::trim)
+        .map(str::to_ascii_lowercase)
+        .as_deref()
+    {
+        Some("minimax-cn") | Some("minimaxi") | Some("minimax_cn") => MINIMAX_CN_BASE_URL,
+        _ => MINIMAX_GLOBAL_BASE_URL,
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub enum Provider {
     Anthropic,
@@ -671,6 +695,13 @@ pub enum Provider {
     /// Databricks AI Gateway v2. Routes by model family through the gateway's
     /// OpenAI Responses, Anthropic Messages, or MLflow Chat Completions paths.
     DatabricksV2,
+    /// MiniMax hosted models over the OpenAI-compatible Chat Completions wire.
+    /// `minimax` targets the global endpoint (`https://api.minimax.io/v1`) and
+    /// `minimax-cn` the mainland-China endpoint (`https://api.minimaxi.com/v1`);
+    /// both authenticate with a static `MINIMAX_API_KEY` bearer. The region is
+    /// carried entirely by the base URL, so the request path reuses the OpenAI
+    /// Chat Completions body builder and parser unchanged — no new wire format.
+    MiniMax,
 }
 
 /// Which OpenAI-family HTTP API to call. Set via `OPENAI_COMPAT_API`
@@ -751,8 +782,9 @@ impl Config {
     pub fn from_env() -> Result<Self, String> {
         let databricks_host = env("DATABRICKS_HOST");
         let databricks_model = env("DATABRICKS_MODEL");
+        let provider_raw = env("BUZZ_AGENT_PROVIDER");
         let provider = resolve_provider(
-            env("BUZZ_AGENT_PROVIDER").as_deref(),
+            provider_raw.as_deref(),
             env("ANTHROPIC_API_KEY").as_deref(),
             env("OPENAI_COMPAT_API_KEY").as_deref(),
         )?;
@@ -797,6 +829,22 @@ impl Config {
                 databricks_host.ok_or_else(|| "config: DATABRICKS_HOST required".to_string())?,
                 OpenAiApi::Chat, // only read by OpenAI/legacy Databricks dispatch
             ),
+            Provider::MiniMax => (
+                req("MINIMAX_API_KEY")?,
+                // MiniMax ships a documented default model (MiniMax-M3), so —
+                // unlike the OpenAI-compatible provider — a bare `minimax`
+                // selection resolves without an explicit model. An explicit
+                // BUZZ_AGENT_MODEL / MINIMAX_MODEL still wins.
+                resolve_model(buzz_agent_model.as_deref(), env("MINIMAX_MODEL").as_deref())
+                    .unwrap_or_else(|| DEFAULT_MINIMAX_MODEL.to_string()),
+                env_or(
+                    "MINIMAX_BASE_URL",
+                    minimax_default_base_url(provider_raw.as_deref()),
+                ),
+                // MiniMax exposes Chat Completions, not the Responses API — pin
+                // it so the `auto` host heuristic never routes to `/responses`.
+                OpenAiApi::Chat,
+            ),
         };
         let system_prompt = match (env("BUZZ_AGENT_SYSTEM_PROMPT"), env("BUZZ_AGENT_SYSTEM_PROMPT_FILE")) {
             (Some(_), Some(_)) => return Err(
@@ -1017,6 +1065,10 @@ fn resolve_provider(
                 ),
                 "databricks" => Ok(Provider::Databricks),
                 "databricks_v2" | "databricks-v2" => Ok(Provider::DatabricksV2),
+                // MiniMax accepts a region-selecting spelling. The API key is
+                // validated later in `from_env` (like Databricks), so the
+                // requested value alone determines the provider here.
+                "minimax" | "minimax-cn" | "minimaxi" | "minimax_cn" => Ok(Provider::MiniMax),
                 _ => Err(format!(
                     "config: BUZZ_AGENT_PROVIDER={raw} not supported"
                 )),
@@ -1282,6 +1334,55 @@ mod tests {
         assert!(err.contains("BUZZ_AGENT_PROVIDER=OpenAIish"));
     }
 
+    #[test]
+    fn resolve_provider_accepts_minimax_region_spellings() {
+        // Every accepted MiniMax spelling resolves to the one provider variant;
+        // the API key is validated later in from_env (like Databricks), so no
+        // key is needed here. Matching is case-insensitive.
+        for raw in [
+            "minimax",
+            "minimax-cn",
+            "minimaxi",
+            "minimax_cn",
+            "MiniMax",
+            "MINIMAX-CN",
+        ] {
+            assert_eq!(
+                resolve_provider(Some(raw), None, None).unwrap(),
+                Provider::MiniMax,
+                "raw={raw:?}"
+            );
+        }
+    }
+
+    #[test]
+    fn minimax_default_base_url_selects_region_by_spelling() {
+        // The bare id and any unknown/global-ish spelling map to the global
+        // host; only the explicit -cn spellings select the mainland-China host.
+        assert_eq!(
+            minimax_default_base_url(Some("minimax")),
+            "https://api.minimax.io/v1"
+        );
+        assert_eq!(
+            minimax_default_base_url(Some("  MiniMax  ")),
+            "https://api.minimax.io/v1"
+        );
+        assert_eq!(
+            minimax_default_base_url(Some("minimax-cn")),
+            "https://api.minimaxi.com/v1"
+        );
+        assert_eq!(
+            minimax_default_base_url(Some("MINIMAXI")),
+            "https://api.minimaxi.com/v1"
+        );
+        assert_eq!(
+            minimax_default_base_url(Some("minimax_cn")),
+            "https://api.minimaxi.com/v1"
+        );
+        // Absent value defaults to the global host.
+        assert_eq!(minimax_default_base_url(None), "https://api.minimax.io/v1");
+    }
+
     #[test]
     fn is_openai_host_matrix() {
         // Lookalike-safe: `api.openai.com.evil.example` and malformed URLs
diff --git a/crates/buzz-agent/src/llm.rs b/crates/buzz-agent/src/llm.rs
index f2359f9ba3..fadda4733c 100644
--- a/crates/buzz-agent/src/llm.rs
+++ b/crates/buzz-agent/src/llm.rs
@@ -146,7 +146,7 @@ impl Llm {
                     .await?;
                 parse_anthropic(v)
             }
-            Provider::OpenAi | Provider::Databricks => {
+            Provider::OpenAi | Provider::Databricks | Provider::MiniMax => {
                 self.openai_request(
                     cfg,
                     effective_model,
@@ -248,7 +248,7 @@ impl Llm {
                 });
                 Ok(parse_anthropic(self.post_anthropic(cfg, &body).await?)?.text)
             }
-            Provider::OpenAi | Provider::Databricks => {
+            Provider::OpenAi | Provider::Databricks | Provider::MiniMax => {
                 let r = self
                     .openai_request(
                         cfg,
@@ -1638,13 +1638,14 @@ where
 ///   never read for Anthropic requests (those go through `post_anthropic` with
 ///   `x-api-key`), but Llm holds one to keep the field non-`Option`.
 /// - `Provider::OpenAi`: a static source over `OPENAI_COMPAT_API_KEY`.
+/// - `Provider::MiniMax`: a static source over `MINIMAX_API_KEY`.
 /// - `Provider::Databricks`: if `DATABRICKS_TOKEN` is set, a static source.
 ///   Otherwise a `PkceOAuthTokenSource` pointed at the workspace's OIDC
 ///   discovery URL. First request without a cached token triggers a browser
 ///   flow; subsequent requests use the cache + refresh transparently.
 pub(crate) fn build_token_source(cfg: &Config) -> Result<Arc<dyn TokenSource>, AgentError> {
     match cfg.provider {
-        Provider::Anthropic | Provider::OpenAi => {
+        Provider::Anthropic | Provider::OpenAi | Provider::MiniMax => {
             Ok(Arc::new(StaticTokenSource::new(cfg.api_key.clone())))
         }
         Provider::Databricks | Provider::DatabricksV2 => {
@@ -1939,6 +1940,31 @@ mod tests {
             .collect()
     }
 
+    #[tokio::test]
+    async fn minimax_routes_over_openai_chat_completions() {
+        // MiniMax reuses the OpenAI Chat Completions wire: a MiniMax config must
+        // POST to /v1/chat/completions (never /v1/responses), echo the
+        // configured model in the request body, and parse the OpenAI-shaped
+        // response. This pins the request path for the region-agnostic transport.
+        let (base_url, captured) =
+            spawn_sequence_stub(vec![StubHttpResponse::ok(chat_response("hi from minimax"))]).await;
+        let mut config = cfg(Provider::MiniMax);
+        config.base_url = base_url;
+        let llm = Llm::new(&config).unwrap();
+
+        let reply = complete_model(&llm, &config, "MiniMax-M3").await.unwrap();
+        assert_eq!(reply.text, "hi from minimax");
+
+        let requests = captured.lock().await;
+        assert_eq!(requests.len(), 1);
+        assert_eq!(requests[0].method, "POST");
+        assert_eq!(requests[0].path, "/v1/chat/completions");
+        assert_eq!(
+            requests[0].body.as_ref().and_then(|b| b["model"].as_str()),
+            Some("MiniMax-M3")
+        );
+    }
+
     #[tokio::test]
     async fn mesh_auto_requires_two_stable_catalog_observations() {
         let (base_url, captured) = spawn_sequence_stub(vec![
