Skip to main content
Glama

sensorforge-mcp

We shrink models to fit edge devices. This MCP server lets your coding agent (Claude Code, Cursor, VS Code, Claude Desktop, Windsurf, Cline) send a trained .tflite or .onnx model to the hosted SensorForge Optimizer and unpack the result into your project: a TensorFlow Lite Micro model and its C sources that need less SRAM and flash, within the accuracy limit you set, with every figure measured by running the file.

The server runs on your machine over stdio. It reads the model and data files you name, calls the SensorForge service with your API key, and writes the results next to your model. The optimizer itself runs on the service.

Get an API key

Sign in at https://sensorforge.dev/optimize/app and create a key under API keys. Keys start with sfk_. Keep it out of your repository: pass it as an environment variable, as in the configurations below.

Related MCP server: JAOT MCP Server

Install

You need uv (for uvx). Python 3.10 or newer is fetched by uv if you don't have it.

Claude Code

claude mcp add sensorforge -e SENSORFORGE_API_KEY=sfk_... -- uvx sensorforge-mcp

Claude Desktop (claude_desktop_config.json), Cursor (~/.cursor/mcp.json, or .cursor/mcp.json in a project), Windsurf (~/.codeium/windsurf/mcp_config.json) and Cline (MCP Servers, Configure, cline_mcp_settings.json) all take the same block:

{
  "mcpServers": {
    "sensorforge": {
      "command": "uvx",
      "args": ["sensorforge-mcp"],
      "env": { "SENSORFORGE_API_KEY": "sfk_..." }
    }
  }
}

Claude plugin: this repository is also a plugin, with the server above and a fit-model-to-chip skill. It asks for your key once and keeps it in your system's credential store. The plugin runs uvx sensorforge-mcp on your machine; it loads in Claude Code and in Cowork sessions on your computer, not in claude.ai chat.

VS Code (.vscode/mcp.json; VS Code asks for the key once and stores it):

{
  "inputs": [
    { "type": "promptString", "id": "sensorforge-key", "description": "SensorForge API key", "password": true }
  ],
  "servers": {
    "sensorforge": {
      "type": "stdio",
      "command": "uvx",
      "args": ["sensorforge-mcp"],
      "env": { "SENSORFORGE_API_KEY": "${input:sensorforge-key}" }
    }
  }
}

Restart the client (or reload its MCP servers), then ask it to list the SensorForge tools.

What to ask

  • "Will models/kws.tflite fit on an nRF54L15? Check it with SensorForge."

  • "Run SensorForge lossless on models/kws.tflite for the nrf5340 and put the C files in firmware/model/."

  • "Optimize models/kws.tflite for the esp32s3 with data/kws.npz: least SRAM, at most 1 point of accuracy lost. Check the data first."

  • "What's left on my SensorForge account today?"

The server also has a prompt, fit_model_to_chip, that walks the agent through every step (in Claude Code: /mcp__sensorforge__fit_model_to_chip). For a repository, drop examples/AGENTS.md into your project so any agent knows the flow.

Tools

Tool

What it does

list_chips

The chips you can target, with each one's SRAM and flash budget.

check_fit

Does the model run on a chip, and in how much SRAM and flash? Seconds; no data.

lossless

Less SRAM and flash, outputs bit-identical to yours; no data. Waits, downloads and unpacks.

check_data

Checks your data file against the model, locally. Nothing is uploaded.

optimize

The smallest model within your accuracy limit, retrained on your data. Returns a run id at once (5–60 min).

wait_for_run

Waits for a run (up to 10 minutes per call) and returns the result; call again while it says still running.

run_status

A run's state now: place in the queue, running, or the verdict with before → after figures.

download

Unpacks a finished run into <model folder>/sensorforge/<run id>/ and says what each file is for.

get_report

The run's full report (markdown).

list_runs

Your recent runs.

stop_run

Stops a queued or running run.

account

Your plan, this month's usage, and the runs left today.

