Process Execution
Submitting code to MCI is a single POST /processes request with the code as the body. MCI creates the process, queues it, and begins execution immediately. The response carries the pid which is used for all subsequent interaction with that process.
An optional ref field can be passed to tag the process with a client-supplied identifier. This allows the client to look up processes by its own internal reference using the ref query parameter on GET /processes, useful for correlating processes back to whatever triggered them without tracking PIDs externally.
const response = await fetch("http://localhost:7687/processes", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code: extractedCode, ref: "my-internal-ref" })
})
const { pid } = await response.json()
Process Polling
Processes run asynchronously. The client tracks progress by polling GET /processes/:pid and inspecting the state and status fields. A process that has finished will have a state of idle and a non-null status indicating whether it succeeded, failed, or was canceled.
async function waitForProcess(pid: string) {
while (true) {
const res = await fetch(`http://localhost:7687/processes/${pid}`)
const process = await res.json()
if (process.state === "idle") return process
await new Promise(resolve => setTimeout(resolve, 500))
}
}
const process = await waitForProcess(pid)
if (process.status === "success") {
// proceed to fetch output
} else {
// handle failure or cancellation
}
Process Output
A completed process exposes three output channels. The primary one is output — a structured value explicitly set by the intent code. This is what gets fed back to the model. It contains exactly what the intent produced, nothing more.
const res = await fetch(`http://localhost:7687/processes/${pid}/output`)
const { output } = await res.json()
The raw process streams are also available separately, useful for debugging:
const stdout = await fetch(`http://localhost:7687/processes/${pid}/stdout`).then(r => r.text())
const stderr = await fetch(`http://localhost:7687/processes/${pid}/stderr`).then(r => r.text())
Controlling Processes
A running or queued process can be stopped at any point by sending a kill signal. The process transitions to idle with a canceled status, and its outputs are preserved up to the point of cancellation.
await fetch(`http://localhost:7687/processes/${pid}/signals/kill`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({})
})
A process in the idle state can be re-queued via the run signal. This applies to canceled processes as well as completed ones. Re-executing a process that already has outputs requires force: true to explicitly overwrite them.
await fetch(`http://localhost:7687/processes/${pid}/signals/run`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ force: true })
})
A process can be freed entirely by sending a DELETE /processes/:pid request. This removes the process and all its outputs from the server. Freeing a process that is still running or queued is not permitted — it must be killed first.
await fetch(`http://localhost:7687/processes/${pid}`, {
method: "DELETE"
})
Last modified on March 18, 2026