Machine Learning
for AI Agents

Ask your agent to train a model, tune it, compare it to the last run, or find an algorithm that fits your data. It just does it. No code. No guesswork. No forgotten context.

$ curl -fsSL https://tuiml.ai/install.sh | bash
Help me install https://tuiml.ai/install
Ready for
🦞 NVIDIA NemoClaw Claude ChatGPT Cursor Gemini Copilot Perplexity
NVIDIA Runs inside NVIDIA NemoClaw

Secure agent-driven
machine learning workflows.

Connect TuiML with NVIDIA NemoClaw to deploy safe, always-on AI assistants that can run real ML workflows, experiments, and evaluations through a structured interface.

1
Install NemoClaw
curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash
2
Enter the sandbox
nemoclaw <sandbox-name> connect
3
Install and connect TuiML
pip install tuiml && openclaw mcp set tuiml '{"command":"tuiml-mcp"}'
Secure Agent ML Workflow One-Command Setup

* NVIDIA, NemoClaw, and the NVIDIA logo are trademarks of NVIDIA Corporation. Compatibility noted above is informational; this is not an official partnership or endorsement.

NVIDIA NemoClaw mascot
Why TuiML

Built so agents can actually do ML

Three principles, six capabilities. Every algorithm ships with a schema agents read directly, so they pick the right tool, pass valid arguments, and get typed results back.

Agents can call it Agents can discover it Agents can trust it

200+ Algorithms

Classifiers, regressors, clustering, anomaly, and time-series, all wrapped as a typed MCP tool your agent can invoke directly.

Train · Tune · Compare

Fit a model, sweep hyperparameters, and rank runs in one conversation. No notebook. No glue code.

Algorithm Discovery

Your agent searches the catalog by task, data shape, or constraint and gets ranked recommendations with rationale, not a flat list of names.

Persistent Experiments

Every run is logged with lineage and metrics. Compare today's model against last week's without re-running anything.

One-Call Serving

Deploy a trained model to a local HTTP endpoint with a single tool call. Stop it the same way. No FastAPI scaffolding.

100% Local & Private

Your data, your machine, your laptop. No cloud, no API keys, no telemetry. Only the LLM calls your agent already makes.

Agent in action

See it in a conversation

A few demos of what an agent can actually do once TuiML is connected. Click a tab to walk through the full exchange.

