Skip to main content

Using the API

Everything the app's own UI can do is also reachable over three transports, all backed by the exact same MaslowService Rust methods:

  • gRPC - MachineService, JobService, ConfigService, FilesService, CalibrationService, defined in proto/maslow/v1/*.proto.
  • HTTP/JSON - a REST-ish gateway over the same operations, following an AIP-136-style convention (a :verb suffix on the resource path for actions that aren't plain CRUD, e.g. POST /v1/machines/default:jog).
  • MCP - a Model Context Protocol server so an LLM can call the same operations as tools, mounted at /mcp on the HTTP gateway.

None of the three are reachable until you enable the API and generate a key.

Enabling the API​

Both servers are off by default. In the app's Config → Settings tab:

  1. Toggle the API on.
  2. Click Generate key (or Regenerate key) to get a plaintext API key. This is the only time the plaintext key is ever shown: only its SHA-256 hash is persisted to disk, so store the key somewhere safe.
  3. Note the ports shown: HTTP defaults to 8642, gRPC to 50051. Both servers bind to 127.0.0.1 only (loopback), not to your LAN interface.

Toggling the API or regenerating the key takes effect immediately: the running servers are restarted in place, no app restart required.

Authenticating requests​

Every request on every transport needs the same bearer token:

Authorization: Bearer <your-api-key>
  • HTTP: an Authorization: Bearer <key> header, checked by an axum middleware in front of every route (including /mcp).
  • gRPC: an authorization metadata entry of the form Bearer <key>, checked by a per-service tonic interceptor.
  • MCP: MCP requests ride the same axum router as the HTTP gateway (mounted at /mcp), so they go through the identical Authorization: Bearer <key> header check; there is no separate MCP-specific auth path.

A request with a missing or invalid key gets 401 Unauthorized (HTTP) or UNAUTHENTICATED (gRPC). The check is against the current live settings on every request, not a value cached at server startup, so a key you just regenerated (or an API you just disabled) takes effect on the very next request.

Connecting an MCP client​

The MCP server speaks the Streamable HTTP transport at:

http://127.0.0.1:8642/mcp

(the same host/port as the HTTP gateway, since it's mounted on that router - not a separate port). Most MCP clients that support remote/HTTP servers take a URL plus custom headers.

Claude Code​

claude mcp add --transport http maslow-desktop http://127.0.0.1:8642/mcp \
--header "Authorization: Bearer <your-api-key>"

Other clients (Claude Desktop and similar mcpServers-config clients)​

{
"mcpServers": {
"maslow-desktop": {
"type": "http",
"url": "http://127.0.0.1:8642/mcp",
"headers": {
"Authorization": "Bearer <your-api-key>"
}
}
}
}

Substitute the API key you generated on the Settings tab. If the client only accepts a bare command-line MCP server (stdio-based) rather than a URL, it can't reach this server: this app's MCP server is HTTP-only, by design, so it can share the same enable toggle and API key as the rest of the control API (see Using the API above) rather than needing its own separate auth story.

Example​

curl -H "Authorization: Bearer $MASLOW_API_KEY" http://127.0.0.1:8642/v1/machines/default:snapshot

See the HTTP, gRPC, and MCP reference pages for the full set of operations, request/response shapes, and (for MCP) tool parameter schemas.