What a download holds:

  • the model for TensorFlow Lite Micro (optimized_tflm.tflite or model_lossless.tflite), the file to deploy;

  • sometimes the same model as desktop LiteRT loads it, for checking it on a PC;

  • c/: model_data.cc / model_data.h (the model as a C array), model_ops.h (the operators to register, the input and output scale and zero point, the tensor arena size) and INTEGRATION.md (how to build it in);

  • the report (report.md or lossless.md).

Data for optimize

Images: a .zip of folders, one per class, holding JPEG or PNG files (person/, no_person/, ...). Folder names in alphabetical order map to the model's outputs 0, 1, 2, ... To fix the test set yourself, put train/ and test/ folders in the zip, each with the class folders.

Audio, sensors and anything else: an .npz with X, the model's inputs exactly as your front end produces them (float32, one row per sample, in the model's input shape), and y, each sample's class index in the model's output order. Add X_test / y_test for a fixed test set. Without y, your model's own answers become the labels.

import numpy as np
np.savez("data.npz", X=features.astype("float32"), y=labels.astype("int64"))

Detectors, autoencoders and regression models: pass output="values"; y is not needed. A few hundred samples per class are enough to measure accuracy; more helps the retraining. check_data checks all of this before you upload.

Limits

  • Model files up to 50 MB (.tflite, .onnx, or a .zip of a firmware export). PyTorch and Keras files are not accepted: export to .tflite or .onnx first.

  • Data up to 500 MB (.npz or .zip; a zip may unpack to 2,000 MB).

  • Runs per day depend on your plan; account shows what is left and when the next run is free.

  • Results (report and model) are kept 14 days.

  • Uploaded models and data are deleted when the run ends.

Privacy Policy

What is collected. The server reads only the files you name. check_fit, lossless and optimize upload the model, and optimize also uploads your data file, to the SensorForge service over HTTPS. check_data runs on your machine and uploads nothing. Your API key is sent only to the SensorForge service.

How it is used and stored. The service uses your uploads to run the job you asked for, each in its own folder. Your runs, reports and optimized models are visible only to your account. Locally the server keeps a short list of your run ids and model paths in ~/.sensorforge-mcp/runs.json, so downloads land next to the right model. Nothing it downloads is ever run.

Who else handles it. The service and its storage run on Railway, Vercel routes traffic to it, and sign-in is by Clerk. Your models and data are not sold or shared with anyone else.

How long it is kept. Uploads and everything made from them are deleted when the run ends. The report and the optimized model are kept for 14 days so you can download them, then deleted. A record of each run (file names, settings, results and compute time) stays for your run history and billing.

Contact. sid@sensorforge.dev. EdgeForge LLC.

Settings

Variable

SENSORFORGE_API_KEY

Your key (required).

SENSORFORGE_URL

The service, default https://sensorforge.dev/optimize.

SENSORFORGE_MCP_HOME

Where the run list is kept, default ~/.sensorforge-mcp.

SENSORFORGE_LOG

Log level on stderr, default WARNING.

License

Apache-2.0. Copyright 2026 EdgeForge LLC. See LICENSE.

Available Tools

12 tools
accountAccount and usageA
Read-only

The account's plan, this month's usage, and how many runs are left today (with when the next one is free when a daily cap is reached).

Inputs: no named parameters.

check_dataCheck data locallyA
Read-only

Check, locally, that a data file is what optimize needs for this model, before uploading anything. For an .npz: X present, float32, each sample in the model's input shape; y one class index per sample within the model's outputs; X_test / y_test if given. For an image zip: class folders (or train/ and test/). Explains each problem and how to fix it. Nothing is uploaded and no run is used.

Inputs: data_path (required), model_path (required), output.

check_fitCheck fit on a chipA

Check whether a model runs on one or more chips and how much SRAM and flash it needs there, measured. Takes seconds; no data needed. Returns a per-chip verdict with SRAM and flash against each chip's budget, and the SRAM lossless would reach. Use it first, before lossless or optimize.

