Skip to main content
Glama
BxNxM
by BxNxM

test-webui example1

DockerHub

micrOSMCP

Standalone TypeScript MCP server and browser tester UI for micrOS devices. Use it to discover devices, inspect the device cache, run micrOS commands, and discover each device's available module commands.

Table of Contents

Related MCP server: Orchestration MCP

Quick Start

npm install
npm run start:ui

Open one of the URLs printed at startup. The native tester binds on all interfaces and prints localhost plus detected LAN addresses:

https://127.0.0.1:3333
https://10.0.1.42:3333

The tester has no authentication layer. Localhost and LAN clients can use every UI API directly, including persisted server-side API-key detection and MCP tools. Run it only on a trusted network, or set HOST=127.0.0.1 to restrict access to the local machine. Each AI assistant response shows a compact footer with aggregate input, output, and total token usage, including all model calls made during its tool loop.

The UI is the easiest way to verify everything locally. It includes an optional AI chat panel for testing the MCP tools with an OpenAI API key, plus manual tool forms that render schemas, keep JSON arguments editable, and give device dropdowns for device-targeted tools.

Browser microphone access for the listen button requires a secure origin, so the UI automatically creates and serves HTTPS with a self-signed certificate stored in data/ui-self-signed-cert.pem and its private key in data/ui-self-signed-key.pem. The certificate includes localhost and detected LAN addresses and is reused until it expires or the address list changes. The server prints https:// URLs for every detected local address.

Client devices must trust data/ui-self-signed-cert.pem before their browsers will permit microphone access. Accepting the certificate warning is sufficient in browsers that then treat the connection as secure, including Safari in typical local setups; other clients may require installing the certificate as trusted.

MICROS_UI_CERT_HOSTS adds IP addresses or DNS hostnames to the generated certificate. Multiple values are comma-separated:

MICROS_UI_CERT_HOSTS=gateway.local,10.0.1.42 npm run start:ui

The hostname must resolve to the UI host from the client device. Changing this list or the detected addresses regenerates the certificate, so clients must accept or trust the replacement certificate. The UI always uses HTTPS, even when MICROS_UI_CERT_HOSTS is omitted; it never falls back to HTTP. Browsers with speech recognition use live dictation; Safari falls back to recording audio and transcribing it with the saved OpenAI API key.

Stopping dictation immediately aborts browser speech recognition. A final dictation result, chat send or clear, tab hiding, and page exit also release capture. The recording fallback stops every media track before transcription, so the browser microphone indicator should turn off as soon as capture ends.

The AI chat API key, selected model, and Speak setting are saved locally by the UI server in data/ui_chat_config.json so reloads can reuse them. The saved key remains server-side: browser configuration responses expose only whether a key exists, never the key itself. Override the config path with MICROS_CHAT_CONFIG_PATH if needed. The model dropdown loads available OpenAI Chat Completions models from supported tool-calling families using the saved key; non-chat and specialized model variants are omitted because the tester's MCP bridge requires function tools. Browser speech recognition and speech synthesis are used for the optional listen/speak controls when the current browser supports them.

Use With An MCP Client

Build first:

npm install
npm run build

Codex-style config.toml:

[mcp_servers.microsmcp]
command = "npm"
args = ["run", "--silent", "start"]
cwd = "/Users/bnm/Development/micrOSMCP"

Generic JSON-style MCP config:

{
  "mcpServers": {
    "microsmcp": {
      "command": "npm",
      "args": ["run", "--silent", "start"],
      "cwd": "/Users/bnm/Development/micrOSMCP"
    }
  }
}

Use --silent with npm in MCP client config so npm does not print lifecycle banners to stdout before the MCP protocol starts. The direct equivalent is:

{
  "mcpServers": {
    "microsmcp": {
      "command": "node",
      "args": ["/Users/bnm/Development/micrOSMCP/scripts/start.mjs", "mcp"],
      "cwd": "/Users/bnm/Development/micrOSMCP"
    }
  }
}

Commands

npm run help                  # Show start modes and environment variables
npm run build                 # Clean dist, compile TypeScript, and copy MCP metadata
npm run start                 # Start stdio MCP server from dist/
npm run start:test            # Build and run minimal MCP/tool contract tests
npm run start -- ui           # Start UI from dist/ without rebuilding
npm run start:mcp             # Explicit stdio MCP mode
MICROS_INITIALIZE_ON_START=0 npm run start:mcp  # MCP mode without startup discovery or feature scan
npm run start:ui              # Build, then start the browser tester UI
npm run docker:build          # Build and export Docker image tar

