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.
Browse the docs
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).
{
"inputs": { "Z": "tensor[m,n]" },
"ops": [
{ "op": "normalize", "x": "Z", "as": "Zn" },
{ "op": "scalarProduct", "x": "Zn", "k": 3.14159, "as": "out" }
],
"output": "out"
}{
"output": "out",
"result": {
"shape": [3, 3],
"dtype": "f32",
"data": "<base64>"
},
"stats": { "ops": 2, "ms": 4.2, "backend": "cpu-llvm" }
}Validation rules
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.as label is a static error.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.