WEKA-MCP hosted demo · no key

@relation weka-mcp

A machine-learning workbench
your model can actually use.

WEKA has done real ML since 1993 — classifiers, clustering, association rules, diagnostics. WEKA-MCP puts all of it behind 46 typed Model Context Protocol tools, so an LLM can load a dataset, train a model, and explain where it fails.

No API key. No sign-up. Paste one URL into ChatGPT or Claude.

iris — a session
@relation iris
@attribute sepallength numeric
@attribute petalwidth  numeric
@attribute class       {setosa, versicolor, virginica}
weka_upload_dataset 150 instances, 5 attributes
weka_train J48 pruned tree · 96.0% correct
weka_predict Iris-setosa p=0.98
petalwidth <= 0.6
├─ Iris-setosa (50.0)
└─ petalwidth > 1.7 → Iris-virginica (46.0/1.0)

@architecture

Two services. One does the ML, one does the translating.

The MCP server holds no machine-learning logic at all. It is a typed forwarder: every tool call becomes a REST call against WEKA running in a JVM next door. That split is why the ML behaves exactly like WEKA does — because it is WEKA.

MCP client Claude · ChatGPT · Code POST /mcp or stdio weka-mcp TypeScript · 46 tools REST :7070 weka-api Java 17 · Javalin WEKA 3.9.6 no ML logic — a typed forwarder the real ML · persists models + data

weka-mcp

The translator

A Node MCP server that turns each tool call into a weka-api REST call and nothing more. Speaks both transports: HTTP on POST /mcp for remote clients, and stdio for desktop ones. Finds the API through WEKA_API_URL.

Port
3000 in-container
Health
/healthz
State
none — stateless

weka-api

The workbench

Java 17 and Javalin wrapping WEKA 3.9.6. This is where training, evaluation, clustering, and diagnostics actually happen. Serialized models and uploaded datasets live on disk, so a model you train stays trainable against later.

Port
7070
Models
/app/models
Data
/app/data

In the cloud, only one of them is reachable

On Azure Container Apps, weka-api has internal-only ingress — it has no public DNS entry, and only weka-mcp inside the environment can reach it. Both apps scale to zero and are capped at one replica, so an idle demo costs close to nothing and a busy one can't run up a bill.

@install

Two ways to connect

Take the hosted server if you want to try it in the next minute. Run it locally if you want your data to stay yours.

Option A

Use the hosted server

It runs in open demo mode: no key, no header, no account. Point any MCP-over-HTTP client at this endpoint.

MCP endpoint https://weka-mcp.ademartutor.com/mcp
  1. Open Settings → Connectors (Plus, Pro, or Business; enable Developer mode if the option is hidden).
  2. Choose Add custom connector.
  3. Paste the endpoint above. Leave the authentication field empty.

All 46 tools appear once the connector saves.

Read this before you upload anything

  • It is a public sandbox. The dataset and model volume is shared and open — anyone can list, download, or delete what you put there. Don't upload anything private.
  • Uploads are capped at 20 MB.
  • The first call after an idle period takes 10–30 seconds while the JVM wakes from scale-to-zero. It isn't broken; it's cold.
  • Training that runs past ~240 seconds can't finish over the ingress timeout. Big jobs belong on a local install.

Option B

Run it locally with Docker

One command builds both services, picks free ports, and waits until the server reports healthy. You need Docker with Compose v2 — and Node 20 or newer only if you want stdio.

git clone https://github.com/ademartutor/weka-mcp-core.git
cd weka-mcp-core
bin/setup

bin/setup probes for free host ports — starting at 3001 for weka-mcp and 7070 for weka-api — writes them to a generated .env, builds, and waits for health. It prints the ports it chose. Internally the two services always talk over weka-api:7070, which mirrors the cloud shape.

Check that it came up

curl -s localhost:3001/healthz
{"ok":true,"wekaApiUrl":"http://weka-api:7070"}

Connect Claude Code

cd weka-mcp && npm ci && npm run build

claude mcp add weka \
  --env WEKA_API_URL=http://localhost:7070 \
  -- node "/ABSOLUTE/PATH/TO/weka-mcp-core/weka-mcp/dist/index.js"

Connect Claude Desktop

{
  "mcpServers": {
    "weka": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/weka-mcp-core/weka-mcp/dist/index.js"],
      "env": { "WEKA_API_URL": "http://localhost:7070" }
    }
  }
}

stdio needs weka-api on the host

The compose stack deliberately doesn't publish weka-api to your host, so localhost:7070 won't answer out of the box. Either run weka-api directly (cd weka-api && mvn -q package -DskipTests && PORT=7070 java -jar target/weka-api-*-shaded.jar) or add ports: ["7070:7070"] to the weka-api service in compose.yaml.

Tear it down

bin/remove            # down -v, removes images, frees the ports
docker compose down   # stop containers, keep the volumes

@tools

All 46 tools

Every tool is weka_-prefixed and typed. Grouped the way you'd actually work: look at the data, transform it, train something, then find out where it breaks.

@config

Environment variables

weka-mcp

VariableDefaultPurpose
WEKA_API_URLhttp://localhost:7070Base URL of weka-api. Compose uses http://weka-api:7070.
MCP_HTTP_PORT3000Port the HTTP transport listens on.
WEKA_API_TIMEOUT_MS210000Per-request timeout, kept under the ~240s ingress ceiling.
INTERNAL_AUTH_SHARED_SECRETunsetWhen set, POST /mcp requires X-Internal-Auth. Unset means the check is skipped.

weka-api

VariableDefaultPurpose
PORT7070Port Javalin binds.
MODELS_DIR/app/modelsSerialized .model files.
DATA_DIR/app/dataUploaded ARFF and CSV datasets.
MAX_UPLOAD_MB100Upload size cap. The hosted demo sets this to 20.
LOG_LEVELINFOLogback root level.
JAVA_TOOL_OPTIONSunsetJVM flags. Compose sets -XX:MaxRAMPercentage=75.0.

One gotcha worth knowing

Locally, WEKA_API_URL carries a port: http://weka-api:7070. In the cloud it must not — internal ingress terminates TLS on 443 and maps to the container's port itself, so the value is https://<api-internal-fqdn> with no port at all.