Repository navigation
Releases: Majrooo/majrooo-mcp-devkit
Releases · Majrooo/majrooo-mcp-devkit
Release list
v0.2.1
v0.2.1
Added
universal_find_references: with more than one searched root the report now lists the searched roots, marks the root each file path is relative to (file.rs (relative to <root>)) and states how many duplicate files were skipped — so a path likeproject/src/lib.rscan no longer be mistaken for a second copy ofsrc/lib.rs.universal_find_references: the audit log entry now recordssearchedRootsandduplicatesDropped.- 10 new tests (
symbols.test.ts): nested-root pruning, duplicate detection via a junction, sibling roots with an identical relative path, single-root parity withuniversalFindReferences, and the report format (total 348). - CI (
.github/workflows/ci.yml):npm ci+npm run build+npm testonwindows-latestandubuntu-latest, plus anubuntu-latestjob that runs the same suite withMCP_PROJECT_ROOT/MCP_EXTRA_ROOTS/MCP_PROJECT_NAMESset (the root registry and project aliases are read from the environment at import time, so both cases have to keep passing). CI status badge added to README.
Changed
run_command_grep: a zero-match response no longer returns a bare(žiadna zhoda)— it now states what was scanned:(žiadna zhoda — 0 z N riadkov výstupu, exit code 0)on the normal path, and(žiadna zhoda — výstup prázdny, exit code M)/exit code neznámy(signal/timeout) in the catch block.Nájdených N zhôd: …is unchanged. Motivation: the same text was returned for "output scanned, nothing matched" and "command produced nothing", which was misread as a lost command (feedback 2026-09-16 — the only actionable part of a report that was otherwise not reproducible). New helperformatZeroMatch()insrc/format.ts+ 3 tests (total 354).
Fixed
universal_find_references: every match was reported twice whencwdwas omitted — all registered roots were searched, and because the registry contains nested pairs (D:\W\TS+ the projects inside it,…\Rust+…\Rust\pixel-blaster-engine) the same file was reachable through two roots. The dedup key was the root-relative path (different per root) andtotalMatchessummed every root, soColAlignreported 56 matches for 28 real ones, the listing was truncated mid-output, and the two path prefixes made one file look like two. Nested roots are now pruned (pruneNestedRoots), files are deduplicated by resolved real path, andtotalMatchesis the sum over the files actually listed. Distinct files that exist in two sibling roots under the same relative path are no longer silently dropped.universal_find_references:cwdwas documented as "default: primary project root" while the implementation searched every registered root — the description now matches the behaviour (tool description,cwdparameter,help_tool, README).- The test suite is no longer Windows-only. Fixtures that were hardcoded
D:\.../Z:\...literals are relative paths on POSIX, so the affected tests could only pass on Windows (resolveCwdRequested,resolveFilePath,resolve_cwd,buildRegistrations / findMatchingRegistration,findOutOfRootWriteTargets,findSuspiciousCrossRootReads,findAliasByName / findAliasByPath,findEscapeReason — git -C bypass). They now build a real tree underos.tmpdir()withpath.join/path.sep— the pattern the multi-root fallback block already used — and separator-agnostic path assertions. Coverage is unchanged (348 tests, still green on Windows); POSIX is enforced by the new CI job. - POSIX: the command-target safety checks were silently Windows-only.
isFlag()tested^\/[a-z]unanchored, and on POSIX every absolute path starts with/<letter>— so an absolute POSIX path was read as a cmd flag andfindOutOfRootWriteTargetsnever saw the target ofmkdir /tmp/x,mkdir -p /tmp/xorcopy a.txt /tmp/x(worst case thecopy/movebranch fell back toa.txt).QUOTED_PATH(cross-root reads, active withMCP_BLOCK_CROSS_ROOT_READS=1) matchedC:\,../and~/only, so quoted absolute POSIX reads were invisible. Both are fixed:isFlag()now accepts a/xflag only as a 1–2 letter token, andQUOTED_PATHgained a POSIX absolute branch (a quoted token is a path, never a flag). The 5 previously skipped assertions run again, plus 3 new platform-neutral regression tests (mkdir/copyat the filesystem root, quoted absolute read) that fail on the old code even on Windows.
Known Limitations (documented)
- Residual: a 1–2 letter directory directly under the filesystem root (
/a) is still read as a cmd flag byisFlag()— use a longer name or the unquoted full path form for such targets.
v0.2.0
v0.2.0
Added
close_feedback: closing an entry now also moves every closed entry out of the active log into.mcp/FEEDBACK_ARCHIVE.md, so.mcp/FEEDBACK.mdkeeps holding open items only (it had grown to 39 entries / 65 KB). The move is append-first (block written to the archive before it is removed from the log, so a crash can at most duplicate, never lose an entry), idempotent (entries already archived are skipped) and self-healing (entries closed before this feature are migrated with the next close).close_feedbackreturnsarchived(IDs moved) andarchivePath.list_feedback: newarchivedparameter —truelists.mcp/FEEDBACK_ARCHIVE.md(closed entries) instead of the active log; all existing filters (type,tool,status) apply to the archive too.archiveClosedEntries()(src/feedback.ts) — bulk-migrates closed entries from the active log to the archive; also reused byclose_feedback.batch_apply_edits: explicit machine-readable outcome — every response now carriesmessage(human summary),appliedEdits(edits whose changes are on disk),written(files changed on disk) andapplied: true|falseon eachpreviewentry. Failure responses additionally carryreason(validation_failed|write_failed),reverted(files rolled back) andnothingWritten. A validation failure now says plainlyVALIDATION FAILED on edit #N of M — NO edits were written to diskinstead of returning a preview that looks like a partial success; when writes did happen but were all rolled back it saysNO net changes were left on disk: N edit(s) had been written and M file(s) were rolled back […]. The MCP tool result is the message followed by the JSON payload.batch_apply_edits: preview is padded to map 1:1 to theeditsarray — edits that were never reached get anaction: "error"entry withnot evaluated — batch stopped at edit #N.batch_apply_edits:excludePatternsparameter — whenreplaceAllis used withexcludePatterns, occurrences inside excluded regions (e.g.#[cfg(test)]blocks) are skipped. Handles annotation-on-separate-line with 5-line lookahead for opening brace.batch_apply_edits: sequential validation in Phase 2 — each edit is re-validated against current file state (after previous edits) with rollback on failure. Phase 1 defers validation for chained edits on same file.findEscapeReason(): optionalcwdparameter — when a command contains bothgit -C/--git-dir/--work-treeand a cd/pushd escape pattern, the function checks if the git path resolves insidecwdbefore flagging as escape.safetyCheck()now passescwdtofindEscapeReason().- 9 new tests (total 317, up from 308)
- 6 new tests for explicit
batch_apply_editsoutcome reporting (total 323) report_tool_feedback: the reportedtoolname is now validated against this server's tool registry — unknown names are rejected without writing anything, with a "did you mean …?" suggestion for typos (Unknown tool 'batch_apply_edit' … Did you mean 'batch_apply_edits'?); when nothing is close, the error lists the tools this server exposes. New optional parameterallowUnknownTool: truebypasses the check for missing-capability reports about the server as a whole. Validation runs only when the handler supplies the registry, so the pure function stays usable without one.- 8 new tests for the feedback archive (self-healing migration, idempotency, verbatim blocks, archived filters, log hygiene) (total 331)
- 7 new tests for tool-name validation + legacy log normalization (total 338)
Changed
resolveFilePath()multi-root fallback now triggers even whencwdis provided but the file doesn't exist at the resolved location. Scans all allowed roots for the relative path — 1 match auto-resolves, 2+ shows disambiguation error.ALLOWED_ROOTSnow includes paths fromMCP_PROJECT_NAMES(friendly project names). Projects registered only viaMCP_PROJECT_NAMESand not viaMCP_EXTRA_ROOTSare now recognised as allowed roots — fixes file-based tools failing to resolve paths for alias-registered projects.run_command_grep: catch block now extracts stdout/stderr from exec error object. Non-zero exit code with output returns matches instead of error.
Fixed
batch_apply_edits: sequential application — edit 2 can now find text created by edit 1 on the same file (was failing with "search string not found" because Phase 1 validated all edits against original file content).batch_apply_edits:replaceAllno longer breaks test code — useexcludePatterns: ["#[cfg(test)]"]to skip test modules.batch_apply_edits: relative/absolute paths now resolve correctly when the target project is registered only viaMCP_PROJECT_NAMES(was resolving against devkit root instead of project root).batch_apply_edits: partial rollback — when a chained edit fails, only files modified by the failed edit and subsequent edits are reverted. Files successfully modified by earlier edits are preserved (was: full atomic rollback lost all valid edits).extract_code_block: relative and absolute paths now resolve correctly for alias-registered projects (was returning "Cannot read file" for files within the project).run_command_grep: zero matches with non-zero exit code now returns empty result instead of error.batch_apply_edits: validation-failure response was ambiguous — the returnedpreviewshowedaction: "edit", matchCount: 1for edits that had validated while no edit was written at all, so callers could not tell that the batch was a complete no-op. The response now statesVALIDATION FAILED on edit #N of M — NO edits were written to diskplus machine-readableappliedEdits,written,reverted,nothingWrittenand per-entryapplied.extract_code_block: relative paths now resolve across all allowed roots even whencwdis provided.report_tool_feedback: appending an entry no longer stacks---separators — a trailing separator left by the previous write is removed first, so the log keeps exactly one separator between entries (.mcp/FEEDBACK.mdhad accumulated doubled separators over time).close_feedback/archiveClosedEntries(): rewriting the active log after an archive no longer leaves a doubled separator and extra blank lines between the header and the first entry.
Known Limitations (documented)
batch_apply_edits: same-file chain failures revert the entire file (can't partially undo changes to a single file).run_safe_command: 60s client-side timeout limit (MCP client, not server) — userun_commandstool for long-running commands.- Windows
cmd.exe:;is not a command separator — use&or separate tool calls. universal_find_references: symbols with special characters (colons, spaces) may fail when sent from certain MCP clients due to client-side JSON-RPC serialization issues.
v0.1.1
v0.1.1
Added
- Supported Languages section in README.md (Rust, TypeScript, Python, C++)
- Multi-root fallback for
resolveFilePath(): relative paths withoutcwdnow scan all allowed roots — unique match auto-resolves, multiple matches produce disambiguation error (6 new tests) - 6 new tests for
resolveFilePathmulti-root fallback (total 300, up from 294) - Tool Annotations (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint) for all 17 tools per MCP spec src/__tests__/tool-integration.test.ts— 23 new tests coveringlist_tools,help_tool,read_log_slice,list_allowed_roots,resolve_cwd- M8ven Trust Index badge in README.md
- Release automation script (
scripts/release.cjs) - Pre-commit hook: blocks sensitive files (.env, .key, .pem, etc.)
- Pre-push hook: gitleaks scan + path scanner for tracked files
- 7 refactoring tools (Phase 1–3):
universal_find_references— language-agnostic symbol search with optional role detection (declaration/import/usage)extract_code_block— code block extraction with annotation-aware, string/comment-safe bracket matchingsplit_file_by_declarations— split large files into modules with index generation (mod.rs/index.ts/init.py)batch_apply_edits— atomic multi-file edits with validation-first and rollback on failuregenerate_module_skeleton— generate module files by extracting symbols from sourceverify_refactor_safety— semantic diff with 5 checks (function count, signatures, exports, imports, comment ratio)
report_tool_feedback— agent feedback tool for bugs, improvements, feature requests (writes to.mcp/FEEDBACK.md, idempotent, project-protected)list_feedback— list feedback entries with optional filters (type, tool, status)close_feedback— close feedback entries by ID with optional resolution textlist_tools— lists all available MCP tools with markdown-formatted descriptions, filterable by categoryhelp_tool— detailed help for any tool including markdown parameter tabletextResult()/jsonResult()helpers insrc/format.tsfor consistent MCP response formatting- Test fixtures (
src/__tests__/fixtures/) with Rust, TypeScript, Python test data - Bypass test suite: 14 tests documenting security heuristic coverage and known limitations (base64, variable indirection, encoded cd)
- Integration test suite (
src/__tests__/handlers.test.ts): 7 tests verifying tool output format - Shared
resolveFilePath()helper insrc/safety.ts— unified file path resolution with alias lookup + allowed roots validation for all file-based tools cwdparameter forsplit_file_by_declarations,generate_module_skeleton, andbatch_apply_edits(relative path resolution)- 6 new tests for
resolveFilePath()(total 269, up from 263) - 116 new tests (total 263, up from 147)
- Shared parsing helpers exported from
src/symbols.ts(tokenizer, bracket matching, annotation detection) tsconfig.json: exclude test fixtures from compilation
Changed
resolveFilePath()now checks file existence on disk before falling back to scan other allowed roots — prevents silent misresolution when multiple projects share common filenames (e.g.index.ts,README.md)- README.md: added
cwdparameter toextract_code_blockdocumentation, updated test badge to 300, described multi-root path resolution inbatch_apply_editsand Typical workflow section - PROJECT_CONTEXT.md: added language support entry, updated test count to 300
index.tsrefactored — extractedsrc/commands.ts(safetyCheck, executeCommand, executeGrep, resolveToolCwd) andsrc/helpers.ts(temp paths, audit log, line parsing);index.tsreduced from 1349 to 950 lines (-30%)- Audit logging removed from
list_toolsandhelp_tool(discovery tools are now truly read-only) - Upgraded
@modelcontextprotocol/sdkfrom 1.29.0 to 1.30.0 - Refactored
extract_code_blockto use sharedresolveFilePath()(replaced inline ad-hoc path resolution with safety validation)
Fixed
- README.md: test count badge updated from 294 to 300
- Closed feedback:
batch_apply_editsrelative paths now resolve across allowed roots - Closed feedback:
list_toolsraw JSON envelope — identified as Cline client display issue, not server bug batch_apply_edits: addedcwdparameter +resolveFilePath()— now resolves relative paths (was returning "Cannot read file" for files in newly created subdirectories)split_file_by_declarations&generate_module_skeleton: multi-lineuse/importblocks now collected completely (was truncated at first line, breaking generated imports)extract_code_block&split_file_by_declarations: removed#→ line comment handling from tokenizer — Rust#[derive(...)]/#[allow(...)]attributes no longer cause missing closing braces in extracted functionssplit_file_by_declarations: now includes top-leveluse/importstatements in generated modulessplit_file_by_declarations: detects and appendsimplblocks associated with extracted types (Rust)split_file_by_declarations&generate_module_skeleton: relative file paths now resolve correctly via sharedresolveFilePath()helper (was returning "Cannot read file")split_file_by_declarations: finds private declarations (fn,const,struct) andpub(crate)/pub(super)itemsgenerate_module_skeleton: filtersextractCodeBlockmatches to declaration-only — no more garbled output from usage sitesgenerate_module_skeleton: imports now only collected from top-level (no indentedusestatements)split_file_by_declarations: cross-module references now generateuse super::TypeName;importssplit_file_by_declarations: cfg-aware cross-module imports — wraps with#[cfg(...)]when symbol is only used in cfg-gated code, falls back to#[allow(unused_imports)]split_file_by_declarations:modblocks (e.g.#[cfg(test)] mod tests) now extractablebatch_apply_edits: multiple edits to same file now accumulate correctly (was overwriting previous edits)batch_apply_edits: CRLF line endings now handled — normalizes to LF for comparison, preserves original endings in outputextract_code_block: addedcwdparameter — relative paths now resolved against cwd or primary rootuniversal_find_references: withoutcwd, now searches ALL allowed roots (was defaulting to primary root only)- LICENSE restructured — standard GPL text first, project copyright as appendix
v0.1.0
v0.1.0
Added
- 6 MCP tools:
run_safe_command,run_destructive_command,read_log_slice,
run_command_grep,list_allowed_roots,resolve_cwd - Safety layers: dangerous-pattern blacklist, directory-escape detection,
write-target checks, destructive confirmation, missing target guard - Output normalization: Windows UTF-8, ANSI stripping, redirect reporting
- GPL-3.0-or-later license (full text in LICENSE)
- 147 passing tests (vitest)
- Branch protection: linear history, force push blocked
- README badge shields (Version, License, Tests, Node.js)
- GitHub About: description, homepage, topics