Documentation

Build with declarative graphs

Everything you need to compose, validate, and execute multi-step scientific computing & statistical analysis through the Euriklis MCP server or HTTP API.

DAG request shape

A DAG has three keys: inputs (named tensors or graphs supplied by the caller), ops (an ordered list of operations), and output (the label of the op whose result is returned).

Request
{
  "inputs": { "Z": "tensor[m,n]" },
  "ops": [
    { "op": "normalize",     "x": "Z",  "as": "Zn" },
    { "op": "scalarProduct", "x": "Zn", "k": 3.14159, "as": "out" }
  ],
  "output": "out"
}
Response
{
  "output": "out",
  "result": {
    "shape": [3, 3],
    "dtype": "f32",
    "data": "<base64>"
  },
  "stats": { "ops": 2, "ms": 4.2, "backend": "cpu-llvm" }
}

Validation rules

Strict referencesEvery x, scalar, or k field on an op must reference either a key in inputs or the as label of an earlier op. Undefined references throw — no auto-creation.
Pure and functionalAll ops are pure. There are no in-place mutations, no side-effects, and no void ops in the data plane. An op with no as label is a static error.
Static validationBefore execution, the validator runs shape inference, type checking, and cycle detection. Failures return a structured error and do not consume your call quota.

Why DAGs?

An agent that wants "normalize then multiply by π" can issue two MCP calls — one per op — but every round-trip is a latency hit and a chance for the agent to drift. Declaring the full computation as one DAG sends one request, validates the full plan up front, executes on a single backend, and returns the final tensor.

Each op stays a primitive (composable, testable) while the caller speaks at the level of intent. The compiler — LLVM for CPU, PTX for GPU — then fuses where it can.