Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者による説明(英語の原文)
Extract durations, sizes, percentages and frequencies in one base unit, refusing ambiguous ones.
この3つを1つのスコアにまとめることはしません。意見、測定、人気はそれぞれ別のものだからです。
このサーバーのやさしい解説はまだ書いていません。以下はレジストリから読み取った事実です。
使っているAIアプリを選んで、設定をコピーしてください。
必要なもの
どのアプリを使っていますか?
上でアプリを選んでください。選んだアプリを覚えておくので、次からはボタンに「…にインストール」と表示されます。
Claude Desktop → Settings → Developer → Edit Config を開き、claude_desktop_config.json にこれを貼り付けます
{
"mcpServers": {
"units-le": {
"command": "npx",
"args": [
"-y",
"units-le-mcp"
]
}
}
}ターミナルでこれを実行します
claude mcp add units-le -- npx -y units-le-mcpプロジェクトの .cursor/mcp.json、または ~/.cursor/mcp.json に貼り付けます
{
"mcpServers": {
"units-le": {
"command": "npx",
"args": [
"-y",
"units-le-mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
プロジェクトの .vscode/mcp.json に貼り付けます
{
"servers": {
"units-le": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"units-le-mcp"
]
}
}
}ブラウザがアプリを開いてよいか確認し、そのあとアプリが設定を表示して確認を求めます。キーの値は空欄のままなので、自分で入力してください。
これはパソコンで動くサーバーですが、ChatGPTがつなげるのはインターネット上のサーバーだけです。ほかのアプリを選んでください。
選んだアプリは、この端末のCookieに保存されます。アカウントは不要です。
この設定は、作者のレジストリ登録情報から作成しています。READMEと違う場合は、READMEに従ってください。
パソコンで動くサーバーです。インストールすると、ツール一覧がAIアプリに表示されます。
誰でも見られる情報をチェックしており、コードは読んでいません。当てはまらない項目は数に入れていません。 · 2026年11月7日にチェック
レジストリ名は、リポジトリを所有するGitHubアカウント nolindnaidoo で確認済みです
このリポジトリはまだGitHubから読み取っていません
このリポジトリはまだGitHubから読み取っていません
これはパソコンで動くため、インターネット上のエンドポイントはありません
パソコンで動き、代わりにローカルの設定を使います
パソコンで動くサーバーです。ツール一覧を読み取れるのは、インターネット上のエンドポイントがある場合だけです
レジストリでこのカテゴリにある有効なすべてのサーバーと比較しています。スターは、公開者がリポジトリの所有者である場合だけ数えます。
当てはまる基本チェック1項目のうち1項目に合格しました。コードは読んでいません。キーやトークンを追加する前に、サーバーがどんなアクセスを求めているかを確認し、必要な権限だけを持つキーを使ってください。
レジストリには必須のキーは載っていません。ただし、最初に使うときにサインインを求めるサーバーもあります。
あなたのパソコンで動きます。必要なときにAIアプリが起動し、データは作者のサーバーを通りません(サーバー自体がオンラインサービスを呼び出す場合を除きます)。
GitHubリポジトリの最終更新は–、最新バージョン(1.1.0)がレジストリに届いたのは31 日前です。
Claude Desktop、Claude Code、Cursor、VS CodeなどのMCP対応アプリで使えます。パソコンにNode.jsも必要です。
同じカテゴリには:Spec Driven Development, Remote Desktop Commander, Excaliself
同じカテゴリで、ほかの作者が作ったサーバー。スターの多い順。
カードの見方:★ GitHubスターi3つの柱:レビュー · チェック · 利用状況i更新=最新バージョンをレジストリに公開した日i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Find, read, create, edit, and organize Excalidraw drawings in your self-hosted Excaliself instance.
作者のリポジトリから書かれたとおりにコピーしたものです。PopNx MCPは内容を確認・推奨していません。HTML、画像、スクリプトは取り除いています。リンクはこのサイトの外へ移動します。
Units-LE: One Quantity, One Unit
Find every quantity in a document — durations, sizes, percentages, frequencies — with its value in one base unit, and refuse the ambiguous ones by name
YAML · TOML · JSON · INI · dotenv · CSV · and anything else, scanned as text
Useful? A star or rating is how other developers find it —
★ GitHub ·
timeout: 30s in one service and timeout: 30000 in another are the same number of milliseconds, and nothing about the text says so. memory: 1GB and memory: 1GiB differ by 7% and look identical at a glance.
Run Units-LE: Extract Quantities and every quantity in the active document — a number welded to a unit — opens in a report beside the editor: as the document wrote it, in one base unit so two of them can be compared, with its line, column and key path. A quantity it cannot read unambiguously keeps its row and gets a reason instead of a guess. Works in VS Code and in VS Code–based editors like Cursor and VSCodium (installable from Open VSX).
500m that means minutes to one reader and millicores to anotherIt never rewrites a document, and never guesses.
| Where | What you get | Install |
|---|---|---|
| VS Code | The report, in your editor, on a keystroke | Marketplace |
| Cursor, VSCodium, Windsurf | The same extension | Open VSX |
| A terminal or a CI step | A whole tree, with exit codes | cargo install units-le · crates.io |
| A terminal, via Node | The same command line, held to the Rust one byte for byte | npx units-le · npm |
| Any MCP agent, via Node | extract_units over stdio | npx units-le-mcp · npm |
This is the whole product. Any tool can multiply 30s by a thousand; what makes this one usable in a review is that it will not pretend.
| It sees | Reason | What comes back |
|---|---|---|
500m, 10M, 5k, 1y, 100Mb | ambiguous_unit | no base value — m is minutes, milliseconds or Kubernetes millicores; M is mega- or minutes; k/K/G/T/P are prefixes with no unit after them; a calendar year has no fixed length; a lowercase b is bits by the standard and bytes in most software that writes it |
1.5KB, 1.5KiB | fractional_bytes | no base value — a byte count has no fractional part. 1.5KiB is exactly 1536 bytes and is still refused: the refusal is about the category, not the arithmetic |
1,5s, 1.000s, 1.2.3s | locale_separator | no base value — one and a half, or fifteen hundred? This tool does not infer a locale. Narrowed so 0.825s and 2.5s read normally |
1h + 30m, 30s*2 | compound_arithmetic | no base value — an expression, not a quantity, reported as one finding rather than two |
1MB, 256KB | si_iec_hazard | the base value, plus the reason — see below |
99999…PiB | out_of_range | no base value — it does not fit in 128 bits, and is refused rather than wrapped |
Every one of them keeps its row, its source text, its position and a sentence a person can act on. A refusal is never a dropped row and never a guess.
si_iec_hazard annotates; it does not withholdIt is the one reason that still answers. MB is 10^6 by the standard, so 1MB comes back as 1000000 bytes *and* carries reason: "si_iec_hazard" — because a great deal of software writes MB and means 2^20. Reporting nothing would be less useful than reporting the standard answer with the flag attached, and picking 2^20 would be the guess this tool exists not to make.
So it is not counted as refused. A row with si_iec_hazard is the only row that carries both a base and a reason; every other reason means the base is null.
A bare number with no unit is not a finding at all. timeout: 30 yields nothing here — that is numbers-le's question, and the boundary is what keeps the two tools distinct.
| Dimension | Base unit | Units read |
|---|---|---|
duration | milliseconds | ns us µs μs ms s sec secs min mins h hr hrs d day days w · compounds 1h30m · ISO-8601 PT1H30M P1DT2H P2W PT0.5S |
bytes | bytes | B · SI kB KB MB GB TB PB · IEC KiB MiB GiB TiB PiB · Kubernetes Ki Mi Gi Ti Pi |
percent | ratio | % — 15% is 0.15 |
frequency | hertz | Hz kHz KHz MHz GHz THz |
Case is part of the symbol. MB is a megabyte and Mb is a megabit; folding them would silently multiply by eight, so Mb is refused rather than treated as a synonym.
`1h30m` is a grammar and `1h + 30m` is arithmetic. The first is one quantity written in two parts. Inside a compound the parts disambiguate each other — m alone is refused, and m between h and s can only be minutes, because a compound is written largest-first. That ordering is required rather than assumed, so 30s1h is not a quantity at all.
Physical units are a non-goal, not a gap. Length, mass, temperature belong to a different question, and reading them would mean unit algebra (m/s²), which is what uom is for. See crate/SPEC.md.
JSON, YAML, CSV, TOML, INI and dotenv are parsed. Everything else is scanned as text — a Kubernetes manifest, a Terraform file, a Markdown table of limits, a log — so the files where quantities actually live yield them rather than nothing.
Unlike numbers-le's text scan, this one has a shape to look for, so v1.2.3 yields nothing rather than two numbers. Every format with a shape carries a key path — cache.ttl, limits[0], server.timeout, TIMEOUT — and every finding carries a 1-based line and column, the column in UTF-16 units, which is the number your editor shows.
Its false-positive class is measured rather than imagined. A run inside an opaque blob still reads as a quantity: 001d in a UUID is one day, and a base64 hash ending /2w== is two weeks. The boundary characters that let those through are the same ones that let -30s and ttl=30s through. Over crate/fixtures/documents/opaque.txt — 280 lines of lockfile hashes, container digests, git object names, UUIDs and signing material, none of which is a quantity — the scan reports 5 false findings, 1.8%, and a test prints that number on every run. Each one carries its line and column, which is what makes it a row you discard rather than a number you trust.
No "this timeout is too low". No defaults database. No conversion flag, no rewriting, no arithmetic. It reports what a document says and what that means in one base unit; which limits are right is the reviewer's call.
Extract reads the document you have open. A scan reads many files from disk and gives one report.
Units-LE: Scan Workspace for Quantities from the command palette.Scan Folder for Quantities, or run Units-LE: Scan Folder for Quantities and pick one.The report opens with a table of every file that holds something, then has a section per file:
# Units-LE workspace report
my-project · 113 file(s) read · 3 quantit(ies), 1 could not be resolved
| File | Quantities | Could not be resolved |
|---|---|---|
deploy/values.yaml | 3 | 1 |
deploy/values.yaml · yaml (3)1h30m · duration · → 5400000 milliseconds · key cache.ttl512MiB · bytes · → 536870912 bytes · key memory2GB · bytes · → 2000000000 bytes · key disk2 file(s) larger than the safety limit were not read.
What a scan reads. Files come from disk, so an unsaved edit is not seen. A file over the safety size, or one that is not UTF-8 text, is left unread. It stops at 5,000 files or 10,000 listed quantities. The report ends with a line for each thing it left out, so a short report is never mistaken for a clean project.
What it skips, and how to change that. Three switches are on by default, and each can be turned off on its own in Settings:
| Switch | Skips |
|---|---|
scanUseDefaultExcludes | Dependency folders, build output, tool caches and lockfiles. The full list is below |
scanRespectGitignore | Whatever the project's .gitignore files skip |
scanSkipBinaryFiles | Images, fonts, archives and other files that are not text |
Two lists adjust the result without turning a switch off. To skip more, add a pattern to scanExcludes. To read something a switch would skip, add it to scanAlwaysInclude:
{
// Also skip the test fixtures. "units-le.workspace.scanExcludes": ["/fixtures/"], // Read the vendored code, though the built-in list skips it. "units-le.workspace.scanAlwaysInclude": ["/vendor/"] }
Units-LE: Open Settings opens all of these in the Settings editor.
The built-in list
Folders, wherever they appear:
.git, .hg, .svn, node_modules, bower_components, jspm_packages, .pnpm-store, .yarn, vendor, site-packages, Pods, Carthage, dist, build, out, target, _build, _site, dist-newstyle, zig-out, storybook-static, cdk.out, DerivedData, CMakeFiles, .next, .nuxt, .output, .svelte-kit, .angular, .astro, .docusaurus, .vuepress, .expo, .turbo, .parcel-cache, .cache, .sass-cache, .jekyll-cache, .dart_tool, .pub-cache, .gradle, .kotlin, .cxx, .externalNativeBuild, captures, `ephemer
冒頭だけを表示しています。続きはリポジトリで読めます