Skip to content

CLI: Add subcommand cratedb-mcp serve using Click#22

Merged
amotl merged 1 commit intomainfrom
cli
May 19, 2025
Merged

CLI: Add subcommand cratedb-mcp serve using Click#22
amotl merged 1 commit intomainfrom
cli

Conversation

@amotl
Copy link
Member

@amotl amotl commented May 17, 2025

About

Explicit is better than implicit: Following common sense, and excellent blueprints of others, this patch adds command-line parsing using a standard interface, to improve discoverability of subcommands and options for both humans and machines.

Details

  • cratedb-mcp serve now provides dedicated options --transport and --port.
  • The MCP server now also supports the new streamable-http transport.

    The Streamable HTTP transport from protocol version 2025-03-26 is the recommended transport mechanism for web-based MCP applications, replacing the HTTP+SSE transport from protocol version 2024-11-05.

@coderabbitai
Copy link

coderabbitai bot commented May 17, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update refactors the CLI for cratedb-mcp to use the Click library, introducing a new serve subcommand with explicit --transport and --port options, and adds support for a new transport type. Documentation and tests are updated to reflect the new command structure and usage patterns.

Changes

File(s) Change Summary
CHANGES.md, README.md Updated changelog and usage documentation to describe the new CLI structure, subcommands, transport options, and environment variable handling. All usage examples now use the new serve subcommand.
cratedb_mcp/cli.py Replaced the manual CLI with a Click-based command group, added serve subcommand with options for transport and port, and extended transport support to include streamable-http. Removed the old main() function.
cratedb_mcp/main.py Changed FastMCP app instantiation to use a dynamic application name from __appname__ instead of a hardcoded string.
pyproject.toml Added click and pueblo as dependencies, and updated the CLI entry point from main to cli to match the new Click-based structure.
tests/test_cli.py Refactored tests to use Click's CliRunner for invoking CLI commands and validating output, replacing manual sys.argv and environment variable manipulation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI (Click)
    participant FastMCP

    User->>CLI (Click): cratedb-mcp serve --transport=... --port=...
    CLI (Click)->>CLI (Click): Parse options (transport, port)
    CLI (Click)->>FastMCP: Run server with selected transport and port
    FastMCP-->>CLI (Click): Server starts
    CLI (Click)-->>User: Outputs logs and status
Loading

Suggested reviewers

  • bmunkholm
  • kneth

Poem

In the meadow where commands now Click,
Rabbits hop and options pick.
"Serve" we chant, with ports in hand,
New transports wander o’er the land.
Docs refreshed, the tests all run,
Our CLI journey’s just begun!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d306a7 and 0cca69e.