Forwarded start help:

npm run start -- --help

Useful environment variables:

MICROS_DEVICE_CACHE_PATH=/path/to/device_conn_cache.json npm run start
MICROS_DEVICE_FEATURE_CACHE_PATH=/path/to/device_feature_cache.json npm run start
MICROS_DEVICE_NOTES_CACHE_PATH=/path/to/device_notes_cache.json npm run start
MICROS_FUNCTION_MANUAL_PATH=/path/to/sfuncman.json npm run start
MICROS_NETWORK_PREFIX=10.0.1 npm run start
MICROS_CHAT_CONFIG_PATH=/path/to/ui_chat_config.json npm run start -- ui
MICROS_UI_MAX_BODY_BYTES=12582912 npm run start -- ui
HOST=0.0.0.0 PORT=3333 npm run start -- ui

Tools

The MCP server exposes six tools.

Tool

Purpose

search_devices

Primary device and feature lookup before command execution. Search cached identity, notes, modules, complete function signatures, and optional live status.

list_devices

Return a compact cached device inventory with device identity, note, and known module names only.

discover_devices

Run a fresh /24 network discovery, update the device cache, and refresh cached features for discovered devices.

run_command

Run a command or command pipeline on one selected device.

set_device_note

Read, append, or replace the persistent note for a cached device.

discover_commands

Run modules, then <module> help >json, to map and cache a device's command surface.

run_command

String pipeline using the micrOS <a> separator:

{
  "deviceTag": "TinyDevBoard",
  "command": "version<a>conf webui"
}

Array pipeline:

{
  "deviceTag": "TinyDevBoard",
  "command": ["version", "conf webui"]
}

Use read-only commands such as version for smoke tests. Other micrOS commands may change device state.

Commands pass through a denial policy before device lookup or socket execution. Configuration reads such as conf and conf webui are allowed. Configuration writes are denied in direct and pipeline forms, including conf webui true, conf<a>webui true, and the equivalent array representation. Controlled denials return ok: false, the matching policy rule, and deniedCommand.

When the first word of the first command exactly matches a cached module name, case-insensitively, the response includes an optional moduleHint. It contains that module's complete cached function list with signatures and available sfuncman.json documentation:

{
  "moduleHint": {
    "matchedCommands": ["dht22"],
    "modules": [
      {
        "name": "dht22",
        "functions": [
          {
            "name": "measure",
            "signature": "measure log=False",
            "doc": "Measure with dht22"
          }
        ]
      }
    ]
  }
}

The hint is derived from cached discovery data and may be present in both successful and failed command responses. It is omitted unless the first token of the first command matches a module exactly; a module appearing only in a later pipeline command does not produce a hint.

set_device_note

Store persistent context about a device, such as location, attached peripherals, wiring, or command interpretation hints:

{
  "deviceTag": "TerraceSensor",
  "note": "Mounted on the terrace. DHT22 readings are outdoor temperature and humidity.",
  "mode": "replace"
}

Use mode: "append" to add a line without replacing the existing note. Omit note or send an empty value to return the current note without changing it. Notes are stored by device name in data/device_notes_cache.json, survive feature rediscovery, and are shown by list_devices and search_devices.

search_devices

Use this as the primary device selection tool when you know part of a device name or part of a capability:

{
  "query": "dht22"
}

The query searches cached device identity fields, persistent device notes, and cached feature metadata, including module names and complete function signatures. Set fuzziness to 0 for literal substring matching, 1 for conservative typo tolerance (the default), or 2 for broader matching. Very short queries remain strict at the lower levels to avoid noisy results.

Multi-word searches use two passes. The complete query is tried first and its results are returned when any device matches. If it returns no devices, the tool retries with each individual word and returns devices matching any word. The response reports matchMode as query or words and lists the effective matchedTerms.

For each matching device, modules are selected using both the active query terms and words longer than two characters from its device note. Irrelevant modules are removed, while every selected module retains its complete function signatures. Each returned function also includes name and, when found in data/sfuncman.json, doc.

