MCM API
The MCM (mimik Compute Manager) API provides capabilities for deploying and managing mims on mimOE.
Base URL
http://localhost:8083/mcm/v1
Authentication
MCM supports two authentication methods. The MCM API key is the simplest option and works without any signup or account association.
MCM API Key (Recommended)
Pass the MCM_API_KEY as a bearer token:
Authorization: Bearer <MCM_API_KEY>
The MCM API key is found in the API key file (mimoe-api-key.env) in your working directory. mimOE auto-generates this file on first startup. See API Key File for details.
# Example: list images using the MCM API key
curl -X GET "http://localhost:8083/mcm/v1/images" \
-H "Authorization: Bearer $(grep MCM_API_KEY mimoe-api-key.env | cut -d= -f2)"
JWT Access Token (Alternative)
A JWT access token with the edge:mcm scope also works. This is used by clients that have completed Account Association.
Authorization: Bearer <access_token>
If the bearer token does not match the MCM API key, mimOE falls back to JWT verification with edge:mcm scope. If both fail, the request is rejected with HTTP 403.
API Key File
mimOE uses an API key file to secure its APIs. The file is auto-generated on first startup and contains two keys:
| Key | Purpose |
|---|---|
ACCOUNT_API_KEY | Protects the Account Association API (JSON-RPC) |
MCM_API_KEY | Protects the MCM API (this page) |
File location: <workDir>/mimoe-api-key.env
# mimOE API Keys
ACCOUNT_API_KEY=abc123def456
MCM_API_KEY=xyz789ghi012
The file is generated automatically if it does not exist. Keys persist across restarts. The file path is logged at startup:
[2026-01-28 08:01:05.902Z] [info] API key file: ./mimoe-api-key.env
You can provide your own key file with the --api-key-file flag:
mimoe --api-key-file /path/to/my-keys.env --work-dir /path/to/workdir
Client ID
Every MCM operation is scoped to a client ID. When using API key authentication, the client ID defaults to "api". You can override it with the x-client-id header.
| Auth Method | x-client-id Header | Resolved Client ID |
|---|---|---|
| MCM API key | not set | "api" |
| MCM API key | my-app | my-app |
| JWT | (ignored) | JWT client_id claim |
# Use default client ID ("api")
curl -X GET "http://localhost:8083/mcm/v1/images" \
-H "Authorization: Bearer $MCM_API_KEY"
# Override client ID
curl -X GET "http://localhost:8083/mcm/v1/images" \
-H "Authorization: Bearer $MCM_API_KEY" \
-H "x-client-id: my-app"
When authenticated via JWT, the client_id claim from the token always determines the client ID. The x-client-id header is ignored.
Quick Reference
Endpoints
| Images | mims | Other |
|---|---|---|
| List Images | List mims | Deploy Composition |
| Upload Image | Deploy mim | |
| Delete Image | Delete mim | |
| Download Tarball | Backup/Restore DataStore |
Response Objects
mim Image Object | mim Object | Environment Variables | DataStore Status
Endpoints
List Images
Retrieve all mim images stored on this node.
Request
GET /images
Response (200 OK)
{
"data": [
{
"id": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a-my-agent-v1",
"name": "my-agent-v1",
"digest": "sha256:2fa55f5c1fc0ce890c4b8642ae1e0404e3ab19213b77a1d4d88f75804a4a18e2",
"repoTags": ["my-agent-v1:latest"],
"created": 1505947350,
"size": 170480
}
]
}
See mim Image Object for field descriptions.
Example
- cURL
- JavaScript
- Python
curl -X GET "http://localhost:8083/mcm/v1/images" \
-H "Authorization: Bearer $MCM_API_KEY"
const response = await fetch('http://localhost:8083/mcm/v1/images', {
headers: { 'Authorization': `Bearer ${mcmApiKey}` }
});
const { data: images } = await response.json();
import requests
response = requests.get(
"http://localhost:8083/mcm/v1/images",
headers={"Authorization": f"Bearer {mcm_api_key}"}
)
images = response.json()["data"]
Upload Image
Upload a mim image (tar file) to the node.
Request
POST /images
Headers
| Header | Value |
|---|---|
Content-Type | multipart/form-data |
Form Data
| Field | Type | Required | Description |
|---|---|---|---|
image | file | Yes | mim image tar file |
Response (200 OK)
{
"id": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a-my-agent-v1",
"name": "my-agent-v1",
"digest": "sha256:2fa55f5c1fc0ce890c4b8642ae1e0404e3ab19213b77a1d4d88f75804a4a18e2",
"repoTags": ["my-agent-v1:latest"],
"created": 1505947350,
"size": 170480
}
See mim Image Object for field descriptions.
Error (400)
Invalid image or upload failed.
Example
- cURL
- JavaScript
- Python
curl -X POST "http://localhost:8083/mcm/v1/images" \
-H "Authorization: Bearer $MCM_API_KEY" \
-F "image=@my-agent-v1.tar"
const formData = new FormData();
formData.append('image', imageFile);
const response = await fetch('http://localhost:8083/mcm/v1/images', {
method: 'POST',
headers: { 'Authorization': `Bearer ${mcmApiKey}` },
body: formData
});
const image = await response.json();
import requests
with open('my-agent-v1.tar', 'rb') as f:
response = requests.post(
"http://localhost:8083/mcm/v1/images",
headers={"Authorization": f"Bearer {mcm_api_key}"},
files={"image": f}
)
image = response.json()
Delete Image
Remove a mim image from the node.
Request
DELETE /images/{id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Image identifier |
Response (200 OK)
Returns deleted image information.
Error (404)
Image not found.
Example
- cURL
- JavaScript
curl -X DELETE "http://localhost:8083/mcm/v1/images/$IMAGE_ID" \
-H "Authorization: Bearer $MCM_API_KEY"
const response = await fetch(`http://localhost:8083/mcm/v1/images/${imageId}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${mcmApiKey}` }
});
Download Image Tarball
Download a mim image as a tar file.
Request
GET /images/{id}/tarball?hmac={hmac_code}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Image identifier |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
hmac | string | Yes | HMAC authentication code |
Response (200 OK)
Returns tar file with Content-Type: application/tar.
Error (403)
Invalid HMAC code.
List mims
Retrieve all deployed mims on this node.
Request
GET /mims
Response (200 OK)
{
"data": [
{
"id": "abc123",
"name": "my-agent",
"image": "my-agent-v1",
"imageId": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a-my-agent-v1",
"clientId": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a",
"created": 1705947350000,
"state": "started",
"status": "up",
"env": {
"MCM.BASE_API_PATH": "/my-agent/v1"
}
}
]
}
See mim Object for field descriptions.
Example
- cURL
- JavaScript
- Python
curl -X GET "http://localhost:8083/mcm/v1/mims" \
-H "Authorization: Bearer $MCM_API_KEY"
const response = await fetch('http://localhost:8083/mcm/v1/mims', {
headers: { 'Authorization': `Bearer ${mcmApiKey}` }
});
const { data: mims } = await response.json();
import requests
response = requests.get(
"http://localhost:8083/mcm/v1/mims",
headers={"Authorization": f"Bearer {mcm_api_key}"}
)
mims = response.json()["data"]
Deploy mim
Deploy a mim instance from an uploaded image.
Request
POST /mims
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | mim instance name (no spaces) |
image | string | Yes | Image name to deploy from |
env | object | No | Environment variables |
{
"name": "my-agent",
"image": "my-agent-v1",
"env": {
"MCM.BASE_API_PATH": "/my-agent/v1",
"MCM.API_ALIAS": "true"
}
}
Response (201 Created)
{
"id": "abc123",
"name": "my-agent",
"image": "my-agent-v1",
"imageId": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a-my-agent-v1",
"clientId": "841be21b-a84b-46a5-a5b0-c5ee59f99b1a",
"created": 1705947350000,
"state": "started",
"status": "up",
"env": {
"MCM.BASE_API_PATH": "/my-agent/v1"
}
}
See mim Object and Environment Variables for details.
Error (400)
Invalid mim configuration.
Example
- cURL
- JavaScript
- Python
curl -X POST "http://localhost:8083/mcm/v1/mims" \
-H "Authorization: Bearer $MCM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-agent",
"image": "my-agent-v1",
"env": {
"MCM.BASE_API_PATH": "/my-agent/v1"
}
}'
const response = await fetch('http://localhost:8083/mcm/v1/mims', {
method: 'POST',
headers: {
'Authorization': `Bearer ${mcmApiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'my-agent',
image: 'my-agent-v1',
env: { 'MCM.BASE_API_PATH': '/my-agent/v1' }
})
});
const mim = await response.json();
import requests
response = requests.post(
"http://localhost:8083/mcm/v1/mims",
headers={
"Authorization": f"Bearer {mcm_api_key}",
"Content-Type": "application/json"
},
json={
"name": "my-agent",
"image": "my-agent-v1",
"env": {"MCM.BASE_API_PATH": "/my-agent/v1"}
}
)
mim = response.json()
Delete Mim
Remove a deployed mim from the node.
Request
DELETE /mims/{id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | mim identifier |
Response (200 OK)
Returns deleted mim information.
Error (404)
mim not found.
Example
- cURL
- JavaScript
curl -X DELETE "http://localhost:8083/mcm/v1/mims/$MIM_ID" \
-H "Authorization: Bearer $MCM_API_KEY"
const response = await fetch(`http://localhost:8083/mcm/v1/mims/${mimId}`, {
method: 'DELETE',
headers: { 'Authorization': `Bearer ${mcmApiKey}` }
});
Backup/Restore DataStore
Backup or restore a mim's persistent DataStore.
Request
POST /mims/{id}/dataStore
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | mim identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | backup or restore |
path | string | Yes | Local filesystem path for backup file |
{
"action": "backup",
"path": "/var/backups/my-agent.db"
}
Response (200 OK)
{
"action": "backup",
"status": "completed",
"message": "Backup completed successfully",
"path": "/var/backups/my-agent.db",
"percentage": 100
}
See DataStore Operation Status for status values.
Example
- cURL
- JavaScript
curl -X POST "http://localhost:8083/mcm/v1/mims/$MIM_ID/dataStore" \
-H "Authorization: Bearer $MCM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "backup", "path": "/var/backups/my-agent.db"}'
const response = await fetch(`http://localhost:8083/mcm/v1/mims/${mimId}/dataStore`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${mcmApiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'backup', path: '/var/backups/my-agent.db' })
});
const result = await response.json();
Deploy Composition
Deploy multiple mims in a single operation.
Request
POST /compositions
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
mims | array | Yes | Array of mim configurations |
{
"mims": [
{
"name": "ai-agent",
"image": "ai-agent-v1",
"env": { "MCM.BASE_API_PATH": "/ai-agent/v1" }
},
{
"name": "processor",
"image": "processor-v1",
"env": { "MCM.BASE_API_PATH": "/processor/v1" }
}
]
}
Response (201 Created)
Returns array of deployed mim information.
Example
- cURL
- JavaScript
curl -X POST "http://localhost:8083/mcm/v1/compositions" \
-H "Authorization: Bearer $MCM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mims": [
{"name": "ai-agent", "image": "ai-agent-v1", "env": {"MCM.BASE_API_PATH": "/ai-agent/v1"}}
]
}'
const response = await fetch('http://localhost:8083/mcm/v1/compositions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${mcmApiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
mims: [
{ name: 'ai-agent', image: 'ai-agent-v1', env: { 'MCM.BASE_API_PATH': '/ai-agent/v1' } }
]
})
});
const deployedMims = await response.json();
mim Image Object
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier ({client_id}-{name}) |
name | string | Image name |
digest | string | SHA256 digest |
repoTags | array | Repository tags |
created | integer | Creation time (Unix timestamp in seconds) |
size | integer | Size in bytes |
mim Object
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
name | string | Instance name |
image | string | Source image name |
imageId | string | Full image identifier |
clientId | string | Deployer's client ID |
created | integer | Creation time (Unix timestamp in milliseconds) |
state | string | Lifecycle state |
status | string | Operational status |
env | object | Environment variables |
Environment Variables
| Variable | Required | Description |
|---|---|---|
MCM.BASE_API_PATH | Yes | API endpoint path (e.g., /my-agent/v1) |
MCM.API_ALIAS | No | When true, mounts on /api endpoint |
MCM.DB_ENCRYPTION_SUPPORT | No | When true, enables database encryption |
MCM.MAX_EXECUTION_TIME_SEC | No | Maximum execution time in seconds (default: 30). mimOE terminates the mim if a request exceeds this limit. Increase for long-running operations. |
WEBSOCKET_SUPPORT | No | When true, enables WebSocket notifications |
By default, mimOE terminates any mim request that takes longer than 30 seconds. For mims that perform long-running operations such as AI inference, large file processing, or external API calls, increase MCM.MAX_EXECUTION_TIME_SEC to prevent premature termination.
"env": {
"MCM.MAX_EXECUTION_TIME_SEC": "120"
}
mim State Values
| State | Description |
|---|---|
started | mim is running |
mim Status Values
| Status | Description |
|---|---|
up | mim is operational |
DataStore Operation Status
| Status | Description |
|---|---|
completed | Operation succeeded |
failed | Operation failed |
inProgress | Operation in progress |
Addon Protection
Addon mims (pre-installed with mimOE) are protected regardless of authentication method:
- Delete protection: Addon containers cannot be deleted via the MCM API. Remove the addon folder to uninstall.
- Image protection: Images referenced by addon containers cannot be deleted.
- Env protection: Requests that include
MCM.ADDON.*environment variables are rejected, preventing regular containers from masquerading as addons.