npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@minicor/mcp-server

v4.0.0

Published

Desktop and browser RPA automation, workflow management, and AI-powered debugging for the Minicor platform. Formerly Laminar.

Readme

Minicor MCP Server

Build, deploy, and debug VM-based browser and desktop automations from Cursor or Claude Code. The AI agent connects to your Windows VM, writes Python automation scripts, tests them through the Minicor executor, and deploys production-ready workflows - with skills accumulated from every build.

Quick Start

1. Install

Cursor - add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "minicor": {
      "command": "npx",
      "args": ["-y", "@minicor/mcp-server"]
    }
  }
}

Claude Code - no global install needed (npx always runs the latest):

claude mcp add minicor -- npx -y @minicor/mcp-server

2. Authenticate

npx -y -p @minicor/mcp-server minicor-mcp-setup

Opens a browser to sign in. Tokens are stored at ~/.minicor/tokens.json with auto-refresh. For headless / SSH:

npx -y -p @minicor/mcp-server minicor-mcp-setup --cli

The package ships multiple commands. Always use npx -p @minicor/mcp-server <command> to run a specific one (minicor-mcp-setup, minicor-bootstrap, …). Running npx @minicor/mcp-server alone only starts the MCP server and ignores trailing arguments.

Hosted MCP (cloud, no install)

The same server also runs hosted at https://mcp.minicor.com/mcp (Streamable HTTP). Sign-in is your Minicor email/password through an OAuth flow - no API keys, no local tokens. The tool set matches the local server except for the tools that read and write your local disk (workspace clones, sessions, sync); those require the local install above.

Claude (web / Desktop / mobile):

  1. Go to Settings > Connectors > Add custom connector.
  2. Paste https://mcp.minicor.com/mcp and save. OAuth is auto-discovered - no client ID or secret.
  3. Claude opens the Minicor sign-in page. Enter your email, password, and region (US/Canada). Done - the connector acts as your account.

Claude Code:

claude mcp add --transport http minicor-cloud https://mcp.minicor.com/mcp

Then run /mcp inside Claude Code to trigger the OAuth sign-in.

Cursor - add a URL-based entry to ~/.cursor/mcp.json (Cursor prompts for the OAuth sign-in on first use):

{
  "mcpServers": {
    "minicor-cloud": {
      "url": "https://mcp.minicor.com/mcp"
    }
  }
}

Access tokens expire within an hour and refresh automatically for up to 30 days; after that you sign in again. To self-host the same endpoint (or restrict sign-in to your email domain), see docs/HOSTED.md.

Older installs may have a separate minicor-builder entry in their MCP config. That server was folded into minicor; re-running minicor-mcp-setup removes the stale entry.

3. Bootstrap Workspace (optional)

After cloning a workspace, generate harness-specific config files:

# For Claude Code - creates CLAUDE.md + .claude/settings.local.json
npx -y -p @minicor/mcp-server minicor-bootstrap claude-code --dir ./my-workspace

# For Cursor - creates .cursor/rules/workspace.mdc
npx -y -p @minicor/mcp-server minicor-bootstrap cursor --dir ./my-workspace

# All harnesses at once
npx -y -p @minicor/mcp-server minicor-bootstrap all --dir ./my-workspace

4. Update

npx users: restart your editor (auto-fetches latest). Global: npm update -g @minicor/mcp-server.

5. Uninstall

Remove the MCP server entry from your editor first:

Cursor - edit ~/.cursor/mcp.json and remove mcpServers.minicor, plus any legacy mcpServers.laminar or mcpServers.minicor-builder entry.

Claude Code - remove the registered server:

claude mcp remove minicor

If the command is unavailable, remove the minicor MCP server entry from your Claude Code MCP config.

Then remove local credentials and config:

rm -rf ~/.minicor

If this machine has an older Laminar install and you no longer need it:

rm -rf ~/.laminar

If you installed the package globally instead of using npx:

npm uninstall -g @minicor/mcp-server

Workspace clones are not removed by these commands.

Code Mode (experimental, opt-in)

By default the server exposes every Minicor operation as its own MCP tool. As an experimental alternative, you can enable a code-mode surface: a single codemode tool that runs JavaScript and provides Minicor methods as async functions on the minicor global.

Enable it by setting the environment variable before launching the server:

EXPERIMENTAL_USE_CODE_MODE=1 minicor-mcp

In Cursor, add it to the server's env block in ~/.cursor/mcp.json:

{
  "mcpServers": {
    "minicor": {
      "command": "npx",
      "args": ["-y", "@minicor/mcp-server"],
      "env": { "EXPERIMENTAL_USE_CODE_MODE": "1" }
    }
  }
}

