Skip to content

feat(mcp): add style parameter support to MCP tools#839

Merged
yamadashy merged 4 commits intomainfrom
feat/mcp-style
Sep 14, 2025
Merged

feat(mcp): add style parameter support to MCP tools#839
yamadashy merged 4 commits intomainfrom
feat/mcp-style

Conversation

@yamadashy
Copy link
Owner

This PR adds support for specifying output format styles in MCP tools, allowing users to choose between XML, Markdown, JSON, and Plain text formats for their AI analysis workflows.

Summary

  • ✅ Added style parameter to packCodebaseTool and packRemoteRepositoryTool
  • ✅ Enhanced attachPackedOutputTool to handle multiple input formats (xml, md, txt, json)
  • ✅ Added detailed format descriptions to help users choose the right format:
    • XML: Structured with <file> tags (default)
    • Markdown: Human-readable with ## headers and code blocks
    • JSON: Machine-readable with files as key-value pairs
    • Plain: Simple format with separators
  • ✅ Implemented format-specific parsing functions for each output style
  • ✅ Maintained backward compatibility with XML as the default format
  • ✅ Updated tests to handle new function signatures

Changes

Modified Files

  • src/mcp/tools/packCodebaseTool.ts - Added style parameter with detailed descriptions
  • src/mcp/tools/packRemoteRepositoryTool.ts - Added style parameter with detailed descriptions
  • src/mcp/tools/attachPackedOutputTool.ts - Added multi-format support and parsing functions
  • tests/mcp/tools/attachPackedOutputTool.test.ts - Updated tests for new functionality

New Features

  • Style parameter defaults to 'xml' for backward compatibility
  • Dynamic output filename based on selected style
  • Comprehensive format-specific content parsing
  • Enhanced tool descriptions explaining format differences

Checklist

  • Run npm run test
  • Run npm run lint

Add support for specifying output format style (xml, markdown, json, plain) in MCP pack tools and attach tool. This allows users to choose the most appropriate format for their AI analysis workflows.

Changes:
- Add style parameter to packCodebaseTool with detailed format descriptions
- Add style parameter to packRemoteRepositoryTool with detailed format descriptions
- Update attachPackedOutputTool to handle multiple input formats (xml, md, txt, json)
- Add format-specific parsing functions for each output style
- Update tool descriptions to explain the differences between formats
- Fix tests to handle new function signatures and add path.extname mock

The style parameter defaults to 'xml' for backward compatibility.
Copilot AI review requested due to automatic review settings September 14, 2025 13:45
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 14, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds multi-format support (XML, Markdown, JSON, plain text) across packing and attaching tools. Introduces style-aware output selection and dynamic filenames. Implements format detection and parsing in attachPackedOutputTool, with format-specific extractors and processedFiles generation. Updates input schemas and handler signatures to include a style option. Adjusts tests for unsupported extensions.

Changes

Cohort / File(s) Summary
Attach tool: multi-format detection and parsing
src/mcp/tools/attachPackedOutputTool.ts
Adds format detection for XML/Markdown/Plain/JSON, resolves file and format from path or directory via defaultFilePathMap, implements format-specific metric extractors, creates processedFiles, updates descriptions, and enhances error handling.
Pack tools: style option and dynamic output file mapping
src/mcp/tools/packCodebaseTool.ts, src/mcp/tools/packRemoteRepositoryTool.ts
Extends input schema with optional style (default xml), passes style to CLI, selects output filename via defaultFilePathMap[style], updates handler signatures and tool descriptions.
Tests update for unsupported format
tests/mcp/tools/attachPackedOutputTool.test.ts
Mocks path.extname, updates test to use .xyz extension and renames case to reflect unsupported format handling.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Caller
  participant AttachTool as attachPackedOutputTool
  participant FS as FileSystem
  participant Parser as Format Extractors

  Caller->>AttachTool: call({ path })
  AttachTool->>AttachTool: resolvePathAndFormat(path)
  alt Path is directory
    AttachTool->>FS: check defaultFilePathMap[style] candidates
    FS-->>AttachTool: first existing file path + inferred format
  else Path is file
    AttachTool->>AttachTool: detect format by extension
  end
  AttachTool->>FS: readFile(resolvedPath)
  FS-->>AttachTool: content
  AttachTool->>Parser: extractFileMetrics(content, format)
  Parser-->>AttachTool: { filePaths, charCounts }
  AttachTool->>AttachTool: compute totals, tokens, processedFiles
  AttachTool-->>Caller: formatPackToolResponse({...}) or error JSON