agent · tuiml connected
Recommend a classifier for the diabetes dataset and benchmark three options.
Tool call tuiml_search
{ query: "classifier", category: "algorithm" }
Result status: success
results: [ RandomForestClassifier, LogisticRegression, J48, NaiveBayes, SVM, MultilayerPerceptron, ... ]
Tool call tuiml_experiment
{ algorithms: ["RandomForestClassifier", "LogisticRegression", "J48"], data: "diabetes", cv: 5, metrics: ["accuracy_score"] }
TuiML
Queried the registry, picked three representative classifiers, and ran a 5-fold experiment on the built-in diabetes dataset. Ranked by mean accuracy:
#1RandomForestClassifier0.768
#2LogisticRegression0.758
#3J480.737
RandomForestClassifier leads. Want me to tune its n_estimators and max_depth with tuiml_tune?
Built in: a queryable algorithm registry plus tuiml_experiment, which ranks multiple algorithms in one call.
agent · session resumed · yesterday's context available
· Session 1 · Monday ·
Train a random forest on the iris dataset.
Tool call tuiml_train
{ algorithm: "RandomForestClassifier", data: "iris", target: "class" }
Result status: success
{ model_id: "7a3c91f2b4d0", model_path: "~/.tuiml/models/7a3c91f2b4d0.joblib", metrics: { accuracy_score: 0.967 } }
· Session 2 · Tuesday (next day) ·
How did yesterday's model do? Evaluate it on the wine dataset and tell me how accuracy compares.
Tool call tuiml_evaluate
// agent reuses model_path from yesterday's response { model_path: "~/.tuiml/models/7a3c91f2b4d0.joblib", data: "wine", target: "class" }
Result status: success
{ metrics: { accuracy_score: 0.944 } }
TuiML
Yesterday's model 7a3c91f2b4d0 is still on disk, so I loaded it by model_path and evaluated on wine:
iris (Monday): 0.967
wine (today): 0.944  ▼ −2.3pp
The same model generalizes well to wine, just a little lower. Want me to retrain on wine with tuiml_train?
Models persist in ~/.tuiml/models/ and stay callable by model_path across sessions.
agent · tuiml connected
Train RandomForestClassifier on my CSV, no preprocessing, just go.
Tool call tuiml_train
{ algorithm: "RandomForestClassifier", data: "raw_data", target: "label", n_estimators: 100, max_leaves: "none" // wrong type for this param }
Structured error status: error
{ status: "error", error_type: "ValueError", error: "max_leaves expected int, got str", suggestion: "Check parameter types and values. Use tuiml_describe to see the algorithm's parameter schema", recovery_tool: "tuiml_describe", recovery_params: { name: "RandomForestClassifier" } }
Auto-recovery tuiml_describe
// agent follows recovery_tool hint to read the schema { name: "RandomForestClassifier" }
Schema parameters
{ n_estimators: "int, default=100", max_depth: "int or None, default=None", max_features: "int | 'sqrt' | 'log2', default='sqrt'", random_state: "int or None, default=42" }
Retry tuiml_train
{ algorithm: "RandomForestClassifier", data: "raw_data", target: "label", preset: "standard", n_estimators: 100, max_depth: 12 }
TuiML
The first call failed because max_leaves isn't a valid parameter. The error pointed me at tuiml_describe, I read the real schema, dropped the bad param, added the standard preprocessing preset, and retrained:
✓ Trained RandomForestClassifier · accuracy 0.911
Every TuiML error returns error_type, a human suggestion, and a recovery_tool + recovery_params, so agents can actually recover instead of giving up.
agent · auto-research session
Try a weighted-bagging tree ensemble on iris. Compare it to XGBoost and RandomForest. Iterate until you beat both.
Tool call tuiml_algorithm_skeleton
{ kind: "classifier", class_name: "WeightedTreeBag" }
Tool call tuiml_create_algorithm
// agent wrote 38 lines of Python. AST-validated, saved, registered. { name: "WeightedTreeBag", version: "1.0.0", kind: "classifier", code: "<38 lines>" }
Registered source_hash 6a12f…
{ registered_as: ["WeightedTreeBag", "WeightedTreeBag_v1_0_0"], path: "~/.tuiml/user_algorithms/WeightedTreeBag/1.0.0/" }
Iterate tuiml_create_algorithm
// v1 scored 0.92. Agent tweaks weighting and resubmits. { name: "WeightedTreeBag", version: "1.0.1", code: "…" }
Benchmark tuiml_experiment
{ algorithms: ["WeightedTreeBag_v1_0_0", "WeightedTreeBag_v1_0_1", "XGBoostClassifier", "RandomForestClassifier"], data: "iris", cv: 10, metrics: ["accuracy_score"] }
Ranked · iris · 10-fold CV
#1 WeightedTreeBag_v1_0_1 0.9667 ± 0.021
#2 XGBoostClassifier 0.9533 ± 0.028
#3 RandomForestClassifier 0.9467 ± 0.033
#4 WeightedTreeBag_v1_0_0 0.9200 ± 0.041
Verdict Wilcoxon signed-rank
{ p_value: 0.031, significant: true, alpha: 0.05, conclusion: "v1_0_1 > XGBoost" }
TuiML
Second iteration (v1.0.1) beat both baselines. Wilcoxon signed-rank on the 10-fold scores confirms the gap is significant (p = 0.031). Source is persisted at ~/.tuiml/user_algorithms/WeightedTreeBag/1.0.1/, so you can rerun or iterate from there anytime.
Every version is AST-validated, source-hashed, and persisted to ~/.tuiml/user_algorithms, so iterations survive restarts and are fully reproducible.
agent · tuiml connected
Train a RandomForest on iris, serve it as a REST endpoint, and verify it works.
Tool call tuiml_train
{ algorithm: "RandomForestClassifier", data: "iris", target: "target", cv: 5 }
Trained model_id a1b2c3d4
{ status: "success", model_id: "a1b2c3d4", metrics: { cv_accuracy_score_mean: 0.9667 } }
Tool call tuiml_serve_model
{ model_id: "a1b2c3d4", port: 8080 }
Serving REST endpoint live
{ status: "success", url: "http://127.0.0.1:8080/predict", server_id: "srv_7f2e", methods: ["POST"] }
Verify POST /predict
// agent sends one sample to confirm the endpoint responds { features: [5.1, 3.5, 1.4, 0.2] } // → 200 OK { prediction: "setosa", proba: { "setosa": 0.98, "versicolor": 0.02, "virginica": 0.00 } }
TuiML
Trained (cv_acc 0.967), served on :8080, and confirmed a live prediction round-trip. Stop the server anytime with tuiml_stop_server(server_id="srv_7f2e").
Train, deploy, and smoke-test in one conversation. No YAML, no Dockerfile, no context switching.
Framework adapters

Drop into any agent framework

Same TuiML tools, native bindings for every popular framework. Pick your SDK, install the extra, copy the snippet.

import tuiml # Default: Claude Sonnet 4.6. Set ANTHROPIC_API_KEY in your env. # tuiml.agent() returns a Pydantic-AI Agent preloaded with # - every TuiML MCP tool (tuiml_train, tuiml_experiment, ...) # - the canonical SKILL.md as the system prompt result = tuiml.agent().run_sync( "Train RandomForestClassifier on iris, then benchmark it " "against XGBoost. Return both accuracy scores." ) print(result.output) # → "RandomForestClassifier: 0.95, XGBoostClassifier: 0.96 (diff: +0.01)" # Pick a different LLM. Any Pydantic-AI model string works: # tuiml.agent("openai:gpt-4o") # OpenAI # tuiml.agent("google:gemini-2.0-pro") # Google # tuiml.agent("groq:llama-3.3-70b") # Groq

Install · pip install tuiml[pydantic-ai]

from openai import OpenAI from tuiml.agent import openai as tuiml_openai client = OpenAI() response = client.chat.completions.create( model="gpt-4o", tools=tuiml_openai.get_tools(), messages=[ {"role": "system", "content": tuiml_openai.system_prompt()}, {"role": "user", "content": "Train RandomForestClassifier on iris."}, ], ) for call in response.choices[0].message.tool_calls or []: result = tuiml_openai.dispatch_tool_call(call) print(result)

Install · pip install tuiml[openai]

from anthropic import Anthropic from tuiml.agent import anthropic as tuiml_anthropic client = Anthropic() response = client.messages.create( model="claude-sonnet-4-6", max_tokens=4096, system=tuiml_anthropic.system_prompt(), tools=tuiml_anthropic.get_tools(), messages=[{"role": "user", "content": "Compare RF and XGBoost on iris."}], ) for block in response.content: if block.type == "tool_use": result = tuiml_anthropic.dispatch_tool_use(block) print(result)

Install · pip install tuiml[anthropic]

from langgraph.prebuilt import create_react_agent from langchain_anthropic import ChatAnthropic from tuiml.agent import langchain as tuiml_lc agent = create_react_agent( model=ChatAnthropic(model="claude-sonnet-4-6"), tools=tuiml_lc.get_tools(), prompt=tuiml_lc.system_prompt(), ) agent.invoke({ "messages": [("user", "Tune XGBoost on the wine dataset.")] })

Install · pip install tuiml[langchain]

from pydantic_ai import Agent from tuiml.agent import pydantic_ai as tuiml_pai agent = Agent( "anthropic:claude-sonnet-4-6", tools=tuiml_pai.get_tools(), system_prompt=tuiml_pai.system_prompt(), ) result = agent.run_sync("Train a classifier on iris and show metrics.") print(result.output) # For the one-liner: tuiml.agent().run_sync(...)

Install · pip install tuiml[pydantic-ai]

from crewai import Agent, Task, Crew from tuiml.agent import crewai as tuiml_crew data_scientist = Agent( role="Data Scientist", goal="build accurate models", backstory=tuiml_crew.system_prompt(), tools=tuiml_crew.get_tools(), ) task = Task(description="Train and tune XGBoost on iris", agent=data_scientist) Crew(agents=[data_scientist], tasks=[task]).kickoff()

Install · pip install tuiml[crewai]

Common questions

Frequently asked

Quick answers about scope, comparison, and how TuiML fits into your stack.

How is TuiML different from just calling scikit-learn from a code interpreter?

scikit-learn assumes a human in front of an editor. Inconsistent fit/predict shapes, raw Python tracebacks, no algorithm registry. Fine for engineers, painful for agents.

TuiML wraps every algorithm in a typed MCP tool with a uniform schema, structured errors with suggested fixes, and a queryable registry the agent can search by task and data shape. You stop spending tokens on glue code and stack traces.

Why not use a thin sklearn-MCP wrapper instead?

Thin wrappers inherit sklearn's inconsistencies, return raw exceptions, and are stateless per call. They also cover only classical algorithms. No time-series, no anomaly detection, no model serving.

TuiML is purpose-built: shared experiment state across calls, diffable runs, and a single tool to deploy a trained model, not a thin layer over someone else's API.

How does TuiML compare to managed AutoML (Vertex, SageMaker, H2O)?

Managed AutoML platforms work, but you pay for compute, deal with auth and quotas, and your data leaves the machine. Algorithm choice is a black box.

TuiML runs 100% local, free, BSD-3-Clause, with explicit algorithm selection your agent can reason about. Same end-to-end loop (train → evaluate → serve) without the cloud bill or vendor lock-in.

Which agents and clients work with TuiML?

Anything that speaks MCP. The tuiml setup wizard auto-detects and configures Claude Desktop, Claude Code, Cursor, ChatGPT Desktop, Codex CLI, Zed, Continue, Windsurf, VS Code Copilot, Perplexity, Goose, and OpenClaw / NemoClaw.

Can my agent actually deploy a model, not just train one?

Yes. tuiml_serve_model spins up a local HTTP endpoint for a trained model in one tool call. No FastAPI scaffolding, no Docker, no separate serving framework. The agent can train, evaluate, deploy, and verify in a single conversation.

Is TuiML production-ready?

It's alpha. The API surface is stabilizing, the algorithm catalog is live, and early adopters are using it daily. But if you need 15-year battle-tested reliability today, raw scikit-learn is still the safer bet. We close that gap fast; open issues get a quick response.

What about my data? Does anything leave my machine?

No. TuiML installs locally, trains locally, serves locally. The only network calls are the ones your agent makes to its own LLM. Your dataset never sees our servers. There are no servers.

How much does it cost?

Free, open source, BSD-3-Clause. The only cost is whatever your agent's LLM provider charges for tokens, same as you'd pay anyway.

Supported By

Developed at the AI Institute, University of Waikato. Built for the modern AI era.

Build with us

The open build board

Algorithms, integrations, and tools the community can build with TuiML. Perfect for students and contributors. Pick a card and ship it.

Live from GitHub issues