Once enabled:

const workspaces = await minicor.list_workspaces({});
const matches = await codemode.search("workflow");
const docs = await codemode.describe("minicor.create_rpa_flow");
return { workspaces, matches, docs };

This follows Cloudflare's Code Mode pattern: the model writes code that chains tool calls, branches, loops, and composes results locally instead of making one model round trip per operation.

Inside codemode:

  • await minicor.tool_name({ ... }) calls a Minicor MCP operation.
  • await codemode.search("query") discovers relevant methods.
  • await codemode.describe("minicor.tool_name") returns TypeScript-style parameter docs.
  • await codemode.list() lists all available methods.

Unset EXPERIMENTAL_USE_CODE_MODE to return to the default one-tool-per-operation surface.

Session Lifecycle

The MCP server sends instructions to every client on connect, telling agents to start a session first when in a workspace clone. Call the session_start tool with the workspace directory:

session_start({ directory: "/path/to/workspace" })

(With experimental code mode enabled, run the same call as await minicor.session_start({ ... }) through the codemode tool.)

This works across all harnesses, including Claude Code, Cursor, and Bedrock.

Session Tools

| Tool | What it does | | --- | --- | | session_start | Load workspace context (AGENTS.md, VMs, skills, issues, prior session). Call FIRST in a workspace clone. | | session_checkpoint | Save progress mid-session. Writes .minicor/session.json + syncs [Workspace:Session] issue. | | session_end | Persist final state, sync to platform, optionally update context.md. Call before ending work. | | set_workspaces_root | Set default root directory for cloning workspaces (saved to ~/.minicor/config.json). |

Auto-Save on Disconnect

If the agent crashes or the user closes the IDE, the server auto-checkpoints with status: "interrupted" so no session state is lost. The next agent resumes from that checkpoint.

Multi-Agent Handoff

Sessions are synced to [Workspace:Session] issues on the platform, so agents on other machines (or scheduled Bedrock agents) can resume where the last agent left off.

The RPA Lifecycle

This is the complete flow from zero to production automation. The agent handles each phase using MCP tools and skills. Workflows are built and tested inside a Job (see Jobs below): the job's test cases are written before the workflow exists and are the definition of done for the whole build.

Phase 1: Workspace Setup

"Create a workspace for Acme Corp and set up a VM"
  • create_workspace / list_workspaces / get_workspace - create or find a workspace
  • vm_list - discover available VMs
  • deploy_vm - provision a new Windows VM if needed
  • install_mds_on_vm / start_mds_on_vm - install the Minicor Desktop Service
  • vm_connect - connect to the VM via Cloudflare tunnel

Phase 2: Clone Workspace

"Clone workspace 257 to my local folder"
  • clone_workspace - pulls everything to a local folder:
    • minicor.json - workspace manifest
    • workflows/ - all workflow steps as files (git-native)
    • .minicor/skills/general/ - bundled RPA skills
    • .minicor/skills/workspace/ - workspace-specific learned skills
    • .minicor/issues/ - agent-persisted context from previous runs
    • .minicor/skill-index.json - compact skill summary
    • .minicor/workspace.json - workspace metadata

The folder is git-ready. Push to GitHub for version control, diffs, and CI/CD.

Phase 3: Scope & Define the Green-Gate

"I want to automate patient lookup in Centricity"

The agent:

  • Takes screenshots, inspects UI elements, identifies the app framework
  • Loads relevant skills: get_skill("job-build-loop"), then get_skill("cdp-browser-automation") or get_skill("desktop-uiautomation")
  • Checks list_skills() for customer-specific skills (e.g., "centricity-quirks")
  • Studies existing workflows via get_workflow_overview
  • Determines strategy: CDP browser, desktop uiautomation, or hybrid
  • Writes the test cases before building. register_job (a thin job whose workflow step will call the new workflow) plus teach_job or add_test_case with a real input and assertions. These cases start red; the rest of the lifecycle exists to turn them green.

Phase 4: Build (Iterative)

For each automation step:

  1. Observe - vm_screenshot + vm_inspect_ui to map the UI
  2. Write - Python script using patterns from loaded skills
  3. Prototype - vm_execute_script to test on the VM directly
  4. Save - create_rpa_flow to persist as a Minicor workflow step
  5. Test through Minicor - execute_workflow_async with start_from_step/end_at_step to verify the step works through the real executor (config variables, data passing, JS wrapper)

The testing step is critical - vm_execute_script doesn't resolve {{config.*}} variables or data.input interpolation. The agent loads get_skill("rpa-testing-workflow") for exact tool call sequences.