Common use cases:

  • Device identity: {"query":"TerraceSensor","fuzziness":0} for a precise name, UID, or IP fragment.

  • Capability: {"query":"brightness"} to find devices whose cached module signatures expose brightness control.

  • Persistent context: {"query":"outdoor temperature"} to search device notes as a phrase, then as outdoor or temperature only when the phrase has no matches.

  • Misspelling recovery: {"query":"temprature","fuzziness":1} for conservative typo tolerance.

  • Broad recovery: {"query":"kitchn diming","fuzziness":2} when multiple words may be misspelled.

  • Live availability: add "status":"online" to return only currently reachable matches.

Require live status while searching:

{
  "query": "Terrace",
  "status": "online"
}

In the tester UI, status defaults to Any; choosing online or offline performs live TCP checks only for cached devices matching the text query.

discover_devices

{
  "networkPrefix": "10.0.1",
  "startHost": 2,
  "endHost": 254,
  "port": 9008,
  "timeoutMs": 1000,
  "concurrency": 50,
  "refreshFeatures": true,
  "featureTimeout": 3,
  "featureConcurrency": 3
}

If networkPrefix is omitted, the server uses MICROS_NETWORK_PREFIX when set, otherwise the active local IPv4 interface. Startup logs whether the scan prefix was native auto-detected or injected through the environment for container mode.

Discovery is a fresh network scan every time this tool runs. By default, it also refreshes the feature cache for newly discovered devices, but the tool response stays compact with module and command counts rather than full function details. Set refreshFeatures to false when you only want to update device addresses. Use featureConcurrency to control how many discovered devices are inspected in parallel during feature refresh.

discover_commands

All cached devices:

{}

One device by UID, IP, or partial device name:

{
  "deviceTag": "TinyDevBoard"
}

The feature cache stores each module once with compact signature strings. The response expands each function with its parsed name and optional reference documentation:

{
  "name": "gameOfLife",
  "functions": [
    {
      "name": "load",
      "signature": "load w=32 h=16 custom=None",
      "doc": "Load an initial state."
    },
    {
      "name": "next_gen",
      "signature": "next_gen w=32 h=16 raw=False"
    }
  ]
}

Discovery requests <module> help >json and parses the returned JSON signature array, with a text fallback for older firmware. Response documentation is matched by module name and the first word of each signature; lookup is case-insensitive as a fallback. A missing manual, module, function, null doc, or invalid manual does not fail the tool: the doc field is simply omitted. Override the manual path with MICROS_FUNCTION_MANUAL_PATH. Legacy caches containing raw help and flattened commands are normalized into the compact structure when read. Each discovery result uses the same top-level uid, ip, port, deviceName, and deviceNote fields as other device tools.

Use password if the device requires micrOS app authentication.

How Tools Are Defined

Each MCP tool is defined in one file under mcp/tools/ plus one adjacent Markdown description file. The TypeScript file owns:

  • the business function, such as runCommand(...)

  • the MCP definition object, such as runCommandTool

The file basename is the metadata source of truth: mcp/tools/run-command.ts becomes the MCP tool run_command with title Run Command. The adjacent mcp/tools/run-command.md file owns the MCP-facing tool description. This keeps each tool standalone while allowing the generic MCP registrar to discover tools dynamically.

Server-level MCP instructions are stored in mcp/description.md and loaded at startup. The tester chat system prompt is stored separately in ui/chat-system-prompt.md. mcp/mcp-tools.ts only discovers tool modules, registers the collected definitions, and formats MCP responses. Generic MCP helper code lives in mcp/tool-definition.ts, mcp/tool-loader.ts, and mcp/tool-registry.ts. mcp/tools.ts is the public barrel for tool functions, tool definitions, and shared types.

The rough call path is:

MCP client
  -> mcp/index.ts
  -> registerMcpTools() in mcp/mcp-tools.ts
  -> loadToolDefinitions() in mcp/tool-loader.ts scans mcp/tools/
  -> focused definition + implementation in mcp/tools/<tool-name>.ts
  -> description text from mcp/tools/<tool-name>.md
  -> shared micrOS helpers in mcp/tools/common.ts when needed

Add A New Tool

  1. Create a focused tool file under mcp/tools/, for example mcp/tools/reboot-device.ts.

  2. Define the tool input type in that same file. Put types in mcp/tools/common.ts only when they are genuinely shared helper types.

  3. In the same file, export the business function and an McpToolDefinition.

  4. Add mcp/tools/reboot-device.md with the MCP-facing description.

  5. Export the function and definition from mcp/tools.ts when other code or tests should import them directly.

  6. Add a short README entry in the tool table or tool examples.

  7. Run npm run start:test for focused contract tests and project entrypoint checks.