Loading
sequenceDiagram
  autonumber
  actor Caller
  participant PackCodebase as pack_codebase
  participant CLI as repomix CLI
  participant FS as FileSystem

  Caller->>PackCodebase: call({ directory, style?, ... })
  PackCodebase->>PackCodebase: style := style || 'xml'
  PackCodebase->>CLI: run({ directory, style, ... })
  CLI-->>PackCodebase: exit code / result
  PackCodebase->>PackCodebase: outputPath := join(directory, defaultFilePathMap[style])
  PackCodebase-->>Caller: formatPackToolResponse(outputPath)
Loading
sequenceDiagram
  autonumber
  actor Caller
  participant PackRemote as pack_remote_repository
  participant CLI as repomix CLI
  participant FS as FileSystem

  Caller->>PackRemote: call({ remote, style?, ... })
  PackRemote->>PackRemote: style := style || 'xml'
  PackRemote->>CLI: run({ remote, style, ... })
  CLI-->>PackRemote: exit code / result
  PackRemote->>PackRemote: outputPath := join(workdir, defaultFilePathMap[style])
  PackRemote-->>Caller: formatPackToolResponse(outputPath)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat(mcp): add style parameter support to MCP tools" is concise, follows conventional commit style, and accurately summarizes the primary change in the changeset (adding a style parameter and multi-format support to MCP tools such as packCodebaseTool, packRemoteRepositoryTool, and attachPackedOutputTool), making it easy for teammates to scan history and understand the main intent.
Description Check ✅ Passed The PR description adheres to the repository template by including a summary of changes, a checklist (with tests and lint marked complete), a clear "Summary" section, a list of modified files, and details about features and defaults (XML as default and supported formats), which aligns with the raw summary and PR objectives and provides reviewers the necessary context to evaluate the change. It documents the key implementation and behavioral changes (style parameter, multi-format parsing, updated tests) and is sufficient for typical review.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @yamadashy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the flexibility of MCP tools by introducing support for multiple output formats (XML, Markdown, JSON, and Plain text) when packing codebases or remote repositories. The packCodebaseTool and packRemoteRepositoryTool now include a style parameter, allowing users to specify their preferred output format. Concurrently, the attachPackedOutputTool has been upgraded to automatically detect and correctly parse content from any of these new formats, streamlining AI analysis workflows. The changes maintain backward compatibility by defaulting to XML and include updated tool descriptions for clarity.

Highlights

  • Multi-format Output Support: The packCodebaseTool and packRemoteRepositoryTool now accept a style parameter, enabling output in XML, Markdown, JSON, or Plain text formats.
  • Enhanced Input Parsing: The attachPackedOutputTool has been updated to intelligently detect and parse these new output formats, improving flexibility for AI analysis.
  • Backward Compatibility: XML remains the default output style for all packing tools, ensuring existing workflows are unaffected by these changes.
  • Comprehensive Format Descriptions: Tool descriptions now include detailed explanations of each supported output format to guide users in choosing the appropriate style.
  • Updated Test Coverage: Tests for attachPackedOutputTool have been expanded to validate the new multi-format parsing capabilities and error handling for unsupported formats.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for specifying output format styles in MCP tools, allowing users to choose between XML, Markdown, JSON, and Plain text formats for their AI analysis workflows. This enhances the flexibility of the MCP tools while maintaining backward compatibility with XML as the default format.

  • Added style parameter to packCodebaseTool and packRemoteRepositoryTool with format descriptions
  • Enhanced attachPackedOutputTool to handle multiple input formats (xml, md, txt, json) with format-specific parsing functions
  • Updated tests to handle new function signatures and mock additional path utilities

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/mcp/tools/packCodebaseTool.ts Added style parameter with detailed format descriptions and dynamic output filename
src/mcp/tools/packRemoteRepositoryTool.ts Added style parameter with format descriptions and output filename mapping
src/mcp/tools/attachPackedOutputTool.ts Enhanced to support multiple formats with format detection and parsing functions
tests/mcp/tools/attachPackedOutputTool.test.ts Updated test mocks and test case description for new functionality