Phase 5: Test End-to-End, Then Green-Gate the Job

After all steps pass individually:

  • execute_workflow_async with real inputs + configurationId - full workflow, no step isolation
  • Poll get_execution_status + vm_screenshot to monitor
  • diagnose_execution on failure, fix with update_flow, re-run
  • The workflow is not done until it passes end-to-end through the Minicor executor

Then close the loop at the job level:

  • Point the job's workflow step at the finished workflowId (update_job variant=draft). If the workflow was edited in Dev Mode, dev_mode_publish first - jobs execute published workflows, not drafts.
  • run_tests variant=draft - the test cases from Phase 3 are the pass/fail verdict for the build
  • On a red case, resolve_job_state / inspect_job_execution locate the failing step; replay just that slice with run_job (fromStepId + seedExecutionId) or drop back into the workflow, fix, re-run
  • When the suite is green, publish_job puts it live at /m/:slug/:path

Phase 6: Production Hardening

For production workflows (not POCs):

  • Load get_skill("state-verification") - add expectedPreState/expectedPostState to each step
  • Run the workflow twice to verify idempotency
  • create_agent with mode: "monitor" + watchWorkflowId for failure monitoring
  • create_agent with mode: "scheduled" + cron for recurring runs
  • Persist context: create_issue with [Agent:<name>] Rules for cross-run learning

Phase 7: Extract & Share Knowledge

After a successful build:

  • generate_skill - gathers workflow code, execution history, and agent issues
  • The agent analyzes patterns and calls save_skill to persist them
  • Skills are stored per-workspace and available to future builds
  • Customer-specific quirks become reusable knowledge

Jobs (RPA orchestration)

A Job is a middleware route whose behavior is a structured definition (a step graph) instead of freeform handler code. Jobs sit above workflows: a job step either calls an entire Minicor workflow (kind: "workflow", by workflowId) or runs a code block (kind: "code"). The job never touches a workflow's internal steps - a workflow is an opaque callable with an input and an output. A job is the macro zoom (what ran, status, replays); a workflow → step is the microscope. This is the layer that turns one or more workflows into a versioned, testable, observable API endpoint.

The job tools