Implementation example:

// mcp/tools/example-tool.ts
import { z } from "zod";
import { cacheToDevices, readDeviceCache } from "./common.js";
import { defineTool } from "../tool-definition.js";

export type ExampleToolInput = {
  query?: string;
};

export async function exampleTool(input: ExampleToolInput = {}) {
  const cache = await readDeviceCache();
  const devices = cacheToDevices(cache);

  return {
    query: input.query ?? null,
    count: devices.length,
    devices
  };
}

export const exampleToolDefinition = defineTool<ExampleToolInput>(import.meta.url, {
  inputSchema: {
    query: z.string().optional().describe("Optional filter text.")
  },
  handler: exampleTool
});

Description file:

Describe what the tool does for MCP clients and humans.

Barrel export:

// mcp/tools.ts
export type { ExampleToolInput } from "./tools/example-tool.js";
export { exampleTool, exampleToolDefinition } from "./tools/example-tool.js";

Tool responses should be JSON-serializable objects. If a tool can fail in a controlled way, prefer returning { ok: false, error: "..." }; the generic registrar in mcp/mcp-tools.ts marks those responses as MCP errors when appropriate.

Device Cache

Default cache path:

data/device_conn_cache.json

Cache format:

{
  "device_uid": {
    "ip": "ip-address",
    "port": 9008,
    "deviceName": "device-name"
  }
}

If the cache is missing or invalid, the server creates it with these defaults:

  • __devuid__: 192.168.4.1, port 9008, device name __device_on_AP__

  • __localhost__: 127.0.0.1, port 9008, device name __simulator__

The first cache read also attempts one automatic discovery and continues with whatever cache is available. Discovery is additive: it updates discovered devices but does not delete stale cached entries.

At MCP startup, the server runs an initialization pass that scans for devices, then discovers each cached device's modules and functions. Successful feature discoveries are persisted in:

data/device_feature_cache.json

Feature cache entries contain only discovery data. Device names remain in the connection cache, and user notes remain in the notes cache, avoiding duplicated fields across runtime files. Legacy three-element connection arrays and feature records with duplicated metadata are migrated and overwritten in the compact format when read.

Persistent user notes are stored separately by device name in:

data/device_notes_cache.json

Optional function documentation is read from the static data/sfuncman.json reference file. It enriches search_devices, discover_commands, and command module hints without being copied into the feature cache.

list_devices stays compact: it includes device identity, persistent notes, and known module names, but not function-level feature details. Use search_devices as the normal device and capability lookup before run_command, and discover_commands when cached module/function details need refreshing. Startup progress is logged to stderr so MCP stdout remains protocol-safe while clients can show that discovery is pending. Set MICROS_INITIALIZE_ON_START=0 to skip startup initialization, for example when you need the stdio server to start without touching the network.

Docker

Build and export a standalone Docker image archive:

npm run docker:build

Defaults:

image: micros-mcp:latest
export: dist/micros-mcp_latest.tar.gz

The exported archive is a standard docker save artifact. Load it with docker load on another machine, then run the micros-mcp:<tag> image.

Customize:

npm run docker:build -- --image micros-mcp:dev
npm run docker:build -- --output dist/micros-mcp.tar
npm run docker:build -- --image micros-mcp:dev --output dist/micros-mcp_dev.tar.gz

Install an exported image on another machine:

docker load -i dist/micros-mcp_latest.tar.gz

Publish a public Docker Hub image:

docker login
docker build -t bxnxm/micros-mcp:latest .
docker push bxnxm/micros-mcp:latest

For a public multi-architecture image that supports common 64-bit Intel/AMD and ARM hosts, build and push with buildx:

docker login
docker buildx create --use
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t bxnxm/micros-mcp:latest \
  --push \
  .

The archive workflow above exports the image for the local Docker builder's platform. The buildx publish flow creates a registry manifest so compatible hosts pull the right architecture automatically.

Run as stdio MCP in Docker:

docker run --rm -i -e MICROS_NETWORK_PREFIX=10.0.1 -v micros-mcp-data:/app/data micros-mcp:latest mcp

Run the tester UI endpoint in Docker:

docker run --rm -p 3333:3333 -e MICROS_NETWORK_PREFIX=10.0.1 -e MICROS_UI_CERT_HOSTS=gateway.local,10.0.1.42 -v micros-mcp-data:/app/data micros-mcp:latest ui