Comment on lines +195 to +199
while (true) {
match = fileRegex.exec(content);
if (!match) {
break;
}
Copy link

Copilot AI Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace the infinite loop with a more idiomatic while condition. Use while ((match = fileRegex.exec(content)) !== null) instead of the infinite loop with break statement.

Copilot uses AI. Check for mistakes.
Comment on lines +220 to +224
while (true) {
match = fileRegex.exec(content);
if (!match) {
break;
}
Copy link

Copilot AI Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace the infinite loop with a more idiomatic while condition. Use while ((match = fileRegex.exec(content)) !== null) instead of the infinite loop with break statement.

Copilot uses AI. Check for mistakes.
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 14, 2025

Deploying repomix with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3f86488
Status: ✅  Deploy successful!
Preview URL: https://1f3304b9.repomix.pages.dev
Branch Preview URL: https://feat-mcp-style.repomix.pages.dev

View logs

@codecov
Copy link

codecov bot commented Sep 14, 2025

Codecov Report

❌ Patch coverage is 95.20548% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.27%. Comparing base (14f1075) to head (3f86488).
⚠️ Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
src/mcp/tools/attachPackedOutputTool.ts 96.52% 4 Missing ⚠️
src/mcp/tools/packRemoteRepositoryTool.ts 75.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #839      +/-   ##
==========================================
+ Coverage   87.13%   87.27%   +0.14%     
==========================================
  Files         113      113              
  Lines        6723     6839     +116     
  Branches     1384     1408      +24     
==========================================
+ Hits         5858     5969     +111     
- Misses        865      870       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request effectively introduces support for multiple output formats (XML, Markdown, JSON, Plain) in the MCP tools. The implementation is generally solid, with good separation of concerns for parsing different formats. My review includes suggestions for improving code maintainability by using more modern JavaScript features and reducing code duplication. The most critical feedback is the absence of unit tests for the new parsing logic for Markdown, JSON, and plain text formats. It's crucial to add these tests to ensure the new functionality is robust and reliable.


test('should handle non-XML file error', async () => {
const testFilePath = '/test/not-xml-file.txt';
test('should handle non-supported file format error', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This pull request introduces significant new parsing logic for Markdown, Plain text, and JSON formats, but there are no tests covering these new code paths. Please add unit tests for extractFileMetricsMarkdown, extractFileMetricsPlain, and extractFileMetricsJson. You should also add integration tests within this file that exercise the attachPackedOutputTool with .md, .txt, and .json files to ensure they are resolved and parsed correctly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/mcp/tools/attachPackedOutputTool.test.ts (1)

77-107: Add tests for markdown/json/plain and CRLF parsing.

Current tests only cover XML. Add positive cases for each format and a CRLF variant to guard regexes.

I can add fixtures and tests for:

  • Markdown: “## File: …” + fenced code
  • Plain: “================” separators
  • JSON: { "files": { "path": "content" } } and array variant
  • CRLF versions of each

Also applies to: 180-192

🧹 Nitpick comments (8)
src/mcp/tools/packRemoteRepositoryTool.ts (2)

39-43: Validate bounds for topFilesLength.

Permit only reasonable integers (e.g., >=1). Currently any number passes, including negatives/NaN.

-  topFilesLength: z
-    .number()
+  topFilesLength: z
+    .number().int().min(1)
     .optional()
     .default(10)

44-49: Schema nit: default already implies optional.

.default('xml') makes the field optional; .optional() is redundant.

-  style: repomixOutputStyleSchema
-    .optional()
-    .default('xml')
+  style: repomixOutputStyleSchema.default('xml')
src/mcp/tools/packCodebaseTool.ts (2)

35-39: Validate bounds for topFilesLength.

Mirror the remote tool: enforce integer >=1.

-  topFilesLength: z
-    .number()
+  topFilesLength: z
+    .number().int().min(1)
     .optional()
     .default(10)

40-45: Schema nit: default already implies optional.

-  style: repomixOutputStyleSchema
-    .optional()
-    .default('xml')
+  style: repomixOutputStyleSchema.default('xml')
src/mcp/tools/attachPackedOutputTool.ts (4)

164-182: XML entity decoding for accurate char counts.

If the XML encoder escapes characters, lengths are inflated. Decode entities before counting.

-const fileContent = match[2];
+let fileContent = match[2];
+fileContent = fileContent
+  .replaceAll('&lt;', '<')
+  .replaceAll('&gt;', '>')
+  .replaceAll('&amp;', '&')
+  .replaceAll('&quot;', '"')
+  .replaceAll('&apos;', "'");

187-207: Windows line endings support.

Use \r?\n in regex to parse CRLF files.

-const fileRegex = /## File: ([^\n]+)\n```[^\n]*\n([\s\S]*?)```/g;
+const fileRegex = /## File: ([^\r\n]+)\r?\n```[^\r\n]*\r?\n([\s\S]*?)```/g;
-const fileRegex = /={16,}\nFile: ([^\n]+)\n={16,}\n([\s\S]*?)(?=\n={16,}\n|$)/g;
+const fileRegex = /={16,}\r?\nFile: ([^\r\n]+)\r?\n={16,}\r?\n([\s\S]*?)(?=\r?\n={16,}\r?\n|$)/g;

Also applies to: 212-232


241-254: JSON variant: support array-form as well.

In case JSON packs use { files: [{ path, content }] }, add a fallback.

-const files = jsonData.files || {};
-
-for (const [filePath, fileContent] of Object.entries(files)) {
+const files = jsonData.files || {};
+if (Array.isArray(files)) {
+  for (const f of files) {
+    if (f && typeof f.path === 'string' && typeof f.content === 'string') {
+      filePaths.push(f.path);
+      fileCharCounts[f.path] = f.content.length;
+      fileContents[f.path] = f.content;
+    }
+  }
+} else {
+  for (const [filePath, fileContent] of Object.entries(files)) {
     if (typeof fileContent === 'string') {
       filePaths.push(filePath);
       fileCharCounts[filePath] = fileContent.length;
+      fileContents[filePath] = fileContent;
     }
   }
+}

286-291: Reduce noisy console.warn in library code.

Prefer a debug logger or remove to keep MCP logs clean.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14f1075 and 454bc8c.

📒 Files selected for processing (4)
  • src/mcp/tools/attachPackedOutputTool.ts (7 hunks)
  • src/mcp/tools/packCodebaseTool.ts (4 hunks)
  • src/mcp/tools/packRemoteRepositoryTool.ts (4 hunks)
  • tests/mcp/tools/attachPackedOutputTool.test.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/mcp/tools/attachPackedOutputTool.ts (2)
src/config/configSchema.ts (1)
  • defaultFilePathMap (9-14)
src/core/file/fileTypes.ts (1)
  • ProcessedFile (6-9)
src/mcp/tools/packRemoteRepositoryTool.ts (2)
src/config/configSchema.ts (2)
  • repomixOutputStyleSchema (5-5)
  • defaultFilePathMap (9-14)
src/mcp/tools/mcpToolRuntime.ts (1)
  • createToolWorkspace (49-59)
src/mcp/tools/packCodebaseTool.ts (2)
src/config/configSchema.ts (2)
  • repomixOutputStyleSchema (5-5)
  • defaultFilePathMap (9-14)
src/mcp/tools/mcpToolRuntime.ts (1)
  • createToolWorkspace (49-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Build and run with Bun (windows-latest, latest)
  • GitHub Check: Test (windows-latest, 24.x)
  • GitHub Check: Test (windows-latest, 20.x)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
tests/mcp/tools/attachPackedOutputTool.test.ts (3)

48-51: Good: extname mock ensures extension routing is testable.


149-156: Nice rename; broadened unsupported extension test matches new formats.


69-75: Tool registration assertions look good.

src/mcp/tools/packCodebaseTool.ts (1)

86-88: Drop redundant 'xml' fallbacks; rely on input-schema default for style

The Zod input schemas default style to 'xml', so remove "|| 'xml'" and pass style directly (no type-change needed). Apply to:

  • src/mcp/tools/packCodebaseTool.ts (≈ lines 86–98)
  • src/mcp/tools/packRemoteRepositoryTool.ts (≈ lines 83–96)

- Replace while loops with idiomatic for...of matchAll() patterns in all extractFileMetrics functions
- Generate supportedExtensions dynamically from defaultFilePathMap instead of hardcoding
- Remove console.warn from JSON parser for consistency with other format parsers
- Add comprehensive tests for new Markdown, Plain, and JSON parser functions

Addresses all automated review feedback from CodeRabbit, Copilot, and Gemini Code Assist.
- Remove unused match variables from extractFileMetrics functions
- Fix unused error parameter in JSON parser catch block
- Correct test expectations for Markdown parsing (account for newlines in extracted content)
- Ensure all tests properly declare result variables where needed

All tests pass and lint issues resolved.
- Add CRLF support for Windows line endings in Markdown and Plain parsers
- Improve Zod schema validation: topFilesLength now requires integer >= 1
- Remove redundant || 'xml' fallbacks as Zod defaults handle this
- Clean up redundant .optional() in schema definitions with .default()
- Add comprehensive CRLF tests for Markdown and Plain text formats

These changes improve cross-platform compatibility and input validation.
@yamadashy
Copy link
Owner Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for multiple output formats (XML, Markdown, JSON, Plain text) for the MCP tools, which is a great enhancement for flexibility. The changes are well-structured, with new parameters added to the packing tools and corresponding parsing logic in the attachPackedOutputTool. The implementation includes format detection, dedicated parsing functions for each style, and updated tests to ensure correctness. I've identified a couple of areas for improvement in attachPackedOutputTool.ts to enhance maintainability and robustness, but overall this is a solid contribution.

@yamadashy yamadashy merged commit 0d0290c into main Sep 14, 2025
48 checks passed
@yamadashy yamadashy deleted the feat/mcp-style branch September 14, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants