Skip to main content
Glama
taitson

flexlm-mcp

by taitson

flexlm-mcp

An MCP server that lets an AI agent read a FlexLM / FlexNet license server and tell you where you are wasting seats.

It wraps lmutil lmstat, parses the 1990s-style text into structured data, and runs a handful of opinionated checks: features that are saturated, linger measured in days (which quietly turns a floating pool into named licenses), the same user holding duplicate seats, and idle bundles sitting next to saturated ones. Every finding says what is happening, why it costs money, and what to do next.

Read-only. It never runs lmremove, lmreread or lmdown.

Built against Siemens (ugslmd) output; the grammar is FlexNet's, so Autodesk, Ansys, PTC, MathWorks and other FlexLM-licensed vendors parse the same way. Where a vendor prints something unusual, the line is returned in unparsed_lines instead of being guessed at.

Why

A 13-seat bundle of engineering CAD licenses was permanently at 13/13. Engineers waited every morning. The obvious answer was "buy more seats."

One lmstat -a said otherwise:

alice WS-0101 ... start Wed 8/5 15:52  (linger: 7727858 / 8751540)

The two linger numbers are remaining / total, in seconds. 8751540 s is 101 days. Anyone who opened the application once kept a seat for three months, application closed or not. The pool was not full — it was frozen. Another seat was held twice by one person because their laptop appeared under two hostname spellings (WS-0106 and WS-106). A sibling 20-seat bundle was 75% idle.

None of that shows on a utilization dashboard. It shows in the checkout lines, and nobody reads checkout lines — so this tool does.

Related MCP server: mcp-redfish

Tools

Tool

What it answers

flexlm_status

Is the server up? Daemons, seats issued vs in use, saturated features, bundle occupancy.

flexlm_list_features

Features with issued / in use / free / utilization. Filter by substring (e.g. a bundle code).

flexlm_feature_checkouts

Who holds one feature, since when, linger total and remaining, days held.

flexlm_user_sessions

Everything one user holds across the server.

flexlm_find_waste

Saturation, long linger, duplicate seats, idle bundles — with severity and next action.

flexlm_parse_lmstat

Same analysis on pasted lmstat -a text. No server access needed.

Install

pip install flexlm-mcp        # or: pip install git+https://github.com/taitson/flexlm-mcp

You need lmutil (ships with every vendor's license server tools; for Siemens it is under <NX install>\UGFLEXLM\lmutil.exe).

Environment:

Variable

Meaning

LMUTIL_PATH

Full path to lmutil. If unset, lmutil on PATH, then the usual Siemens folder.

FLEXLM_DEFAULT_SERVER

Default port@host when a tool call does not pass one.

FLEXLM_TIMEOUT_S

Seconds to wait for lmstat (default 60).

Claude Desktop

{
  "mcpServers": {
    "flexlm": {
      "command": "flexlm-mcp",
      "env": {
        "LMUTIL_PATH": "C:\\Siemens\\NX2306\\UGFLEXLM\\lmutil.exe",
        "FLEXLM_DEFAULT_SERVER": "28000@licsrv01"
      }
    }
  }
}

Claude Code

claude mcp add flexlm -e LMUTIL_PATH="C:\Siemens\NX2306\UGFLEXLM\lmutil.exe" -e FLEXLM_DEFAULT_SERVER=28000@licsrv01 -- flexlm-mcp

Then ask: "Where are we wasting license capacity?" or "Who is holding NX93100 and for how long?"

Without an agent

The same analysis from the command line:

python -m flexlm_mcp waste 28000@licsrv01
python -m flexlm_mcp features 28000@licsrv01 --filter NX93100
python -m flexlm_mcp parse saved_lmstat.txt

Example output:

[HIGH  ] long_linger  CAD5000
         CAD5000: 10 of 10 seats have linger of up to 101 days
         Linger keeps a seat reserved after the application exits. At 101 days, anyone who opened
         the application once holds a seat for months whether they use it or not — the floating pool
         behaves like named licenses. With the feature saturated, this is capacity you already paid
         for and cannot use.
         → Ask the license administrator to set LINGER for this feature to minutes (e.g. LINGER
           <feature> 900 in the options file) or the vendor default, then restart the vendor daemon.

[HIGH  ] duplicate_seat  CAD5000
         CAD5000: frank holds 2 seats (WS-0106, WS-106)
         Same machine under two hostname spellings (leading zero, case or domain suffix). FlexLM
         counts them as two users.
         → Normalize the hostname on the machine and let the stale seat linger out, or have the
           administrator run lmremove for the stale handle.

[MEDIUM] idle_bundle  CAD3000
         CAD3000: 16/20 seats free while CAD5000 is saturated

What the checks mean

Saturated — ≥ 90% of issued seats in use. Not a finding by itself; it is the reason to look at the next three.

Long lingerLINGER is a FlexLM option that keeps a seat reserved after the application exits, so a user can reconnect without losing it. Minutes are sensible. Days mean the seat count in lmstat has nothing to do with how many people are working. The fix is configuration, not purchase: LINGER <feature> <seconds> in the vendor options file, then lmreread.

Duplicate seat — one login holding two seats of one feature. Usually one machine under two hostname spellings (WS-0106 vs WS-106, case, a domain suffix). The tool normalizes hostnames to spot it.

Idle bundle — vendors sell capability bundles (NX93100, NX91110…) and lmstat names features BUNDLE_feature. When one bundle is saturated and a sibling is mostly free, the answer may be moving users or re-allocating seats, not buying.

Server down — includes the classic VPN trap: lmgrd answers with its hostname, not its IP. A machine without corporate DNS connects to the port and then fails with HOST_NOT_FOUND. The finding says to check DNS first.

Privacy

lmstat output contains user names and hostnames. The tool returns them to your agent because that is what "who is holding this seat" means; it stores nothing. Do not commit real captures to a repository — the test fixture here is synthetic.

Development

pip install -e .
python -m unittest discover -s tests -v

The parser is pure functions over text (flexlm_mcp/parser.py); the checks are arithmetic over the parsed report (flexlm_mcp/analysis.py); running lmutil is isolated in runner.py. Add a vendor quirk by extending the fixture and the parser together.

License

MIT.

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to monitor and control server hardware (power, thermal, storage, firmware, event logs) via Redfish BMC API on Dell iDRAC, HPE iLO, Lenovo XCC, Supermicro BMC, and others.
    17
    3
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables LLMs to monitor server health through natural language, including HTTP endpoint checks, disk/memory/CPU usage, port status, and process listings.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to read Microsoft 365 tenant data, such as users, license usage, and stale accounts, while enforcing least-privilege by refusing to run with excessive Azure permissions.
    4
    MIT