📒 Files selected for processing (6)
  • CHANGES.md (1 hunks)
  • README.md (3 hunks)
  • cratedb_mcp/__main__.py (2 hunks)
  • cratedb_mcp/cli.py (1 hunks)
  • pyproject.toml (2 hunks)
  • tests/test_cli.py (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch cli
  • Post Copyable Unit Tests in Comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 0

🧹 Nitpick comments (3)
CHANGES.md (1)

6-7: Minor: Remove redundancy in "CLI interface"

"CLI" already stands for "Command Line Interface," so "CLI interface" is redundant. Consider rewording to simply "CLI" or "Command Line Interface."

- CLI: Added solid CLI interface using Click, `cratedb-mcp serve`, with
+ CLI: Added solid CLI using Click, `cratedb-mcp serve`, with
🧰 Tools
🪛 LanguageTool

[style] ~6-~6: This phrase is redundant (‘I’ stands for ‘interface’). Use simply “CLI”.
Context: ...n naming conventions - CLI: Added solid CLI interface using Click, cratedb-mcp serve, with ...

(ACRONYM_TAUTOLOGY)

cratedb_mcp/cli.py (1)

24-25: Type handling for transport choices could be improved.

While using Literal for typing is good, accessing __args__ with a type ignore comment is a bit hacky.

Consider defining the choices directly and using them to build the Literal type:

-transport_types = t.Literal["stdio", "sse", "streamable-http"]
-transport_choices = transport_types.__args__  # type: ignore
+transport_choices = ("stdio", "sse", "streamable-http")
+transport_types = t.Literal[transport_choices[0], transport_choices[1], transport_choices[2]]

Or even more maintainable:

transport_choices = ("stdio", "sse", "streamable-http")
TransportType = t.Literal["stdio", "sse", "streamable-http"]
tests/test_cli.py (1)

1-63: Consider adding more test cases for complete coverage.

While the current tests cover the basic functionality, consider adding tests for:

  • Using the --port option with different values
  • Explicitly setting the --transport option (rather than via environment variable)
  • Testing all valid transport types including the new "streamable-http" option

This would provide more comprehensive test coverage for the CLI interface.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64b0881 and 20914de.

📒 Files selected for processing (6)
  • CHANGES.md (1 hunks)
  • README.md (3 hunks)
  • cratedb_mcp/__main__.py (2 hunks)
  • cratedb_mcp/cli.py (1 hunks)
  • pyproject.toml (2 hunks)
  • tests/test_cli.py (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
CHANGES.md (1)
Learnt from: amotl
PR: crate/cratedb-mcp#17
File: CHANGES.md:5-5
Timestamp: 2025-05-16T13:35:04.487Z
Learning: For the cratedb-mcp repository, version numbers and release dates in CHANGES.md are updated by a dedicated "Release vX.Y.Z" commit as part of the release process, not during documentation preparation PRs.
🧬 Code Graph Analysis (1)
tests/test_cli.py (1)
cratedb_mcp/cli.py (1)
  • cli (15-21)
🪛 LanguageTool
CHANGES.md

[style] ~6-~6: This phrase is redundant (‘I’ stands for ‘interface’). Use simply “CLI”.
Context: ...n naming conventions - CLI: Added solid CLI interface using Click, cratedb-mcp serve, with ...

(ACRONYM_TAUTOLOGY)

🔇 Additional comments (15)
cratedb_mcp/__main__.py (1)

4-4: LGTM: Good refactoring to use a centralized application name

Importing __appname__ from the module rather than hardcoding the application name is a good practice that follows the DRY principle.

Also applies to: 13-13

pyproject.toml (2)

75-75: LGTM: Dependencies align with new CLI implementation

The addition of Click (with version constraint) and Pueblo dependencies properly supports the new CLI implementation.

Also applies to: 79-79


95-95: LGTM: Entry point correctly updated for new CLI structure

The CLI entry point has been correctly updated to use the new Click-based command group cli instead of the previous main function.

README.md (4)

115-115: LGTM: Updated usage examples for the new CLI structure

The command examples have been properly updated to use the new serve subcommand with the --transport option. The additional example for the new streamable-http transport type is helpful for users.

Also applies to: 119-119, 121-124


125-126: LGTM: Documentation on alternative environment variable usage

Good addition of information about the alternative approach using the environment variable instead of the command-line option.


137-137: LGTM: Updated Claude configuration example

The Anthropic Claude configuration example has been correctly updated to include the new serve subcommand.


160-160: LGTM: Updated mcptools examples

All mcptools command examples have been correctly updated to include the new serve subcommand.

Also applies to: 163-163, 166-166, 171-171, 176-176

cratedb_mcp/cli.py (4)

4-6: Well-chosen dependency imports for the CLI refactoring.

The addition of click for CLI functionality and pueblo.util.cli.boot_click for initialization demonstrates a good approach to structuring the command-line interface.


12-22: Good implementation of the main CLI command group.

The implementation follows Click's best practices with:

  • Clear group structure with @click.group()
  • Version option support with @click.version_option()
  • Well-formatted docstring with usage information
  • Proper initialization with boot_click

This creates a solid foundation for extending with subcommands.


28-42: Well-structured command options with appropriate defaults and environment variable support.

The implementation properly:

  • Defines transport and port options with clear help text
  • Supports configuration via environment variables
  • Provides sensible defaults
  • Includes help text that explains what each option does

This follows the principle "Explicit is better than implicit" as mentioned in the PR objectives.


43-50: Good implementation of the serve command.

The command correctly:

  • Logs the transport choice for visibility
  • Sets the MCP server port
  • Executes the server with the specified transport

The type casting ensures type safety while allowing Click to handle string inputs from the command line.

tests/test_cli.py (4)

1-5: Good transition to Click testing utilities.

Replacing manual sys.argv manipulation with the CliRunner and updating imports to use the new CLI entry point is the correct approach when testing Click-based command-line interfaces.


8-23: Well-structured version command test.

The test correctly:

  • Uses CliRunner to invoke the CLI with the version option
  • Verifies the exit code is successful
  • Checks that the version number is present in the output

This is a good pattern for testing CLI commands.


26-43: Good test for the default serve command.

The test properly:

  • Mocks FastMCP.run to prevent the server from actually running
  • Uses CliRunner to invoke the CLI with the serve command
  • Verifies that the run method was called

This ensures that the CLI correctly passes control to the actual server implementation.


46-62: Proper test for transport validation.

The test effectively:

  • Sets an invalid transport value through environment variables
  • Verifies that the CLI exits with an error code
  • Checks that an appropriate error message is displayed

This validates that the CLI correctly enforces the allowed transport types.

Copy link

@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: 0

🧹 Nitpick comments (2)
cratedb_mcp/cli.py (1)

24-25: Type definition looks correct but could be improved

The type definition for transport types is good, but accessing __args__ directly with a type ignore comment isn't ideal.

Consider using get_args from typing_extensions for more explicit type handling:

-transport_types = t.Literal["stdio", "sse", "streamable-http"]
-transport_choices = transport_types.__args__  # type: ignore
+from typing_extensions import get_args
+
+transport_types = t.Literal["stdio", "sse", "streamable-http"]
+transport_choices = get_args(transport_types)

This avoids the type ignore comment and will be more future-proof.

tests/test_cli.py (1)

1-145: Consider adding tests for edge cases

While the test coverage is good, consider adding tests for additional edge cases:

  1. Test with a valid but unusual port number (e.g., 65535)
  2. Test command help output (cratedb-mcp serve --help)
  3. Test with no arguments (cratedb-mcp without subcommands)

These additional tests would enhance robustness.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20914de and f8c4f49.

📒 Files selected for processing (6)
  • CHANGES.md (1 hunks)
  • README.md (3 hunks)
  • cratedb_mcp/__main__.py (2 hunks)
  • cratedb_mcp/cli.py (1 hunks)
  • pyproject.toml (2 hunks)
  • tests/test_cli.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • CHANGES.md
  • cratedb_mcp/main.py
  • pyproject.toml
  • README.md
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/test_cli.py (1)
cratedb_mcp/cli.py (1)
  • cli (15-21)
🔇 Additional comments (12)
cratedb_mcp/cli.py (4)

4-5: LGTM: Necessary imports for Click framework

The imports for Click and the boot_click utility are appropriate for setting up the CLI framework.


12-22: LGTM: Well-structured CLI entry point

The main CLI group is properly defined with version option and documentation. The use of boot_click for initialization is appropriate.


28-42: LGTM: Well-structured options for the serve command

The transport and port options are well-defined with appropriate defaults, environment variable mappings, and help messages.


43-51: Serve command implementation looks good

The serve command implementation correctly logs the transport type, sets the port, and runs the MCP server with the specified transport.

One minor observation: The type cast in line 50 is necessary because you're passing a string to a function that expects the Literal type. This is a common pattern when dealing with string inputs that need to be validated against Literal types.

tests/test_cli.py (8)

1-8: LGTM: Appropriate imports for testing

The necessary imports for the tests are in place, including mock, anyio, CliRunner, and the cli to be tested.


11-26: LGTM: Version test is well implemented

The test for the version option correctly invokes the CLI and verifies the output contains the version.


29-49: LGTM: Default serve command test is comprehensive

The test for the default serve command correctly mocks anyio.run, invokes the CLI, and verifies that the right function is called with the default port.


51-71: LGTM: Custom transport and port test is thorough

The test for custom transport and port options correctly verifies that the streamable-http transport is used and the port is set to 1234.


73-89: LGTM: Validation test for invalid transport option

The test correctly verifies that providing an invalid transport option results in an error message and non-zero exit code.


91-108: LGTM: Validation test for invalid transport environment variable

The test correctly verifies that setting an invalid transport via environment variable results in an error.


110-126: LGTM: Validation test for invalid port option

The test correctly verifies that providing an invalid port option results in an error message.


128-145: LGTM: Validation test for invalid port environment variable

The test correctly verifies that setting an invalid port via environment variable results in an error.

@amotl amotl marked this pull request as ready for review May 17, 2025 09:25
@amotl amotl changed the title CLI: Add solid CLI interface using Click, cratedb-mcp serve CLI: Add subcommand cratedb-mcp serve using Click May 17, 2025
Base automatically changed from cratedb-cluster-url to main May 19, 2025 22:58
... with dedicated options `--transport` and `--port`.
@amotl amotl merged commit 1e9d6a7 into main May 19, 2025
5 of 6 checks passed
@amotl amotl deleted the cli branch May 19, 2025 23:01
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