workspace-status-mcp
Provides visibility into local Git repositories, reporting branch, uncommitted changes, unpushed commits, and commit drift between source and release repos.
Queries the latest GitHub Actions CI run status and conclusion for repositories, making it easy to spot failing or non-success CI runs.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@workspace-status-mcpSweep all repos in ~/Projects for git and CI status"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
workspace-status-mcp
An MCP server with four tools:
sweep_status— a one-call snapshot of every git repository under a given folder: branch, uncommitted changes, unpushed commits, and (optionally) the latest GitHub Actions CI conclusion. Replaces manually loopinggit status+gh run listover dozens of repos one at a time.check_docs— flags which repos'Architecture/<repo>.txtdoc is missing or stale. Doesn't write or regenerate anything itself (understanding a codebase well enough to document it is an LLM/human job, not a script's) — it just says where to look, so docs get updated deliberately instead of silently rotting.write_doc— writesArchitecture/<repo>.txtand stamps it with the repo's current commit hash, socheck_docscan later measure staleness precisely (commits since write) instead of guessing from file mtime.check_release_drift— for explicit (source repo, release repo) pairs, counts how many commits landed in the source since the release repo's last git tag, and how old the oldest one is. Cutting a release is usually a manual "whenever I remember" step (tag a version, push it, CI builds and publishes) — this answers "has anyone actually done that lately" without checking by hand.
Why
Working across ~50 repositories in the same workspace, "what actually needs
attention right now" was a real recurring question — checked by hand,
repo by repo, over and over in the same session. sweep_status answers it
in one call and, by default, only returns repos that actually need a look
(dirty working tree, unpushed commits, or a CI run that isn't a plain
success) — clean repos are silently skipped so the answer stays short.
check_docs exists for the same reason, one level up: a per-project
architecture doc is only useful if it's trusted, and it's only trusted if
someone actually checks it's current. Comparing "last commit" to "doc's
mtime" turns that from a thing you have to remember into a thing you can
just ask.
Related MCP server: github-ops-mcp
Claude Code hook: check-docs-reminder
The tools above only help if something actually calls them. hooks/check-docs-reminder.mjs
closes that gap: registered as a SessionStart + Stop hook in
~/.claude/settings.json, it runs checkDocs() itself against whatever
repo Claude's current working directory is under (walking up to the
nearest git root that's a direct child of the projects folder), and — only
when that repo's doc is missing or stale — injects a one-line reminder
into Claude's context via hookSpecificOutput.additionalContext. Silent
otherwise (clean repos, or a cwd outside the projects folder, produce no
output; likewise if the projects folder never had an Architecture/ folder
at all — someone who's never opted into this convention doesn't get nagged
about every repo being "missing"). SessionStart covers forgetting between
sessions; Stop (which fires each time Claude's turn ends) re-checks every
turn within the same session too, and self-quiets the moment write_doc
actually gets called. Deliberately non-blocking — a stale doc is worth a
nudge, not a halted turn.
Not hardcoded to any one person's folder layout, and works the same on
Windows as Linux/macOS. Register it with the args array ("exec form" —
spawned directly, no shell involved, so there's no bash-vs-PowerShell-vs-cmd
syntax difference to worry about):
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "node",
"args": ["/path/to/workspace-status-mcp/hooks/check-docs-reminder.mjs", "SessionStart"] }] }],
"Stop": [{ "hooks": [{ "type": "command", "command": "node",
"args": ["/path/to/workspace-status-mcp/hooks/check-docs-reminder.mjs", "Stop"] }] }]
}
}Watch points
Not every repo necessarily lives under one root — one might get moved out
of ~/Projects onto the Desktop, say, with its doc sitting right next to
it there instead of in the central Architecture/ folder. The hook
resolves "watch points" (projectsRoot + optional docsRoot pairs) in
this order, using the first point whose projectsRoot contains the repo
you're currently in:
CLI args (
args[2]/args[3]after the event name) — a one-off single-point override.The watch-points config file —
~/.claude/workspace-status-points.jsonby default (override the path withWATCH_POINTS_FILE). This is the normal way to manage this day to day:{ "points": [ { "projectsRoot": "/home/sviat/Projects" }, { "projectsRoot": "/home/sviat/Desktop", "docsRoot": "/home/sviat/Desktop" } ] }Add a point, remove one (or all of them), or redirect an existing one just by editing this file — no code change, no re-registering the hook. A missing file, or an empty/absent
pointsarray, falls through to the next source below.PROJECTS_ROOT/DOCS_ROOTenvironment variables — single-point fallback for anyone registering the hook through a shell command instead of theargsexec form.Default: a single point at
<home>/Projects.
check_docs/sweep_status accept the same idea directly as points/roots
arguments (see below) if you want to query multiple locations from a
conversation without touching the config file.
Install
npm installRequires the GitHub CLI (gh), authenticated, if you want CI status
(check_ci: true, the default). Without it CI results just come back as
null per repo.
Cross-platform — all four tools and the hook are plain Node.js (path.join,
os.homedir(), no hardcoded /) shelling out to git/gh, both of which
run natively on Windows too. No platform-specific code path.
Updating
There's no separate build or publish step — claude mcp add points
straight at this checkout's src/server.js, so updating is just:
git pull && npm installTake effect on the next new Claude Code session (each session spawns its own MCP server process, so an already-running session keeps using the code it started with).
Tool: sweep_status
Argument | Type | Default | Meaning |
| string | — (required unless | Folder to scan, one level deep (e.g. |
| string[] | — | Several roots in one call instead of one |
| string[] | all subfolders | Limit to specific repo names instead of scanning everything (matched across all roots) |
| boolean |
| Also query GitHub Actions for each repo's latest run |
| boolean |
| Only return repos that need a look; |
Each repo entry: name, path, branch, uncommittedFiles (count),
ahead/behind (vs upstream, null if no upstream configured),
hasUpstream, and ci ({status, conclusion, workflow, url} or null).
Tool: check_docs
Argument | Type | Default | Meaning |
| string | — (required unless | Folder with the repos |
| string |
| Folder with the |
|
| — | Several independent projectsRoot+docsRoot pairs in one call instead of one |
| string[] | all subfolders | Limit to specific repo names (applied within each point independently) |
| boolean |
| Only return missing/stale; |
Each repo entry: name, projectsRoot (which point it came from),
docPath, status (missing / stale /
current / no-commits), trackingMethod (commit if the doc was
written via write_doc, mtime otherwise — see below), lastCommitAt,
and either commitsSinceWrite/writtenAtCommit/writtenAt (commit
tracking) or docUpdatedAt/staleBySeconds (mtime tracking, only on
stale).
Tool: write_doc
Argument | Type | Default | Meaning |
| string | — (required) | Folder with the repos |
| string | — (required) | Repo folder name (e.g. |
| string | — (required) | Full text to write to |
| string |
| Folder with the |
Writes <repo>.txt and, next to it, .meta/<repo>.json with the repo's
HEAD commit hash at write time. check_docs then reports the exact
number of commits since the doc was written (git rev-list --count)
instead of the coarser mtime-vs-last-commit-time comparison — the same
pattern check_release_drift already uses for source→release drift. Docs
written directly (e.g. via a plain file write, not this tool) keep using
mtime tracking — there's no meta file to compare against.
Tool: check_release_drift
Argument | Type | Default | Meaning |
| string | — (required) | Folder with the repos |
|
| — (required) | Explicit list of source→release folder-name pairs |
| boolean |
| Only return |
Each pair entry: source, release, status (drifted / current /
no-tags), and on drifted: latestTag, tagCreatedAt,
commitsSinceTag, oldestUnreleasedCommitAt, oldestUnreleasedAgeDays.
Architecture
src/sweep.js— all the logic: finds.gitfolders one level under a root (exported asfindGitRepos, reused bydocs.js), then for each one runsgit branch/git status/git rev-listand (optionally)gh run listin parallel, batched at 8 repos at a time to avoid hammering the GitHub API.sweepStatus()'sroots(plural) runsfindGitReposper root and merges the results before filtering byrepos/only_attention— so a repo name filter matches regardless of which root it actually lives under.src/docs.js—checkDocs(): prefers commit-based tracking (.meta/<repo>.json, written bywrite_doc) when available; falls back to comparinggit log -1 --format=%ctagainst the doc file's mtime for docs written directly. A repo with no commits yet reportsno-commitsrather than being silently lumped intomissingorcurrent.points(plural) checks each independent projectsRoot+docsRoot pair in turn and tags every result with which one it came from.src/write-doc.js—writeDoc(): writes<repo>.txtplus.meta/<repo>.json({commitHash, writtenAt},HEADat write time). Doesn't generate the text itself — understanding a codebase well enough to document it stays an LLM/human job.src/server.js— registers all four tools with the MCP SDK over the stdio transport.test/smoke.mjs—sweep_statusagainst real local repos (no synthetic fixtures needed — the workspace itself already has clean, dirty, and upstream-less repos to test against), plus aroots(plural) case against a real root and a throwaway empty one.test/docs.mjs—check_docsagainst temporary, throwaway git repos with controlled commit/file timestamps (real~/Projectsdrifts over time, which would make a fixed test flaky), including both tracking methods and apoints(plural) case.test/write-doc.mjs—writeDoc()against a temporary git repo: correctHEADcaptured,.meta/created on demand, empty content rejected.test/hook.mjs—hooks/check-docs-reminder.mjsas a real subprocess (it's a CLI entry point, not a library function): silent outside any watch point, silent with noArchitecture/folder at all, reminds and resolves the right repo from a nested subdirectory, the watch-points config file driving two independent points at once, and an empty/absentpointsarray in that file falling through to the next source.src/release-drift.js—checkReleaseDrift(): finds the release repo's most recent tag viagit for-each-ref --sort=-creatordate(sorted by actual tag time, not the semver-string sort-v:refnamewould give —v1.10would otherwise sort beforev1.9), then countsgit log --since=@<tagTimestamp>in the source repo. The source↔release relationship isn't guessable from folder structure (no general rule "folder X releases folder Y"), so the caller passes pairs explicitly.test/release-drift.mjs— temporary repos with explicitGIT_AUTHOR_DATE/GIT_COMMITTER_DATEper commit (not relying on real wall-clock gaps between commits made milliseconds apart in a test run, whichgit log --since's second-level granularity could otherwise make flaky), plus one live check against the real NyxilumLang→NyxilumNode pair that only asserts it doesn't throw.
License
MIT — Faneraiy14.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceLocal-only GitHub Actions and CI maintenance scanner for AI-built apps. Exposes scan, explanation, and fix-planning tools to MCP clients; modifies nothing and makes no outbound requests by default.3632MIT
- AlicenseAqualityBmaintenanceAn MCP server that provides operational tooling over the GitHub API — issue triage, PR review monitoring, repo health audits, and team access reviews.111MIT
- AlicenseNot gradedqualityAmaintenanceCI health reports for GitHub Actions: flaky tests named from logs, wasted compute priced in dollars, zombie crons, PR feedback time, plus 21 lint rules with safe auto-fixes. Read-only MCP tools wrap the same Go binary.MIT
- FlicenseNot gradedqualityCmaintenanceEnables detection and remediation of Kubernetes GitOps drift via MCP tools, supporting drift detection, policy evaluation, patch application, PR generation, and audit trail retrieval.
Related MCP Connectors
Living docs and MCP context for GitHub repos — conventions, gaps, and source-cited pages on merge.
Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.
Revternal MCP — wraps the Revternal Developer Intelligence API
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Faneraiy14/workspace-status-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server