Skip to main content

Host a private daemon from an application

Start a private mecated child process when your editor or application needs the supplied server composition while owning its lifetime. For TypeScript, SDK spawn and query manage these resources for you. This guide covers the hosting contract for another language or wrapper.

Install mecated before spawning it. The parent owns its runtime directory, child process, connection, and cleanup; Mecatl's lifetime channel makes child shutdown follow parent loss.

Start a private child process​

Create an owner-only runtime directory and a pipe or connected UNIX socket pair in your parent process. Pass its read endpoint as inherited descriptor 3 to the child, keep the other endpoint open, and start mecated with these arguments. Replace <RUNTIME_DIR> with the absolute private directory:

mecated serve \
--grpc-unix-socket <RUNTIME_DIR>/mecated.sock \
--http-addr "" \
--ready-file <RUNTIME_DIR>/ready.json \
--lifetime-pipe-fd 3

--grpc-unix-socket serves gRPC without opening a TCP port. Dial the example as unix://<RUNTIME_DIR>/mecated.sock. Mecatl creates the socket owner-only, rejects unsafe parent-directory permissions, removes stale sockets, and refuses to replace a live listener. Configuring both the socket and --grpc-addr is an error. An empty --http-addr disables both HTTP/SSE and the admin listener, so it cannot be combined with --perf-mcp. Keep the full socket path within 103 bytes on macOS or 107 bytes on Linux.

--ready-file is published atomically after every listener is bound. A freshly published file means the parent can dial the daemon:

{
"schema": "mecated-ready/1",
"pid": 5821,
"transport": "unix",
"grpc_address": "<RUNTIME_DIR>/mecated.sock",
"socket_path": "<RUNTIME_DIR>/mecated.sock",
"api_major": 1,
"features": ["mcp_servers_on_create", "server_info"],
"deployment": "eu-west-1 staging"
}

Use api_major and features to check compatibility before the first RPC. The owner-only file contains no credentials and remains after shutdown, so check that pid belongs to the child you launched before trusting an existing record. If startup fails before readiness, stop waiting and report the child exit; clean up the runtime directory after the process exits.

--lifetime-pipe-fd accepts a pipe read end or a connected UNIX stream socket. Keep the other endpoint open. EOF triggers graceful shutdown and persistence. The socket, readiness-file, and lifetime-pipe flags are off by default.

--lifetime-stdin uses piped stdin for the same parent-liveness signal. A parent using Deno.Command sets stdin: "piped" and holds the writer open. Closing the writer or exiting closes the channel and triggers graceful shutdown. The daemon discards any bytes received. Regular files and terminals are rejected, and the flag cannot be combined with --lifetime-pipe-fd. The Deno SDK integration manages this channel for you.

Add MCP servers per session​

Clients can add per-session MCP servers only when mecated uses a UNIX socket and HTTP is disabled:

Listener topologymcp_servers
--grpc-unix-socket and --http-addr ""accepted
Anything else, including loopback TCPrefused with UNIMPLEMENTED / HTTP 501 and client_mcp_unsupported

Clients can check for mcp_servers_on_create through GetCompatibilityInfo. The general HTTP compatibility endpoint is GET /v1/compatibility, but HTTP is disabled in this private topology. Per-session entries support streaming HTTP without redirects. Server names must use 1-64 characters from [A-Za-z0-9._-], cannot contain __, and must be unique. Put credentials in headers; Mecatl redacts them and rejects URLs containing user information.

If any requested server is unreachable, session creation fails atomically with client_mcp_unreachable and no session is created.

Next steps​