Set MICROS_NETWORK_PREFIX to your LAN /24 prefix, such as 10.0.1. In native host mode this prefix is auto-detected; in Docker mode it must be injected because the container usually sees Docker's network interface instead of your LAN interface.

Persist the device cache:

docker volume create micros-mcp-data

docker run --rm -i -e MICROS_NETWORK_PREFIX=10.0.1 -v micros-mcp-data:/app/data micros-mcp:latest mcp

OR

docker run --rm -p 3333:3333 -e MICROS_NETWORK_PREFIX=10.0.1 -e MICROS_UI_CERT_HOSTS=gateway.local,10.0.1.42 -v micros-mcp-data:/app/data micros-mcp:latest ui

Image contents:

  • Included: compiled MCP server in dist/mcp, compiled optional UI server in dist/ui, UI static assets in ui/assets, the static function manual, scripts/start.mjs, package.json, and production node_modules.

  • Generated at runtime: /app/data. The image creates this as an empty directory.

  • Excluded from the Docker build context: runtime files under data/, dist/, node_modules/, Git metadata, and local archive files. Only data/sfuncman.json is admitted as static reference data; device caches, device notes, certificates, and optional UI chat config files are not copied from the local checkout into the image.

Docker network notes:

  • Native mode: the server auto-detects the active local IPv4 prefix and logs it as native/auto-detected.

  • Docker mode: pass MICROS_NETWORK_PREFIX and the server logs it as containerized/injected.

  • If Docker still cannot find devices, confirm the container can route TCP traffic to micrOS devices on port 9008. Docker Desktop, host firewalls, VPNs, or Wi-Fi client isolation can block this even when the prefix is correct.

  • Native and Docker UI modes bind to 0.0.0.0:3333 by default so LAN access and published container ports work consistently. The tester has no authentication; expose it only on trusted networks, or override native mode with HOST=127.0.0.1. Omitting MICROS_UI_CERT_HOSTS does not enable HTTP.

  • A container normally sees its own addresses rather than the Docker host's LAN address. Add every host LAN IP or DNS name used by clients to MICROS_UI_CERT_HOSTS, such as gateway.local,10.0.1.42.

  • Ensure names such as gateway.local resolve to the Docker host, then open https://gateway.local:3333. Without a matching certificate entry, browsers report a hostname mismatch.

  • Mount /app/data as a persistent volume to reuse the generated certificate across container restarts and avoid unnecessary certificate warnings.

Docker MCP client config:

{
  "mcpServers": {
    "microsmcp": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "MICROS_NETWORK_PREFIX=10.0.1",
        "-v",
        "micros-mcp-data:/app/data",
        "micros-mcp:latest",
        "mcp"
      ]
    }
  }
}

Architecture

MCP means Model Context Protocol. It lets a client application start this server, list available tools, and call them with structured JSON arguments.

For this project, MCP is the adapter layer between a client and micrOS devices:

MCP client -> stdio -> micrOSMCP -> TCP socket -> micrOS device

The implementation mirrors the useful behavior of micrOS socketClient.py and micrOSClient.py, but it is standalone TypeScript and does not call Python.

Project structure:

  • mcp/: standalone MCP stdio server. This owns tool registration, tool definitions, micrOS socket/discovery helpers, and the public tool barrel.

  • ui/: tester mini app. This owns the local HTTPS bridge, optional AI chat bridge, and static browser assets under ui/assets/.

  • data/: local runtime state plus the tracked static sfuncman.json function reference. Connection, feature, note, certificate, and optional UI chat config files live here by default and are ignored by git.

  • scripts/: operational entrypoints for start modes, Docker image export, and minimal tests.

  • Dockerfile: minimal runtime image for stdio MCP or the tester UI endpoint.

Runtime flow:

  1. MCP client calls a tool, for example run_command.

  2. mcp/index.ts starts the MCP server and registers tools through mcp/mcp-tools.ts.

  3. mcp/mcp-tools.ts asks mcp/tool-loader.ts to discover tool modules from mcp/tools/.

  4. The matching file under mcp/tools/ owns the Zod schema, reads the cache, selects a device, opens a TCP socket if needed, and performs the micrOS operation.

  5. The result is serialized as formatted JSON text and returned to the MCP client.