Inputs: model_path (required), chips.

downloadDownload a run's resultA
Idempotent

Download a finished run's result and unpack it into the project: the model for TensorFlow Lite Micro, its C sources (c/: the model as a C array, the operator list, integration notes) and the report. Refuses to write into a folder that is not empty unless overwrite=True. Returns each file and what it is for.

Inputs: run_id (required), folder, overwrite.

get_reportGet a run's reportA
Read-only

The run's full report as markdown: the measured figures, what was changed and why, and what to do next. Available on every plan, including the trial.

Inputs: run_id (required).

list_chipsList chipsA
Read-only

List the chips (edge devices) the optimizer targets, with each one's SRAM and flash budget for the model. Use a chip's name as chip in check_fit, lossless and optimize. Chips without budgets take yours (ram_kb, flash_kb in optimize).

Inputs: no named parameters.

list_runsList runsA
Read-only

The account's recent runs, newest first: id, when, kind, model, status and verdict. Runs are kept 14 days.

Inputs: limit.

losslessLossless shrinkA

Make the model smaller in SRAM and flash with outputs bit-identical to the original: no data, no retraining. Usually under a minute. Waits for the result, downloads it, and unpacks the model for TensorFlow Lite Micro and its C sources into the project. Returns the before -> after figures and the files. If it is still running after about four minutes it returns the run id: then call wait_for_run and download.

Inputs: chip (required), model_path (required), folder, overwrite.

optimizeOptimize within an accuracy limitA

Find the smallest model for the chip within your accuracy limit, retrained on your data. Runs on the service for 5-60 minutes, so this returns right away with the run id and its place in the queue: then call wait_for_run(run_id) (again while it says still running), and download(run_id) when it passes. The data is used for this run only and deleted when it ends.

Inputs: chip (required), data_path (required), model_path (required), effort, +7 more.

run_statusRun statusA
Read-only

The state of a run right now, without waiting: queued (with its place in line), running (with its latest progress), or finished with the verdict and the before -> after SRAM, flash and accuracy.

Inputs: run_id (required).

stop_runStop a runA
DestructiveIdempotent

Stop a queued or running run, for example one sent with the wrong chip or data. A stopped run gives no result; submit it again to rerun.

Inputs: run_id (required).

wait_for_runWait for a runA
Read-only

Wait for a run to finish, checking about every 10 seconds and reporting progress. Returns the final result (verdict and before -> after figures), or 'still running, call again' when max_wait_s is up: then call wait_for_run again. Optimize runs take 5-60 minutes, so expect several calls.

Inputs: run_id (required), max_wait_s.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 12 tools

    Disambiguation4/5

    The core workflow tools are well separated: check_data validates locally, check_fit measures fit without data, lossless shrinks without data, and optimize retrains on data, with descriptions stating the ordering. The main soft spot is the run-inspection cluster (list_runs, run_status, wait_for_run, get_report) plus download, which overlaps with lossless since lossless also downloads and unpacks output — but each still has a stated distinct behavior.

    Naming Consistency3/5

    Most tools follow snake_case verb_noun (list_runs, stop_run, check_fit, check_data, run_status, wait_for_run, get_report), but a large minority are bare single words of mixed grammatical type: download, optimize (verbs), account (noun), lossless (adjective). Readable, but the convention is not predictable across the set.

    Tool Count5/5

    Twelve tools map cleanly onto a coherent pipeline (inspect chips, validate data, check fit, optimize/lossless, poll, download, report, account, stop) with no filler or duplicate endpoints. Well within the well-scoped 3–15 range.

    Completeness4/5

    The run lifecycle is covered end to end: discovery (list_chips), preflight (check_data, check_fit), execution (optimize, lossless), progress (run_status, wait_for_run), cancellation (stop_run), output retrieval (download, get_report), plus history and quota (list_runs, account). Minor gaps remain, such as deleting/cleaning up old runs or a plain fetch of results without unpacking into a project directory.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers