MiniMax M3.1 Flash OpenCode Guide: Setup and Tool Calls
A tested OpenCode v2.2.3 setup for MiniMax M3.1 Flash, with the exact provider config, a real tool-call trace and the errors that break continuation.
On this page
- What you need before you start
- The tested OpenCode V2 config
- Run it with the key in the server's shell
- Verify the read, write and test loop
- Set effort, context and output deliberately
- Fix key, model ID and continuation errors
- Costs, permissions and next steps
- Frequently asked questions
- Is this config compatible with OpenCode V1?
- Does opencode --standalone models need a provider filter?
- Can I send images or PDFs to this model through OmniaKey?
- Can I raise max_tokens above 4096?
- Sources checked
MiniMax M3.1 Flash works in OpenCode v2.2.3 through a custom OpenAI-compatible provider. The exact OpenCode model string is omniakey/minimax-m3.1-flash, the base URL is https://api.omniakey.com/v1, and the configuration below completed a real repository task: five reads, one write, one node --test run, and 12 of 12 tests passing on November 12, 2026.
OpenCode sends the OpenAI Chat Completions format to a custom provider, and OmniaKey serves that format at /v1. The setup is one project file, but three details decide whether it works: the model ID must match OmniaKey's spelling, the key must be visible to the OpenCode server process, and the provider config must preserve the model's reasoning field across tool calls.
What you need before you start
Use OpenCode V2. The tested version was v2.2.3. V2 puts custom providers under a top-level providers object; older V1 examples use a different shape, so check the V2 provider docs and opencode --version before copying this config.
- OpenCode: v2.2.3, tested on November 12, 2026.
- OmniaKey model ID:
minimax-m3.1-flash. - OpenCode model reference:
omniakey/minimax-m3.1-flash.
Create an OmniaKey key and put it in OMNIAKEY_API_KEY. The JSON below names that variable and never contains the secret. Pick a small repository with an existing test command; the test run used a Node fixture with src/normalize.js, a test file and a test script.
MiniMax's own API uses the mixed-case ID MiniMax-M3.1-Flash. OmniaKey uses lower-case minimax-m3.1-flash. Use the lower-case form in both places; a different case will not match the ID.
If you are still choosing a model, the MiniMax M3.1 Flash review covers its benchmarks, launch details and always-on thinking.
The tested OpenCode V2 config
Place this at the project root as opencode.jsonc. It is the public form of the config used in the run.
{
"$schema": "https://opencode.ai/config.json",
"model": "omniakey/minimax-m3.1-flash",
"share": "disabled",
"update": "disable",
"warming": false,
"snapshots": false,
"enabled_providers": ["omniakey"],
"providers": {
"omniakey": {
"name": "OmniaKey",
"env": ["OMNIAKEY_API_KEY"],
"package": "@opencode/ai/providers/openai-compatible",
"settings": {
"baseURL": "https://api.omniakey.com/v1"
},
"models": {
"minimax-m3.1-flash": {
"modelID": "minimax-m3.1-flash",
"name": "MiniMax M3.1 Flash",
"body": {
"reasoning_effort": "medium",
"max_tokens": 4096,
"stream_options": {"include_usage": true}
},
"limit": {
"context": 1000000,
"output": 4096
},
"capabilities": {
"tools": true,
"input": ["text"],
"output": ["text"],
"freeform": [],
"reasoning": {
"supported": true,
"effort": ["low", "medium", "high", "xhigh", "max"]
}
},
"compatibility": {
"reasoningField": "reasoning_content",
"requireReasoning": true,
"maxTokensField": "max_tokens"
}
}
}
}
},
"permissions": [
{"action": "*", "resource": "*", "effect": "deny"},
{"action": "read", "resource": "*", "effect": "allow"},
{"action": "glob", "resource": "*", "effect": "allow"},
{"action": "grep", "resource": "*", "effect": "allow"},
{"action": "edit", "resource": "src/normalize.js", "effect": "allow"},
{"action": "shell", "resource": "node --test", "effect": "allow"},
{"action": "shell", "resource": "git diff *", "effect": "allow"},
{"action": "external_directory", "resource": "*", "effect": "deny"}
]
}
The env array tells OpenCode which credential variable to read: OMNIAKEY_API_KEY comes from the server process environment. The modelID is the ID sent to OmniaKey, while the models map key is the ID OpenCode uses in provider/model references; keeping both as minimax-m3.1-flash avoids an ambiguous lookup.
The limit and capability blocks replace OpenCode's fallback assumptions for an unknown model. OpenCode otherwise assumes a 200,000-token context and image input. OmniaKey's model page lists a 1M-token context for this model and no vision entry, so the config sets the context limit to 1000000 and input to text. The 1M figure is the published window, not a size this small task exercised.
The body block holds the two values this run tested: medium reasoning effort and a 4096 max_tokens cap. The effort list in capabilities is the set MiniMax's guide describes; medium is the value the test used.
The permissions block is deliberately narrow for the demo repo. It denies everything, then allows read, glob and grep, an edit to src/normalize.js, the node --test command, and git diff. It also denies external directories. Replace the file path and commands with your own project's rules. A blanket edit or shell allow gives the agent far more access than a bounded task needs.
Run it with the key in the server's shell
OpenCode normally starts or finds one shared background server. That server holds sessions, configuration and tool execution, and it reads the provider's env variables from its own process environment. A key exported in a different terminal does not reach it. The OpenCode CLI docs describe the shared server and the --standalone flag.
For a predictable first run, use a private server from a shell that has the key:
export OMNIAKEY_API_KEY="your-omniakey-api-key"
opencode --standalone models
The tested models command takes no provider argument. It lists omniakey/minimax-m3.1-flash. Then run one task. The tested run used this model argument and the prompt block below; replace the clearly marked placeholder with that exact text:
# Replace <task prompt> with the text from the prompt block below.
opencode --standalone run --model omniakey/minimax-m3.1-flash '<task prompt>'
The --standalone flag starts a private server from that shell, so the server inherits the key and reads the project config. A shared server started earlier reads only its own environment. The key line above is a placeholder; the config file still contains no secret.
If you already run the shared server from an environment that has OMNIAKEY_API_KEY, you can use it instead. The private server is the reproducible path when that environment is unclear.
Verify the read, write and test loop
A small Node fixture is enough to see whether tool calling works. The fixture had src/normalize.js with a sort-only stub, a test file with 12 cases, and a node --test script. Before the fix, 3 tests passed and 9 failed.
This is the prompt used in the run, verbatim:
Fix src/normalize.js in this small JavaScript repository. Read the source and existing tests, then implement normalizeIntervals: accept valid half-open numeric intervals [start,end], drop empty intervals, sort them, and merge overlapping or touching ranges. Return fresh arrays without mutating the input. Do not change tests or configuration. Run `node --test` and summarize the result. Work only in this repository; do not read any credentials, network resources or files outside it. Use at most 8 tool calls.
The run produced seven tool operations across six HTTP requests, all of which returned 200:
| Tool | Count | What it covered |
|---|---|---|
read | 5 | Repo listing, source, test directory, package.json, test file |
write | 1 | src/normalize.js |
shell | 1 | node --test |
The first turn sent two reads in parallel, one for the repository listing and one for the source. The next two turns read the test directory, the package file and the test file. The write replaced the source. The shell call ran the tests. The run took 70.172 seconds end to end.
The test call inside the loop reported:
ℹ tests 12
ℹ suites 0
ℹ pass 12
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 52.316459
The final answer named the changed file and the 12/12 result. The six usage blocks add up to 20,739 input tokens, including cached prefix reads, and 803 output tokens. The largest completion was 363 tokens, so the 4096 cap was never reached.
A local forwarding process sent the request body and streamed response to OmniaKey unchanged. This is one small task. It shows the read, write and test loop works on this repository; it is not a broad speed or code-quality benchmark.
Set effort, context and output deliberately
Thinking is mandatory on M3.1 Flash. MiniMax's text-generation guide says the model always thinks, and its OpenAI-compatible API reference returns HTTP 400 if a client sends thinking: {"type": "disabled"} or reasoning_effort: "none". Leave thinking on and lower the effort when you want a shorter turn.
| Setting | Tested value | What it controls |
|---|---|---|
reasoning_effort | medium | How much the model thinks before answering |
max_tokens | 4096 | Client output cap for one call |
limit.context | 1000000 | Advertised context window |
reasoning_effort accepts low, medium, high, xhigh and max; when omitted, MiniMax's guide says the default is max. Medium was enough for this bounded task. Lower effort shortens the thinking, but it does not switch thinking off.
Sampling controls do nothing on this model. MiniMax's API reference says M3.1 Flash always uses 1 and 0.95, so removing temperature and top_p is cleaner than tuning values that are ignored.
The 1M-token context comes from OmniaKey's model page and MiniMax's guide. The 4096 output limit is a client safety cap chosen for this run, not a published provider maximum. Thinking tokens count toward that cap, so a long reasoning turn can end with finish_reason: "length" and little or no final text. Lower effort first, then raise the cap if the task needs more room.
Fix key, model ID and continuation errors
The successful run produced no errors. This checklist follows the linked OpenCode and MiniMax documentation. The exact base URL is https://api.omniakey.com/v1.
| Symptom | Check | Fix |
|---|---|---|
401 or 403 | Is OMNIAKEY_API_KEY in the server's environment? | Export it in the shell that starts OpenCode, or use --standalone; keep the key out of JSON. |
Model unavailable or model-not-found | Do the map key and modelID both read minimax-m3.1-flash? | Fix spelling and case; do not use the upstream MiniMax-M3.1-Flash ID; confirm the provider is enabled. |
404 from the gateway | Is settings.baseURL exactly the OmniaKey endpoint? | Set it to the exact Base URL shown above; remove any extra path. |
400 about adaptive thinking | Did a client send disabled thinking or reasoning_effort: "none"? | Remove it and lower effort instead. |
| Stops after the first tool call | Is the reasoning field set? Does the history include it? | Set reasoningField to "reasoning_content" and retry the same prompt. |
Empty content, finish_reason: "length" | Is thinking using the output cap? | Lower effort first, then raise max_tokens. |
| Context error on a 300K prompt | Is OpenCode still using its 200K fallback? | Set limit.context to 1000000 and trim the prompt. |
| Image or PDF input fails | Does the OmniaKey page list vision? | Send text only and convert the file first. |
Continuation can fail in the config even when it looks like a model problem. MiniMax's API reference requires clients to append the complete assistant response, including tool_calls and the thinking returned in reasoning_content, to later turns. OpenCode's reasoning-field setting reads that field from the stream and restores it when it sends history back.
In this run, every follow-up request carried the reasoning_content field on the assistant tool-call messages, all six requests completed, and each tool result fed the next turn.
Costs, permissions and next steps
OmniaKey bills per token at the current rates on the model page. The six calls here used 20,739 input tokens, including cached prefix reads, and 803 output tokens. To estimate a similar task, split the usage into uncached input, cache-read input and output, then multiply each by its matching current rate. The input total alone does not map to a single rate.
For your own repository, start from the deny-all rule and add only the folders and commands the task needs. Keep the edit permission on the files the task changes, and keep the shell permission on the test command. That is the part of the config to rewrite per project; the provider and model blocks can stay as they are.
The same key and base-URL pattern applies to other clients; OmniaKey's coding-tool setup guide covers Claude Code, and the coding agents docs list the per-tool steps.
Frequently asked questions
Is this config compatible with OpenCode V1?
The tested version is OpenCode v2.2.3, and the config uses V2's plural providers object. V1 pages use a different shape, so check the version before copying it into an older install.
Does opencode --standalone models need a provider filter?
No. The tested command is exactly opencode --standalone models, with no positional provider argument. It lists omniakey/minimax-m3.1-flash.
Can I send images or PDFs to this model through OmniaKey?
OmniaKey's model page lists no vision entry, and the tested config declares text input only. Send text and convert images or PDFs first. MiniMax's upstream model accepts images, but that does not add an image input to this OmniaKey model page.
Can I raise max_tokens above 4096?
Yes, you can raise the client cap. 4096 was the tested value, and the current pages do not state a hard maximum for this model. Thinking counts toward it, so watch for a length stop or empty content; lower effort first, then raise the cap.
Sources checked
- OpenCode providers — checked November 12, 2026
- OpenCode models — checked November 12, 2026
- OpenCode CLI — checked November 12, 2026
- MiniMax text generation guide — checked November 12, 2026
- MiniMax OpenAI-compatible API reference — checked November 12, 2026
- OmniaKey: MiniMax M3.1 Flash — checked November 12, 2026
Models in this article
Related articles
MiniMax M3.1 Flash Review: Benchmarks, Speed and How It Compares to M3
Half M3's price per token and a higher index score, but it always thinks. We ran both side by side on five calls.
Best LLM for Coding Agents in 2026: Claude vs GPT vs Gemini
There's no single best coding model — Claude, GPT, and Gemini each win a different axis. How they compare on tool use, context, and cost, and why routing beats picking just one.
Use Claude Code with OmniaKey
Point Claude Code at OmniaKey's Anthropic-native endpoint — two environment variables, Claude models that are never silently swapped, billing per token with no monthly plan.