Requirements

  • Node.js 20 or newer.

  • Network access from the host or container to micrOS devices on TCP port 9008.

  • Docker, only if you want to build or run the container image.

Available Tools

6 tools
discover_commandsDiscover CommandsA

Learn which modules and command signatures are available on live micrOS devices. Use this after discovering a device, after its firmware or modules change, or when search_devices does not show an expected capability. Omit deviceTag to inspect all known devices, or provide a UID, IP address, or device name fragment to inspect matching devices. Use password when micrOS app authentication is enabled.

ParametersJSON Schema
NameRequiredDescriptionDefault
timeoutNoSocket timeout in seconds. Defaults to 10.
verboseNoEnable verbose micrOS client logging.
passwordNoOptional micrOS app password if auth is enabled.
deviceTagNoOptional device UID, IP address, or partial device name. Omit to inspect all cached devices.
concurrencyNoMaximum devices to inspect in parallel when deviceTag is omitted. Defaults to 3.

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It adds useful context about scoping (all vs. matching devices) and authentication (password). However, it does not explicitly state that this is a read-only operation or disclose potential side effects, failure modes, or return behavior. This is a notable gap given the lack of annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences, front-loaded with the primary purpose. It includes specific, useful details without any fluff. Each sentence earns its place, covering purpose, usage context, and parameter behavior efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description explains the tool's purpose and usage well, but it lacks detail on return values or output format, which is especially important given there is no output schema. It also does not distinguish itself from list_devices/discover_devices beyond mentioning search_devices. Overall, it is adequate but with clear gaps in completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all parameters are documented in the schema. The description restates the deviceTag behavior (omitting it inspects all, providing UID/IP/name fragment inspects matching) but does not add significant meaning beyond what the schema already provides. The baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Learn which modules and command signatures are available on live micrOS devices.' It uses a specific verb ('Learn') and resource ('modules and command signatures'), and differentiates from sibling tools like search_devices by focusing on command discovery rather than device discovery.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides usage context: 'Use this after discovering a device, after its firmware or modules change, or when `search_devices` does not show an expected capability.' It also gives scoping instructions (omit deviceTag for all devices, provide UID/IP/name fragment for matching) and notes when to use the password parameter, making it clear when and how to invoke the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discover_devicesDiscover DevicesA

Find live micrOS devices on a local IPv4 /24 network. Use this during initial setup, when a device is missing from list_devices, or when its IP address may have changed. Omit networkPrefix to scan the active local network, or provide a prefix such as 10.0.1. By default, the tool also learns the commands available on discovered devices; set refreshFeatures to false when only device discovery is needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
portNomicrOS service port. Defaults to 9008.
endHostNoLast host number to scan. Defaults to 254.
verboseNoEnable verbose micrOS client logging during feature discovery.
passwordNoOptional micrOS app password for feature discovery if auth is enabled.
startHostNoFirst host number to scan. Defaults to 2.
timeoutMsNoPer-host socket timeout in milliseconds. Defaults to 1000.
concurrencyNoParallel connection checks. Defaults to 50.
networkPrefixNoIPv4 /24 prefix to scan, such as 10.0.1. Defaults to the active local network.
featureTimeoutNoSocket timeout in seconds for feature discovery after devices are found. Defaults to 3.
refreshFeaturesNoRefresh module/function feature cache for newly discovered devices. Defaults to true.
featureConcurrencyNoMaximum discovered devices to inspect in parallel while refreshing features. Defaults to 3.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden. It discloses the side effect of feature learning ('By default, the tool also learns the commands available on discovered devices') and explains networkPrefix behavior. However, it stops short of detailing network impact or permission requirements, so it's not fully rich but is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences: purpose, usage scenarios, and key behavioral toggle. Every sentence earns its place, concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter tool with no output schema, the description covers the critical decisions (when to use, networkPrefix, refreshFeatures) while other parameters are well documented in the schema. Missing return-value details but adequate for selection and invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaning to key parameters by explaining that omitting networkPrefix scans the active local network and setting refreshFeatures to false avoids feature learning. This goes beyond the schema's literal field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Find live micrOS devices on a local IPv4 /24 network.' It uses a specific verb and resource, and the mention of device discovery distinguishes it from siblings like list_devices and search_devices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit usage guidance is provided: 'Use this during initial setup, when a device is missing from list_devices, or when its IP address may have changed.' It also contrasts with list_devices and gives a when-not for refreshFeatures, offering clear contextual direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_devicesList DevicesA