| Tool | What it does | | --- | --- | | resolve_job_state | The first call to make when picking up a job. Returns the job's state (draft vs published, test cases, latest test run, recent executions, active build) plus nextActions - the concrete next tool calls. A red test run is drilled automatically: failing case → failing step → its workflowId (a dev_mode_load hint) → a seeded fromStepId replay command. | | list_middlewares | List the routers (middlewares) in a workspace - jobs attach to one of these. | | register_middleware | Create a router jobs attach to. autoConfigure (default true) populates the router's workspaceApiKey from the workspace's first key; or pass workspaceApiKey explicitly. | | register_job | Create a job - a route backed by a structured definition (step graph). | | update_job | Update a job's definition, path, method, or description. variant: "draft" writes the draft definition (the teach/build working copy); variant: "published" (default) edits the live definition and snapshots a new route version. | | get_job | Get a job (route) incl. its definition (and draftDefinition when one exists); omit routeId to list all routes on the router. | | run_job | Run a job once with an input, poll to completion, return the full JobExecution (per-step Minicor deep-links). variant: "draft" runs the draft definition. For step-range debugging, fromStepId / toStepId (both inclusive) run a slice of the step graph, and seedExecutionId hydrates ctx from a prior execution so mid-graph starts still resolve earlier steps' values. waitForResult: false returns the jobExecutionId immediately for runs you want to stop or monitor. | | stop_job_execution | Stop a queued/running execution. This is a cooperative cancel (there is no pause): a queued run cancels immediately; a running one stops at the runner's next checkpoint (between steps, between forEach items, or while waiting on a workflow). A workflow already running on the VM is not killed - it finishes on its own; the job just stops waiting. Idempotent for already-cancelled runs. | | list_job_executions | List a job's executions (paginated summaries, newest first). Filter by status (queued/running/succeeded/partial/failed/cancelled) and/or trigger (test = suite runs; api,mcp,cron = live traffic). Use to find a prior run to seed a range run from, a running execution to stop, or the latest failure to inspect. | | get_job_execution | Fetch one past execution's full trace: status, input, output, ctx, per-step results. | | inspect_job_execution | Deep-drill an execution end to end: job → steps → (workflow steps) the underlying workflow execution's internal flow-runs, with RPA failure analysis on failures. | | teach_job | Teach a job by example: an input + a natural-language prompt (+ optional expect output or refusal, and artifacts like Loom links or SOP text). Upserts an idempotent judge-graded test case, folds it into the job's active build run, and, when a draft definition exists, runs the draft now and returns its output + judge verdict. | | publish_job | Promote a job's draft definition to published: snapshots a route version, copies draft to published, stamps publishedAt. Live traffic serves the new definition immediately. Run run_tests with variant: "draft" first. | | get_build_status | Get a job's build runs (the teach loop's cycles): status queued/running/green/failed/needs_input, folded-in test cases, builder summary, open questions. Pass buildId for one run; omit to list recent runs. | | answer_build_question | Answer a needs_input question on a build run (credentials choice, ambiguity, 2FA policy). When no open questions remain the build re-queues automatically. | | cancel_build | Stop a queued/running autonomous build run. The build flips to failed with a "stopped by user" summary; the job's draft definition is left as-is. Use it to take the loop over manually. | | update_build_run | Builder-facing: update a build run's lifecycle (running when you start, green/failed with a summary when done, needs_input with questions when blocked). | | add_test_case | Attach a test case to a job: named input + assertions (the green-gate). Assertions are expr (sandbox boolean) or judge (an LLM grades the execution against a natural-language intent). | | update_test_case | Update an existing test case: tighten assertions as behavior firms up, or set enabled: false to disable a case without deleting its history. | | run_tests | Run a job's test suite (or a subset), poll to completion, return the report (green, totals, per-case). variant: "draft" runs against the draft definition. | | get_test_report | Fetch a test run report by id (totals + per-case results, each linking to its job execution). | | list_workspace_api_keys | List a workspace's API keys (id, apiKey, name) - to find a key for the two tools below. | | set_middleware_api_key | Set a router's workspaceApiKey after the fact, then re-read to confirm it stuck. |

The build loop - test-case-first, macroscope → microscope

You work backwards from the job's test cases. The job's test suite is the macro green-gate; individual workflows are the micro RPA underneath. This mirrors the platform's Jobs UI (Overview = macroscope, Build = microscope). The full playbook ships as the job-build-loop skill - load it with get_skill("job-build-loop").

1. GREEN-GATE FIRST - teach_job (input + intent) or add_test_case (input + assertions).
                      A job with no test cases has no definition of correct. Cases start RED.
2. BUILD THE DRAFT  - register_job / update_job variant=draft. Job steps call PUBLISHED
                      Minicor workflows (by workflowId) or run code blocks.
3. RUN THE GATE     - run_tests variant=draft. Green -> publish_job. Red -> step 4.
4. LOCATE (macro)   - resolve_job_state tells you where you are and what to do next;
                      get_test_report + inspect_job_execution drill a failing case down to
                      the failing job step and its workflow's internal flow-runs.
5. FIX AT THE RIGHT LEVEL:
   5a. Job-level    - update_job variant=draft, then replay JUST the failing slice:
                      run_job variant=draft fromStepId=<failing step>
                      seedExecutionId=<failed execution>  (seeds ctx so mid-graph starts
                      resolve earlier steps' values).
   5b. Workflow-level (microscope) - the failing step's workflowId -> dev_mode_load,
                      fix/run the draft's flow steps (dev_mode_run needs vmId),
                      dev_mode_publish - jobs execute PUBLISHED workflows.
6. PUBLISH          - when run_tests variant=draft is green, publish_job promotes the draft;
                      runtime traffic at /m/:slug serves it immediately.

A job step supports saveAs, when (conditional skip), forEach (fan-out), onError (abort/skip/continue/{goto} - goto currently treated as abort), retry, and cache (a login/smart-launch gate). Use resource.lockKey to serialize execution per desktop/VM. To migrate an existing NestJS customer middleware onto this layer, use the nestjs-middleware-to-job prompt or skill.

Execution control - stop, ranges, and traffic lenses

  • Stopping: there is no pause/resume. stop_job_execution is a cooperative cancel: a queued run cancels immediately; a running one stops at the runner's next checkpoint (between steps, between forEach items, or while waiting on a workflow). A workflow already running on a VM is not killed - it finishes on its own; the job just stops waiting and starts no new steps.
  • Long or risky runs: run_job with waitForResult: false returns the jobExecutionId immediately - poll it with get_job_execution, stop it with stop_job_execution.
  • Step-range replays: run_job with fromStepId / toStepId runs only a slice of the step graph (both inclusive, by step id). For any mid-graph start, pass seedExecutionId - it hydrates ctx from that prior execution so steps you aren't re-running still have their ctx.* values. The job's output block only runs when the range covers the last step.
  • Finding runs: list_job_executions returns paginated summaries with status and trigger filters - trigger: "test" isolates suite runs, trigger: "api,mcp,cron" isolates live traffic (the same split as the platform's Development/Production lenses).
  • Autonomous builds: watch with get_build_status, unblock with answer_build_question, take over with cancel_build. Don't edit the draft while a build is running - coordinate or cancel first.

Teach-by-example: draft vs published

Every job has two definition variants:

  • draft: the teach/build loop's working copy. Iterate here freely; live traffic never sees it.
  • published: what runtime traffic at /m/:slug/:path serves. publish_job promotes draft to published (snapshots a route version, stamps publishedAt).

update_job, run_job, and run_tests all take variant: "draft" | "published" (default published). The teach flow, from the agent's perspective:

1. ACCRUE CASES: teach_job upserts judge-graded test cases from examples
                 (input + prompt + optional expected output / refusal + artifacts).
                 When a draft exists, it also runs the draft immediately and
                 returns the output + judge verdict.
2. BUILD DRAFT:  update_job variant=draft to iterate on the step graph.
3. VERIFY:       run_tests variant=draft until green: true.
4. SHIP:         publish_job promotes draft to published; live traffic serves it.

Build runs track each teach cycle: get_build_status shows the run's status (queued/running/green/failed/needs_input), folded-in cases, and open questions. Answer blockers with answer_build_question (the build re-queues when no questions remain). A builder agent working the loop reports its own progress with update_build_run.

ctx / job-shape primer

The definition you pass to register_job (see register_job's definition param for the full schema):

{
  region: "us" | "ca",                       // region awareness - also auto-detected from workspace
  resource?: { configStoreId?, lockKey? },    // configStoreId = which VM/desktop; lockKey serializes runs
  inputSchema:  JSONSchema,
  outputSchema: JSONSchema,
  steps: [ { id, name, kind, saveAs?, when?, forEach?, onError?, retry?, cache?,
             // kind:"workflow" → workflowId + input (object with {{ctx.x}} OR a (ctx)=>({...}) code block)
             // kind:"code"     → code: "(ctx) => ..."
           } ],
  output?: "(ctx) => response",               // builds the job's response from the final ctx
}

ctx is the data through-line between steps - each step's saveAs key is what the next step reads:

  • ctx starts as { input: <the job input> }.
  • Each step's result is stored at ctx.<saveAs> (when saveAs is set), so later steps / when / forEach / output can read it.
  • Inside a forEach step, the current item is ctx.item (results are collected into an array under saveAs).
  • The top-level output block (ctx) => ... builds the job's response from the accumulated ctx.

Assertions (add_test_case) are either expr (TS booleans over { input, output, ctx, steps }, e.g. output.status === "COMPLETED") or judge (an LLM grades the execution against a natural-language intent; expected refusals pass). The full model + runner semantics live in the middleware-service repo's README.md ("## Jobs") and middlewares/JOBS-DESIGN.md.

Region & API key

Jobs are region-aware (us / ca) - pass region or let it be auto-detected from the workspace. Running a job requires the router's workspaceApiKey to be set so a job's workflow steps can call the Laminar API: it's populated by register_middleware's autoConfigure (default), or set later with set_middleware_api_key (find a key via list_workspace_api_keys). register_middleware / set_middleware_api_key report workspaceApiKeyConfigured so you can confirm it stuck.

Skills System

Skills are reusable RPA patterns that accumulate as you build automations. The MCP ships with bundled general skills, including:

| Skill | Purpose | | ---------------------------- | --------------------------------------------------------------------------------- | | job-build-loop | Mandatory for job work. The test-case-first build/debug loop: green-gate first, macroscope (job) → microscope (workflow steps), seeded range replays, stop semantics, publish gates | | rpa-testing-workflow | Mandatory. Exact tool call sequences for testing through the Minicor executor | | cdp-browser-automation | CDP starter template, React-safe setters, parallel execution | | desktop-uiautomation | Framework selection, element selectors, wait/retry patterns | | data-extraction-strategies | Priority-ordered methods for reading data from screen | | data-passing-between-steps | JS-layer interpolation, config variables, step outputs | | state-verification | LLM-based UI verification for production workflows | | nestjs-middleware-to-job | Map a NestJS middleware controller onto the Jobs layer (step graph + test cases) |

Using Skills

list_skills()                         → see all available skills
get_skill("cdp-browser-automation")   → load full patterns + code templates
save_skill(...)                       → persist a new skill from a successful build
generate_skill(workflowId)            → extract patterns from an existing workflow

Skills Service

Skills are automatically persisted through the Minicor platform API. When authenticated, save_skill and generate_skill store skills server-side so they persist across sessions and are available to other agents in the same workspace.

Skill tiers:

  • Global - general RPA knowledge (read-only, bundled with the MCP)
  • Per-workspace - learned from agent sessions, persisted across runs
  • Customer-specific - app quirks, environment patterns

Without authentication, skills fall back to the bundled .md files in the package.

What You Can Automate

  • Web portals - Chrome via CDP. React/Angular SPAs, anti-bot sites, payor portals, EHR web apps.
  • Desktop applications - Windows apps via uiautomation, pywinauto, pyautogui. EMR clients, billing software, legacy systems.
  • APIs - Direct HTTP when the agent discovers usable endpoints behind a portal.
  • Hybrid workflows - Mix browser, desktop, and API steps in one workflow.

VM Setup

The easiest path is to let the agent handle everything:

"Deploy a VM and set it up for automation"

The agent runs: deploy_vminstall_mds_on_vmstart_mds_on_vmvm_connect

Once the VM is provisioned, a secure tunnel is automatically created. The agent connects via the tunnel URL and is ready to build automations. Chrome instances for browser automation are managed automatically by the MDS - no manual setup needed.

For manual setup, use get_lds_setup_guide for step-by-step instructions.

Tools

VM Tools

| Tool | What it does | | ---------------------- | ------------------------------------------------------------------------------------------ | | vm_list | Discover available VMs (returns ID, name, status, tunnel URL) | | vm_connect | Connect to VM via LDS Cloudflare tunnel URL or VM ID | | vm_disconnect | Disconnect from VM | | vm_status | Health check for the connected VM | | vm_screenshot | Full-screen capture of the VM desktop | | vm_screenshot_region | Zoom into a specific screen area | | vm_execute_script | Run a Python script on the VM | | vm_execution_status | Check status of a running script | | vm_execution_control | Pause, resume, stop, or skip a running script | | vm_inspect_ui | Inspect Windows UI elements (window list, element tree, element at point, focused element) | | vm_read_clipboard | Read VM clipboard contents |

Automation Building

| Tool | What it does | | ----------------------- | --------------------------------------------------------- | | create_rpa_flow | Save a validated Python script as a Minicor workflow step | | debug_rpa_step | Test a script with before/after screenshots | | vm_reset_state | Manage windows: focus app, minimize all, close dialogs | | batch_test_rpa | Run a workflow with multiple test inputs | | replay_execution_step | Re-run a step from a failed execution on the VM | | get_lds_setup_guide | LDS installation walkthrough |

Workflows and Executions

| Tool | What it does | | ---------------------------------------------------------- | --------------------------------------------------- | | create_workflow / update_workflow / delete_workflow | Workflow CRUD | | create_flow / update_flow / delete_flow | Step CRUD | | execute_workflow / execute_workflow_async | Run workflows synchronously or async | | list_executions / get_execution / get_full_execution | View execution history and details | | diagnose_execution | Analyze failures with RPA-specific pattern matching | | get_workflow_overview | Full snapshot: steps, code, recent executions | | test_workflow_step | Run a single step in isolation | | preview_flow_changes / compare_flow_versions | Diff code before deploying |

Jobs & Test Cases

| Tool | What it does | | --------------------- | -------------------------------------------------------------------------------------------- | | resolve_job_state | "Where am I in the build loop?" - job state + nextActions (the concrete next tool calls) | | list_middlewares | List the routers (middlewares) in a workspace - jobs attach to one of these | | register_middleware | Create a router (middleware) jobs attach to; autoConfigure populates its workspace API key | | register_job | Create a job - a middleware route backed by a structured definition (step graph) | | update_job | Update a job's definition, path, method, or description; variant: "draft" writes the draft | | get_job | Get a job (route) incl. its definition; omit routeId to list all routes on the router | | run_job | Run a job once, poll to completion; variant: "draft" runs the draft. Step-range replays via fromStepId/toStepId + seedExecutionId; waitForResult: false returns the execution id immediately | | stop_job_execution | Cooperative cancel of a queued/running execution (no pause; VM workflows finish on their own) | | list_job_executions | Paginated execution summaries with status/trigger filters (test vs live traffic) | | get_job_execution | Fetch one execution's full trace (status, input, output, ctx, per-step results) | | inspect_job_execution | Deep-drill: job → steps → workflow execution's internal flow-runs, with RPA failure analysis | | teach_job | Teach by example: upsert a judge-graded test case from input + prompt; runs the draft if one exists | | publish_job | Promote a job's draft definition to published (snapshots a version); live traffic serves it | | get_build_status | Get a job's build runs: status, folded-in test cases, builder summary, open questions | | answer_build_question | Answer a needs_input question on a build run; the build re-queues when none remain | | cancel_build | Stop a queued/running autonomous build run (flips to failed; the draft is left as-is) | | update_build_run | Builder-facing: set a build run's status (running/green/failed/needs_input) + summary | | add_test_case | Attach a test case to a job: named input + expr or judge assertions (the green-gate) | | update_test_case | Update a test case (tighten assertions, or enabled: false to disable without deleting) | | run_tests | Run a job's test suite, poll to completion, return the report; variant: "draft" tests the draft | | get_test_report | Fetch a test run report by id (totals + per-case results, each linking to its job execution) | | list_workspace_api_keys | List a workspace's API keys (id, apiKey, name) - find one for the two tools below | | set_middleware_api_key | Set a router's workspaceApiKey (then re-reads to confirm it stuck) |

See the Jobs (RPA orchestration) section above for the build loop and job/ctx shape. batch_test_rpa can also persist each passing input as a real job test case - set persistAsTestCases with routeId + middlewareId + workspaceId.

2FA / OTP

| Tool | What it does | | ----------------------- | ------------------------------------------------------------------------- | | tfa_provision_phone | Buy a Twilio phone number for the workspace (SMS webhook auto-configured) | | tfa_provision_email | Generate a Mailgun email address for OTP capture | | tfa_list_channels | List all provisioned phone numbers and email addresses | | tfa_delete_channel | Remove a channel (releases Twilio number if phone) | | tfa_register_secret | Store a TOTP secret (base32 or otpauth:// URI), encrypted at rest | | tfa_list_secrets | List stored TOTP secrets for the workspace | | tfa_delete_secret | Remove a stored TOTP secret | | tfa_generate_totp | Get the current 6-digit TOTP code + seconds until expiry | | tfa_verify_totp | Verify a TOTP code against a stored secret | | tfa_parse_qr | Parse a QR code image to extract TOTP parameters | | tfa_request_sms_otp | Wait for an SMS OTP (blocks until SMS arrives or timeout) | | tfa_request_email_otp | Wait for an email OTP (blocks until email arrives or timeout) | | tfa_get_challenge | Check the status of a pending challenge | | tfa_resolve_challenge | Manually resolve a challenge (for captchas or Slack-provided codes) | | tfa_cancel_challenge | Cancel a pending challenge |

Workflows that encounter 2FA prompts use these tools to auto-resolve OTP challenges. Provision channels once per workspace, store the IDs in config stores, and reference them with {{config.sms_channel_id}} or {{config.totp_secret_id}} at runtime.

Config Stores

| Tool | What it does | | --------------------------------------------------- | --------------------------------------------------- | | create_config_store | Create a credential store with key-value properties | | list_config_stores / get_config_store | Browse stores | | update_config_property / remove_config_property | Manage individual properties |

Scripts reference credentials as {{config.propertyKey}} - resolved at runtime by the workflow engine.

Issues

| Tool | What it does | | -------------- | ---------------------------------------------- | | list_issues | List all issues in a workspace | | get_issue | Get a specific issue with full description | | create_issue | Create an issue (supports Markdown) | | update_issue | Update title, description, status, or assignee | | delete_issue | Delete an issue |

Agents use Issues to persist context across runs with the [Agent:<name>] title convention:

  • [Agent:my-bot] Rules - learned behaviors (e.g., "login page takes 15s to load")
  • [Agent:my-bot] Context - persistent state (URLs, credential rotation dates)
  • [Agent:my-bot] Session 2026-04-09 - run summaries

Agents

| Tool | What it does | | -------------- | ---------------------------------------------------------------- | | list_agents | List agents in a workspace | | get_agent | Get agent details (task, mode, VM, run stats) | | create_agent | Create an agent (on-demand, scheduled, or workflow monitor mode) |

Agents are autonomous runners that execute tasks on VMs using MCP tools. After building a workflow, the build-rpa-workflow prompt offers to create a monitoring agent that watches for failures and auto-recovers.

Skills

| Tool | What it does | | ---------------- | --------------------------------------------------------------------- | | list_skills | List available skills (filterable by category, tags, workspace) | | get_skill | Load full skill content by name | | save_skill | Save a skill to the skills service and/or local workspace clone | | generate_skill | Gather workflow context for skill extraction (agent writes the skill) |

Workspace Sync

| Tool | What it does | | --------------------------------- | ------------------------------------------------------------------------------ | | clone_workspace | Full workspace clone: workflows + skills + issues + metadata. Defaults to configured workspaces root if outputDir omitted. | | init_project | Scaffold a git-ready project from a workspace (workflows only) | | pull_workflow / push_workflow | Sync individual workflows | | pull_all / push_changed | Bulk sync | | sync_status | Diff local vs deployed | | set_workspaces_root | Set default root directory for cloning workspaces (~/.minicor/config.json) |

Session Lifecycle

| Tool | What it does | | --------------------- | --------------------------------------------------------------------------------------------- | | session_start | Load full workspace context + begin session tracking. Call FIRST in a workspace clone. | | session_checkpoint | Save progress: writes .minicor/session.json + syncs [Workspace:Session] issue. | | session_end | End session: persist final state, sync to platform, optionally update context.md. |

Prompts

| Prompt | What it does | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | build-rpa-workflow | Guided automation building with POC/production mode. Loads skills, iterative build loop, per-step Minicor testing, optional hardening. | | debug-workflow-execution | Analyze a failed execution with VM-aware debugging and replay | | minicor-workflow-guide | Full workflow specification: step types, data access, keywords, libraries | | 2fa-workflow-guide | Handling 2FA in workflows: provisioning channels, TOTP secrets, auto-resolving OTP codes | | workspace-session-guide | Returns AGENTS.md rules and session state for any workspace clone | | nestjs-middleware-to-job | Convert an existing NestJS customer middleware endpoint into a Job (structured step graph) with test cases as the green-gate |

The build-rpa-workflow prompt accepts a mode parameter:

  • **poc** - Quick prototype. Streamlined testing, no state verification or monitoring.
  • **production** - Full hardening. State verification, idempotency testing, monitoring agent, context persistence.
  • Omitted - The agent asks the user which mode to use.

Environment Variables

Jobs/middleware base resolution (precedence: proxy > direct > default):

| Variable | Purpose | Default | | --------------------------------- | ------------------------------------------------------------------- | ---------------------- | | VM_MANAGER_API_URL | VM Manager service URL | Cloud Run instance | | MIDDLEWARE_SERVICE_PROXY_BASE | Frontend origin fronting the middleware proxy, all regions | unset | | MIDDLEWARE_SERVICE_PROXY_BASE_US| Frontend proxy origin for US (overrides the generic one) | unset | | MIDDLEWARE_SERVICE_PROXY_BASE_CA| Frontend proxy origin for CA (overrides the generic one) | unset | | MIDDLEWARE_SERVICE_PROXY_PREFIX | Proxy path prefix | /api/middleware | | MIDDLEWARE_SERVICE_URL | Direct middleware-service base, all regions (dev/local) | unset | | MIDDLEWARE_SERVICE_URL_US | Direct middleware-service base for US (overrides the generic one) | unset | | MIDDLEWARE_SERVICE_URL_CA | Direct middleware-service base for CA (overrides the generic one) | unset | | EXPERIMENTAL_USE_CODE_MODE | Expose the experimental single codemode tool surface | unset (standard tools) |

When none are set, Jobs calls the region's public middleware-service Cloud Run directly. To route through the frontend (once it deploys an /api/middleware/[...path] proxy), set MIDDLEWARE_SERVICE_PROXY_BASE (or the per-region variants).

Auth

  • Sign in: npx -y -p @minicor/mcp-server minicor-mcp-setup (browser) or append --cli for headless
  • Token storage: ~/.minicor/tokens.json
  • Auto-refresh: tokens refresh before expiry
  • Regions: US (default) or Canada

Development

npm install
npm run build
npm test

Project Structure

src/
  index.ts              - CLI MCP entry (stdio transport, token management, disconnect hooks)
  lib.ts                - Embeddable server factory (in-process, no side effects)
  bootstrap.ts          - CLI to generate harness configs (CLAUDE.md, .cursor/rules, etc.)
  config.ts             - User config (~/.minicor/config.json) - workspacesRoot, etc.
  state.ts              - Shared mutable state (VM connections, active session tracking)
  skills.ts             - Skill loader, parser, index builder
  tools/
    session.ts          - session_start, session_checkpoint, session_end, auto-checkpoint
    skills.ts           - list_skills, get_skill, save_skill, generate_skill
    sync-tools.ts       - clone_workspace, init_project, pull/push, set_workspaces_root
    vm.ts, vm-rpa.ts    - VM and RPA tools
    core.ts             - Workflows, flows, executions
    ...
  prompts/
    workspace-session.ts - Workspace session guide prompt
    build-rpa.ts        - Guided RPA building (POC/production modes)
    ...
skills/
  general/              - Bundled skill files (shipped with npm package)