A Python package for converting agent configuration files between Gemini, OpenCode, Qwen, Kilo, Nanobot, Hermes, LiteLLM ConfigMap, and Mistral Vibe formats.
- Overview
- Supported Formats
- Requirements
- Installation
- Quick Start
- Command Line Options
- Usage Examples
- Conversion Matrix
- Format Specifications
- Nanobot, Hermes, ConfigMap & Vibe Details
- Package Structure
- Troubleshooting
This package converts configuration files between eight popular agent frameworks:
| Format | File Example | Primary Use |
|---|---|---|
| Gemini | gemini_settings.json |
Gemini AI agent configurations |
| OpenCode | opencode.json |
OpenCode.ai configurations |
| Qwen | settings.json |
Qwen Code configurations |
| Kilo | kilo.json |
Kilo (OpenCode variant with permissions) |
| Nanobot | nanobot_config.json |
Nanobot agent configurations |
| Hermes | hermes_config.yaml |
Hermes agent configurations |
| ConfigMap | config.yaml |
LiteLLM Kubernetes ConfigMap (models only) |
| Vibe | config.toml |
Mistral Vibe Code CLI configurations |
The converter supports:
- Full file conversion - Convert entire configuration files
- Section-specific conversion - Convert only MCP servers or models
- Item-specific conversion - Convert a single MCP server or model
- Auto-detection - Automatically detect source format
- Diff mode - Compare two files to find missing items
Note: Nanobot, Hermes, ConfigMap, and Vibe conversions are one-way only (from other formats → Nanobot/Hermes/ConfigMap/Vibe). Conversions from these formats to other formats are not supported.
All formats support MCP (Model Context Protocol) servers with the following mappings:
| Format | MCP Location | Command Format | Environment |
|---|---|---|---|
| Gemini | mcpServers |
command (string) + args (array) |
env (object) |
| OpenCode | mcp |
command (array, combined) |
environment (object) |
| Qwen | mcpServers |
command (string) + args (array) |
env (object) |
| Kilo | mcp |
command (array, combined) |
environment (object) |
| Nanobot | tools.mcpServers |
command (string) + args (array) |
env (object) |
| Hermes | tools.mcpServers |
List of server names only | N/A |
| Vibe | mcp_servers |
command (string) + args (array) |
env (object) |
| Format | Models Location | Notes |
|---|---|---|
| Gemini | (none) | No models section |
| OpenCode | provider.<name>.models |
Nested under providers |
| Qwen | modelProviders.<provider>[] |
Array per provider |
| Kilo | provider.<name>.models |
Same as OpenCode |
| Nanobot | providers + agents.defaults |
Simplified provider config |
| Hermes | model.default + provider |
Single default model |
| Vibe | providers + models |
Custom providers and models list |
- Python 3.10+ (uses type hints with
str | Nonesyntax) - No external dependencies (uses only Python standard library)
- Clone or copy the repository:
cd /gorgon/ia/agentconverter- Make the script executable (optional):
chmod +x agent_converter.py- Verify Python version:
python3 --version # Should show Python 3.10 or higherYou can also run the package as a Python module:
python3 -m agent_converter -i input.json -t qwen# Convert Gemini to Qwen
python3 agent_converter.py -i gemini_settings.json -o output.json -t qwen
# Convert OpenCode to Nanobot
python3 agent_converter.py -i opencode.json -o nanobot_output.json -t nanobot
# Convert Qwen to Hermes
python3 agent_converter.py -i settings.json -o hermes_output.json -t hermes -s qwenThe source format is auto-detected by default. Use -s to specify explicitly.
# Any format → Nanobot (MCP + models)
python3 agent_converter.py -i opencode.json -t nanobot --stdout
# Any format → Hermes (MCP + models)
python3 agent_converter.py -i settings.json -t hermes --stdout -s qwen
# Any format → Vibe (MCP + models)
python3 agent_converter.py -i settings.json -t vibe --stdout -s qwenusage: agent_converter.py [-h] -i INPUT -o OUTPUT -t {gemini,opencode,qwen,kilo,nanobot,hermes,configmappo,vibe}
[-s {gemini,opencode,qwen,kilo,nanobot,hermes,configmappo,auto}]
[--section {mcp,models}] [--mcp MCP] [--model MODEL] [--stdout]
Options:
-i, --input INPUT Input configuration file path (required)
-o, --output OUTPUT Output file path (optional - defaults to stdout)
-t, --target TARGET Target format: gemini, opencode, qwen, kilo, nanobot, hermes, configmappo, or vibe
-s, --source SOURCE Source format: auto-detect or explicitly specify
--section SECTION Convert only a specific section: mcp or models
--mcp MCP Convert only a specific MCP server by name
--model MODEL Convert only models matching this model ID
--stdout Output to stdout (default behavior)
--target-input FILE For diff mode: second input file to compare against
--diff Enable diff mode: compare source with target file
-h, --help Show help message
When --diff is used with --target-input, the script compares two files of the same format and outputs the full missing sections (MCP servers and/or models) that exist in the source but not in the target.
Output is to stdout by default - use -o to write to a file.
Note: Diff mode is not supported for Nanobot, Hermes, ConfigMap, and Vibe as they are one-way target formats only.
python3 agent_converter.py -i gemini_settings.json -o qwen_output.json -t qwenpython3 agent_converter.py -i config.json -o output.json -t opencode -s qwenpython3 agent_converter.py -i opencode.json -o nanobot_config.json -t nanobotpython3 agent_converter.py -i settings.json -o hermes_config.json -t hermes -s qwenConvert only the MCP servers section:
python3 agent_converter.py -i gemini_settings.json -o mcp_only.json -t opencode --section mcpConvert MCP to Nanobot:
python3 agent_converter.py -i opencode.json -o nanobot_mcp.json -t nanobot --section mcpConvert MCP to Hermes:
python3 agent_converter.py -i settings.json -o hermes_mcp.json -t hermes --section mcp -s qwenConvert only a specific MCP server:
# Convert only the 'terraform' server from Gemini to Qwen
python3 agent_converter.py -i gemini_settings.json -o terraform.json -t qwen --mcp terraform
# Convert only 'mcp-camsnap' from OpenCode to Nanobot
python3 agent_converter.py -i opencode.json -o nanobot_camsnap.json -t nanobot --mcp mcp-camsnapConvert only models matching a specific ID:
# Convert only 'qwen3:14b' model from OpenCode to Qwen
python3 agent_converter.py -i opencode.json -o qwen3_model.json -t qwen --model qwen3:14b
# Convert models containing 'ollama' from Qwen to Hermes
python3 agent_converter.py -i settings.json -o hermes_ollama.json -t hermes -s qwen --model ollama
# Convert models to LiteLLM ConfigMap (YAML output)
python3 agent_converter.py -i opencode.json -o config.yaml -t configmappo --section models# Output conversion result to stdout
python3 agent_converter.py -i gemini_settings.json -t nanobot --stdoutCompare two files of the same format to find and output missing MCP servers or models:
# Compare two OpenCode files (outputs to stdout)
python3 agent_converter.py -i opencode.json --target-input opencode_backup.json --diff
# Compare two Qwen files and save to file
python3 agent_converter.py -i settings.json --target-input settings_old.json --diff -o missing.json -s qwenOutput format: JSON containing the full missing sections in the source format.
Empty output ({}) means all source items exist in the target.
Note: Gemini format has no models section, so only MCP servers will be compared for Gemini files.
Convert all common format combinations:
# Gemini → Qwen
python3 agent_converter.py -i gemini_settings.json -o to_qwen.json -t qwen
# Gemini → Nanobot
python3 agent_converter.py -i gemini_settings.json -o to_nanobot.json -t nanobot
# OpenCode → Hermes
python3 agent_converter.py -i opencode.json -o to_hermes.json -t hermes
# Qwen → Nanobot
python3 agent_converter.py -i settings.json -o to_nanobot.json -t nanobot -s qwen
# Kilo → Nanobot
python3 agent_converter.py -i kilo.json -o to_nanobot.json -t nanobot -s kilo| From → To | Gemini | OpenCode | Qwen | Kilo | Nanobot | Hermes | Vibe |
|---|---|---|---|---|---|---|---|
| Gemini | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| OpenCode | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Qwen | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Kilo | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Nanobot | ✗ | ✗ | ✗ | ✗ | - | - | ✗ |
| Hermes | ✗ | ✗ | ✗ | ✗ | - | - | ✗ |
| Vibe | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - |
✓ = Supported conversion ✗ = Not supported (one-way target only) - = Same format (no conversion needed)
| From → To | Gemini | OpenCode | Qwen | Kilo | Nanobot | Hermes | Vibe |
|---|---|---|---|---|---|---|---|
| Gemini | N/A | ✓ (empty) | ✓ (empty) | ✓ (empty) | ✓ (empty) | ✓ (empty) | ✓ (empty) |
| OpenCode | ✓ (empty) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Qwen | ✓ (empty) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Kilo | ✓ (empty) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Nanobot | ✗ | ✗ | ✗ | ✗ | - | - | ✗ |
| Hermes | ✗ | ✗ | ✗ | ✗ | - | - | ✗ |
| Vibe | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | - |
Note:
- Gemini format does not have a models section. Conversions to Gemini for models will produce empty results.
- Nanobot, Hermes, ConfigMap, and Vibe are one-way target formats only - you cannot convert FROM them to other formats.
{
"mcpServers": {
"server-name": {
"command": "/path/to/command",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
},
"security": {
"auth": {
"selectedType": "oauth-personal"
}
},
"ui": {
"theme": "ANSI"
},
"general": {
"sessionRetention": {
"enabled": true,
"maxAge": "30d"
}
}
}Key characteristics:
- MCP servers use
command(string) +args(array) - Environment variables in
envobject - No models section
- Server names can have
_disabledsuffix
{
"$schema": "https://opencode.ai/config.json",
"autoupdate": true,
"mcp": {
"server-name": {
"command": ["/path/to/command", "arg1", "arg2"],
"type": "local",
"environment": {
"ENV_VAR": "value"
}
}
},
"provider": {
"provider-name": {
"name": "Provider Display Name",
"npm": "@ai-sdk/openai-compatible",
"options": {
"baseURL": "http://localhost:11434/v1"
},
"models": {
"model-id": {
"name": "Model Display Name",
"modalities": {
"input": ["text", "image"],
"output": ["text"]
}
}
}
}
}
}Key characteristics:
- MCP uses
commandas array (command + args combined) - Environment in
environmentobject - Models nested under
provider.<name>.models - Uses
baseURL(camelCase)
{
"$version": 3,
"env": {
"API_KEY_NAME": "default-value"
},
"mcpServers": {
"server-name": {
"command": "/path/to/command",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
},
"modelProviders": {
"openai": [
{
"id": "model-id",
"name": "Model Display Name",
"envKey": "API_KEY_NAME",
"baseUrl": "http://localhost:11434/v1",
"generationConfig": {
"modalities": {
"image": true
}
}
}
]
},
"model": {
"name": "selected-model-id"
},
"security": {
"auth": {
"selectedType": "openai"
}
}
}Key characteristics:
- MCP uses
command(string) +args(array) - Global
envsection for API keys - Models as array under
modelProviders.<provider> - Uses
baseUrl(camelCase) - Image modalities as boolean in
generationConfig
Kilo format is identical to OpenCode but includes a permission section:
{
"$schema": "https://opencode.ai/config.json",
"autoupdate": true,
"permission": {
"bash": "allow"
},
"mcp": { ... },
"provider": { ... }
}{
"agents": {
"defaults": {
"workspace": "~/.nanobot/workspace",
"model": "provider/default",
"maxTokens": 110000,
"temperature": 0.7,
"maxToolIterations": 20,
"memoryWindow": 50
}
},
"providers": {
"provider-name": {
"apiKey": "",
"apiBase": "http://localhost:11434/v1",
"extraHeaders": null
}
},
"tools": {
"mcpServers": {
"server-name": {
"command": "/path/to/command",
"args": ["arg1", "arg2"],
"env": {
"ENV_VAR": "value"
}
}
}
},
"gateway": {
"host": "0.0.0.0",
"port": 18790
}
}Conversion output includes:
tools.mcpServers- MCP servers from sourceproviders- Simplified provider configuration (apiKey, apiBase, extraHeaders)agents.defaults- Default agent settings with first provider as model
Note: API keys are set to empty strings - you must fill them in manually.
model:
default: provider/model-id
provider: provider-name
toolsets:
- all
agent:
max_turns: 60
verbose: false
reasoning_effort: medium
tools:
mcpServers:
- server-name-1
- server-name-2Conversion output includes:
tools.mcpServers- List of MCP server names (not full config)model.default- First available model from sourceprovider- Provider nametoolsets- Set to["all"]agent- Default agent settings
Note: Hermes MCP format is a simple list of server names, not full server configurations.
default_agent = "plan"
active_model = "devstral-openrouter"
enable_auto_update = true
[[providers]]
name = "openrouter"
api_base = "https://openrouter.ai/api/v1"
api_key_env_var = "OPENROUTER_API_KEY"
api_style = "openai"
backend = "generic"
[[models]]
name = "mistralai/devstral-2512:free"
provider = "openrouter"
alias = "devstral-openrouter"
[[mcp_servers]]
name = "my-mcp-server"
transport = "stdio"
command = "npx"
args = ["-y", "@example/mcp-server@latest"]
env = {KEY = "value"}Conversion output includes:
default_agent- Defaults to"plan"active_model- Defaults to the first converted model aliasenable_auto_update- Preserves auto-update preference from source formats (mapped fromautoupdateorgeneral.enable_auto_update)[[providers]]- Provider configuration withapi_base, generatedapi_key_env_varname,api_style = "openai", andbackend = "generic"[[models]]- List of custom models matching the providers[[mcp_servers]]- List of MCP server configurations (with command, args, and env variables)
Nanobot, Hermes, ConfigMap, and Vibe are target-only formats. You can convert FROM any format TO these targets, but NOT the reverse.
Supported conversions:
- Gemini → Nanobot ✓
- Gemini → Hermes ✓
- Gemini → Vibe ✓
- OpenCode → Nanobot ✓
- OpenCode → Hermes ✓
- OpenCode → Vibe ✓
- Qwen → Nanobot ✓
- Qwen → Hermes ✓
- Qwen → Vibe ✓
- Kilo → Nanobot ✓
- Kilo → Hermes ✓
- Kilo → Vibe ✓
Not supported:
- Nanobot → Any format ✗
- Hermes → Any format ✗
- Vibe → Any format ✗
| Feature | Nanobot | Hermes | Vibe |
|---|---|---|---|
| Format | Full server config (command, args, env) | Simple list of server names | Full server config (command, args, env) |
| Environment | Preserved | Not applicable | Preserved |
| Use case | Direct config migration | Enable/disable server list | Direct config migration |
| Feature | Nanobot | Hermes | Vibe |
|---|---|---|---|
| Format | providers dict + agents.defaults |
model.default + provider string |
providers list + models list |
| Multiple providers | All preserved | First model used as default | All preserved |
| API keys | Empty placeholders | Not included | API key env var generated |
The code is organized as a modular Python package:
agent_converter/
├── __init__.py # Package initialization
├── __main__.py # Entry point for `python -m agent_converter`
├── cli.py # CLI argument parsing and main entry point
├── conversion_orchestrator.py # Main conversion logic
├── diff.py # Diff comparison functions
├── format_detection.py # Format detection utilities
├── utils.py # File I/O and helper functions
├── mcp_converters/ # MCP format converters
│ ├── __init__.py
│ ├── gemini.py
│ ├── opencode.py
│ ├── qwen.py
│ ├── kilo.py
│ ├── nanobot.py
│ ├── hermes.py
│ └── vibe.py
└── model_converters/ # Model format converters
├── __init__.py
├── gemini.py
├── opencode.py
├── qwen.py
├── kilo.py
├── nanobot.py
├── hermes.py
└── vibe.py
Each format has its own converter module, making it easy to:
- Add support for new formats
- Test individual converters
- Maintain format-specific logic
Solution: Use -s to explicitly specify the source format:
python3 agent_converter.py -i config.json -o output.json -t nanobot -s opencodeSolution: Verify the input file path is correct:
ls -la gemini_settings.jsonExpected behavior: Gemini format has no models section. This is normal.
Check: Ensure the source file has the correct structure. Use --section mcp if needed.
Solution: Ensure you're using a valid target: gemini, opencode, qwen, kilo, nanobot, hermes, configmappo, or vibe.
- Check detected format:
python3 agent_converter.py -i config.json -t qwen 2>&1 | grep "Detected"- Preview conversion to stdout:
python3 agent_converter.py -i config.json -t nanobot --stdout | head -50- Convert specific items to verify:
python3 agent_converter.py -i config.json -t hermes --mcp terraform --stdout# Full conversion
python3 agent_converter.py -i ~/.gemini/gemini_settings.json -o ~/.nanobot/config.json -t nanobot
# Verify the output
cat ~/.nanobot/config.json# Get only MCP servers from OpenCode in Hermes format
python3 agent_converter.py -i opencode.json -o hermes_mcp.json -t hermes --section mcp# Convert only specific servers
python3 agent_converter.py -i gemini_settings.json -o minimal_nanobot.json -t nanobot --mcp terraform# Extract models from Qwen config for Hermes
python3 agent_converter.py -i settings.json -o hermes_models.json -t hermes --section models -s qwenThis script is provided as-is for converting between agent configuration formats.
Created for converting between Gemini, OpenCode, Qwen, Kilo, Nanobot, Hermes, LiteLLM ConfigMap, and Mistral Vibe agent configurations.