Show a quick inventory of known micrOS devices, including each device's UID, name, address, note, and module names. Use this to see what devices are known without checking whether they are currently online. Use search_devices when selecting a command target, finding a capability, or inspecting command signatures.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It discloses that the tool does not check online status ('without checking whether they are currently online') and implies a read-only listing ('Show a quick inventory'). While it doesn't explicitly state side-effect-freedom or permissions, the nature of a read-only inventory is clear, so only a small gap remains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The purpose is front-loaded, and usage guidance is concise. The format is ideal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list tool with no parameters and no annotations, the description fully covers the tool's purpose, output content, and distinguishing usage. The sibling distinction adds necessary context. No important information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is trivially 100%. The baseline for 0 parameters is 4, and the description adds no parameter info because there are none to describe. No deductions are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Show a quick inventory of known micrOS devices' with specific fields listed. It also distinguishes itself from the sibling `search_devices`, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use guidance is provided: 'Use this to see what devices are known without checking whether they are currently online.' It also names the alternative tool and its use cases: 'Use `search_devices` when selecting a command target, finding a capability, or inspecting command signatures.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_commandRun CommandA

Run a micrOS command or a sequential command pipeline on one live device. Before using this tool, call search_devices to confirm the exact device and relevant command signature. Target the device by its exact UID, device name, or IP address.

Command syntax examples:

  • No arguments: version

  • Positional argument: conf webui

  • Module function: dht22 measure

  • Keyword argument: dht22 measure log=True

  • String pipeline: rgb status <a> dht22 measure

  • Array pipeline: ["version", "dht22 measure"]

For a string pipeline, <a> separates commands by default; separator can select a different delimiter. For an array pipeline, each array item is one command and runs in order.

Commands act on a real device and may change its state. Configuration reads such as conf and conf webui are allowed, but configuration writes such as conf webui true are rejected. Other commands are not automatically made safe, so use the least disruptive command that fulfills the request.

ParametersJSON Schema
NameRequiredDescriptionDefault
commandYesThe command or command pipeline to run. String commands may use the <a> separator. Unsafe command forms are denied before connecting to a device.
timeoutNoSocket timeout in seconds. Defaults to 10.
verboseNoEnable verbose micrOS client logging.
passwordNoOptional micrOS app password if auth is enabled.
deviceTagYesThe exact micrOS device UID, device name, or IP address to target.
separatorNoOptional string command separator. Defaults to <a>.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavioral disclosure. It clearly warns that commands act on a live device, may change state, config writes are rejected, and other commands are not automatically safe. This provides strong safety-relevant context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear examples and sections. Every sentence adds value, covering syntax, prerequisites, and safety without unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with six parameters, no annotations, and no output schema, the description covers purpose, prerequisites, syntax variations, safety constraints, and behavioral expectations thoroughly. No significant gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds meaningful syntax examples, explains the `<a>` separator and array pipeline behavior, and confirms deviceTag can be a UID, name, or IP, going beyond the schema's field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states 'Run a micrOS command or a sequential command pipeline on one live device.' This is a specific verb+resource description that distinguishes the execution tool from sibling discovery/listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to call `search_devices` before using the tool to confirm the exact device and command signature. It also cautions to use the least disruptive command, but does not explicitly contrast with all sibling alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_devicesSearch DevicesA

Find the right micrOS device and command syntax before run_command. Search by a device UID, name, IP address, note, module, function, or capability phrase. Results identify matching devices and show relevant modules with their complete function signatures and available documentation. Use fuzziness 0 for literal matching, 1 for conservative typo tolerance, or 2 for broader recovery. Set status to online or offline when live reachability matters. If a device or capability is missing, use discover_devices or discover_commands, then search again.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesDevice or capability text to search across cached identity, notes, modules, and complete function signatures. Multi-word queries retry with individual words only when the full query has no matches.
statusNoOptional live reachability requirement. Omit for any status.
fuzzinessNoSearch tolerance: 0 uses literal substrings, 1 allows close spellings (default), and 2 is broader.
includeStatusNoCheck live online/offline status for matched devices.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations or output schema are provided, so the description carries the behavioral burden. It discloses search scope, fuzziness semantics, status filtering, and fallback behavior. It does not describe the exact result envelope or explicitly state read-only safety, but it provides substantial behavioral context beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with purpose and usage context. Every sentence adds decision-relevant information with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema or annotations, the description covers the tool's domain, parameter choices, use timing, and fallback paths. The only gap is a precise description of the returned data structure, but the description states that results include devices and modules with function signatures and documentation, which is sufficient for invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The description adds value by listing searchable fields and explaining fuzziness levels (0 literal, 1 conservative typo, 2 broader) and when status is relevant. This goes beyond the schema's property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Find the right micrOS device and command syntax before run_command.' It enumerates searchable attributes (UID, name, IP, note, module, function, capability) and distinguishes itself from sibling discovery/command tools by focusing on searching cached data to prepare for execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is explicit: use this before run_command. It names alternatives (discover_devices and discover_commands) for missing devices/capabilities and directs the user to search again after discovery. It also clarifies when status filtering matters.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_device_noteSet Device NoteA

Read or save helpful context about one micrOS device, such as its location, attached hardware, purpose, or how its readings should be interpreted. Target the device by UID, IP address, or an unambiguous name fragment. Omit note or pass an empty string to read the current note. Provide a note with mode: "replace" to replace the current text or mode: "append" to add a new line.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoHow to update the note. Defaults to replace.replace
noteNoNote text to store. Omit or send an empty value to return the current note without changing it.
deviceTagYesDevice UID, IP address, or unambiguous partial device name.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the transparency burden. It discloses the read vs. write behavior, explains that omitting note or using an empty string reads the current note, and details the difference between replace and append modes. However, it does not describe the return format or any potential side effects beyond overwriting in replace mode.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with the main purpose, and each sentence adds essential information without repetition or fluff. It is compact and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no annotations, the description covers the main behaviors and parameter semantics well. It omits the return format when reading, but the intent is implied. Given the tool's simplicity, this is a minor gap that keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds meaningful context: it explains that deviceTag can be a UID, IP, or name fragment, and it clarifies the behavior of the note parameter (omit/empty for read) and mode parameter (replace vs append). This goes beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb-resource combination: 'Read or save helpful context about one micrOS device.' It provides concrete examples of the content (location, hardware, purpose) and distinguishes itself from sibling tools like list_devices or run_command by focusing specifically on device notes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context on when to use the tool: for reading or saving device context. It explains how to target a device and the modes for updating, but it does not explicitly name alternatives or state when not to use it. This is clear but lacks explicit exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 6 tool updatesv0.1.0
    • First observeddiscover_commands
    • First observeddiscover_devices
    • First observedlist_devices
    • First observedrun_command
    • First observedsearch_devices
    • First observedset_device_note

TDQS

A4.4/5.0
Disambiguation4/5

Each tool has a distinct role, but list_devices and discover_devices both show device inventories, and search_devices and discover_commands both surface command signatures. The descriptions clarify the differences (known vs. live scan, indexed vs. live query), so selection should be reliable.

Naming Consistency5/5

All tool names use a consistent snake_case verb_noun pattern (list_devices, discover_commands, discover_devices, run_command, search_devices, set_device_note). The two discover_* tools are differentiated by their object, maintaining clarity.

Tool Count5/5

Six tools is well-scoped for a device management server, covering discovery, inventory, command lookup, execution, and note-taking without unnecessary bloat. Each tool earns its place.

Completeness5/5

The tool surface covers the full lifecycle of interacting with micrOS devices: discovering devices on the network, listing known devices, searching for capabilities, learning command signatures, executing commands, and annotating device context. No obvious dead ends or missing core operations.

Maintenance

ActivityStale
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A demonstration MCP server built in TypeScript that shows how to implement stdio-based communication for integration with MCP clients. Serves as a template for building custom MCP servers with strong typing and maintainability.
    -
  • F
    license
    A
    quality
    D
    maintenance
    A TypeScript MCP server for launching, tracking, and managing external coding-agent runs across local and remote backends like Codex and Claude Code. It allows top-level agents to orchestrate subagents through tools for spawning tasks, polling events, and handling interactive sessions.
    7
    2
    -
  • A
    license
    B
    quality
    D
    maintenance
    Production-ready TypeScript MCP server exposing utility, GitHub, and Microsoft Teams tools over stdio.
    14
    1
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    MCP server for controlling MicroPython devices (ESP32, RP2040, etc.) via USB Serial or WebREPL, enabling code execution, file operations, and device management from MCP clients.
    9
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/BxNxM/micrOSMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server