-
Notifications
You must be signed in to change notification settings - Fork 81
feat(mcp): introduce MCP server #1094
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis pull request introduces the Wren MCP Server with extensive documentation and new modules. It adds a README outlining setup instructions and environment variables, creates a set of Pydantic data models and utility functions, and implements various asynchronous API endpoints for interacting with the Wren Engine. Additionally, Docker Compose and Justfile configurations are provided for deployment, along with a JSON schema for manifest validation and project metadata in the pyproject.toml. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as AI Agent/Client
participant MCP as MCP Server
participant Wren as Wren Engine
Client->>MCP: Request operation (e.g., query, deploy, health_check)
MCP->>Wren: Forward request via asynchronous API call
Wren-->>MCP: Return response or error
MCP-->>Client: Send back formatted result
Suggested labels
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
🧹 Nitpick comments (22)
mcp-server/etc/config.properties (1)
1-2
: Configuration properties look good but could benefit from more documentation.The basic configuration settings for environment and HTTP port are correctly defined. Consider adding comments to explain the purpose of these properties and other valid options (e.g., what environments are supported besides "test").
+# Configuration file for MCP server +# Possible environments: test, dev, prod (example) node.environment=test +# HTTP server port configuration http-server.http.port=8080mcp-server/app/utils.py (4)
5-6
: Consider improving type hint for dictionary value type.The type hint
any
should be capitalized asAny
and imported from the typing module. This ensures proper type checking.import base64 import orjson +from typing import Any -def dict_to_base64_string(data: dict[str, any]) -> str: +def dict_to_base64_string(data: dict[str, Any]) -> str: return base64.b64encode(orjson.dumps(data)).decode("utf-8")
9-10
: Function looks good, but add input validation.The function correctly encodes a string to base64, but it would be helpful to add validation to handle edge cases like None or empty strings.
def json_to_base64_string(data: str) -> str: + if data is None: + raise ValueError("Input data cannot be None") return base64.b64encode(data.encode("utf-8")).decode("utf-8")
10-11
: Add newline at end of file.The file is missing a newline at the end, which is a common convention for source files.
def json_to_base64_string(data: str) -> str: return base64.b64encode(data.encode("utf-8")).decode("utf-8") - +
1-11
: Consider adding docstrings and examples.These utility functions would benefit from docstrings explaining their purpose and providing examples of their usage.
import base64 import orjson +from typing import Any def dict_to_base64_string(data: dict[str, Any]) -> str: + """ + Convert a dictionary to a base64-encoded string. + + Args: + data: Dictionary to encode + + Returns: + Base64-encoded string representation of the dictionary + + Example: + >>> dict_to_base64_string({"key": "value"}) + 'eyJrZXkiOiJ2YWx1ZSJ9' + """ return base64.b64encode(orjson.dumps(data)).decode("utf-8") def json_to_base64_string(data: str) -> str: + """ + Convert a JSON string to a base64-encoded string. + + Args: + data: JSON string to encode + + Returns: + Base64-encoded string representation of the JSON string + + Example: + >>> json_to_base64_string('{"key": "value"}') + 'eyJrZXkiOiAidmFsdWUifQ==' + """ return base64.b64encode(data.encode("utf-8")).decode("utf-8")mcp-server/justfile (2)
9-12
: Install-core task has commented out code and relies on uv.The task has commented out code that should either be removed or uncommented. Additionally, the task relies on the
uv
package manager without checking if it's installed.install-core: - # just build-core + # First build the core package + just build-core # Using pip install to avoid adding wheel to pyproject.toml - uv pip install --force-reinstall {{ core-wheel-path }} + command -v uv >/dev/null 2>&1 || { echo "uv is not installed. Installing packages with pip instead."; pip install --force-reinstall {{ core-wheel-path }}; exit 0; } + uv pip install --force-reinstall {{ core-wheel-path }}
12-13
: Add newline at end of file.The file is missing a newline at the end, which is a common convention for source files.
# Using pip install to avoid adding wheel to pyproject.toml uv pip install --force-reinstall {{ core-wheel-path }} - +mcp-server/docker/compose.yaml (2)
23-24
: Fix trailing spaces and add newline at end of file.Line 23 has trailing spaces and the file is missing a newline at the end, as flagged by the static analysis tool.
environment: MAX_HEAP_SIZE: 819m - MIN_HEAP_SIZE: 819m - + MIN_HEAP_SIZE: 819m +🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
[error] 24-24: trailing spaces
(trailing-spaces)
1-24
: Consider adding service dependencies and healthchecks.The compose file would benefit from explicit dependencies between services and healthchecks to ensure proper startup order and reliability.
services: ibis-server: image: ghcr.io/canner/wren-engine-ibis:latest ports: - "8000:8000" environment: WREN_ENGINE_ENDPOINT: http://java-engine:8080 volumes: - ./../etc:/usr/src/app/etc + depends_on: + java-engine: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 10s java-engine: image: ghcr.io/canner/wren-engine:latest ports: - "8080:8080" volumes: - ./../etc:/usr/src/app/etc deploy: resources: limits: cpus: '1' memory: 1G environment: MAX_HEAP_SIZE: 819m MIN_HEAP_SIZE: 819m + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/v1/info"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 30s🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
[error] 24-24: trailing spaces
(trailing-spaces)
mcp-server/pyproject.toml (1)
1-14
: Update the placeholder project description.The project has a placeholder description "Add your description here". Consider updating it with a meaningful description that explains the purpose of the MCP server and how it interacts with the Wren Engine.
-description = "Add your description here" +description = "Model Context Protocol (MCP) server for the Wren Engine that provides tools for AI agent integration"mcp-server/README.md (1)
65-69
: Fix formatting issues in heading and operating system name.Two minor formatting corrections needed:
- Remove the trailing colon in the heading
- Correct "MacOS" to "macOS" (Apple's official spelling)
-#### Notes: +#### Notes - You **may need to provide the full path** to the `uv` executable in the `"command"` field. You can find it using: - - **MacOS/Linux**: `which uv` + - **macOS/Linux**: `which uv` - **Windows**: `where uv`🧰 Tools
🪛 LanguageTool
[grammar] ~67-~67: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv- **Windows**:
w...(MAC_OS)
🪛 markdownlint-cli2 (0.17.2)
65-65: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
mcp-server/app/dto.py (3)
8-11
: Consider using consistent typing patterns for optional fields.For optional fields, it's better to explicitly use
Optional[type]
or thetype | None
union syntax (Python 3.10+) for clarity rather than setting default values to None. This enhances type checking and code clarity.- expression: str = None + expression: str | None = None - isCalculated: bool = False + isCalculated: bool = False - relationship: str = None + relationship: str | None = None - description: str = None + description: str | None = None
28-32
: Use consistent naming convention for fields.The
Relationship
class uses snake_case forjoin_type
andjoin_condition
while other classes use camelCase (likeisCalculated
andtableReference
). Consider using a consistent naming convention throughout all models.name: str models: list[str] - join_type: str - join_condition: str + joinType: str + joinCondition: str
52-52
: Add Optional type annotation for optional list field.Similar to other fields, it's better to explicitly mark optional fields with the appropriate type annotation.
- column_names: list[str] = None + column_names: list[str] | None = Nonemcp-server/mdl.schema.json (1)
117-121
: Align field names between JSON schema and Pydantic models.The schema uses
condition
while the Pydantic model in dto.py usesjoin_condition
. Similarly, the schema uses camelCase for properties but the Pydantic model uses snake_case for some fields. Consider aligning the naming conventions for consistency.# In dto.py - join_type: str - join_condition: str + joinType: str + joinCondition: str # OR in mdl.schema.json - "joinType": { + "join_type": { ... - "condition": { + "join_condition": {mcp-server/app/wren.py (7)
1-5
: Prefer a single JSON parsing library for consistency
Currently, bothorjson
and the built-injson
library are imported. Whileorjson
can offer performance benefits, mixing two libraries for similar purposes can lead to confusion and potential inconsistencies. Consider standardizing onorjson
for all JSON operations, given its performance advantage.
22-30
: Avoid raw print statements in production code
The file useslogging
module) for better log levels, formatting, and discoverability.
39-56
: Revisit exception handling strategy
When the POST request fails, the function returns the exception objecte
directly (line 55). This can expose internal error details. You might consider logging the exception and returning a sanitized error message or re-raising a custom exception to avoid leaking implementation details.
95-104
: Validate MDL schema before deployment
A TODO comment suggests schema validation. If the schema is critical, consider adding robust validation using something like JSON Schema validation before storing the base64 data. This helps catch errors early and prevent invalid schema states in production.
195-242
: Consider returning partial results instead of short-circuiting
In the loop, if a table or column is not found (lines 215–219, 233), the function returns immediately with an error message. If multipleTableColumns
are provided, this prevents further valid items from being processed. Consider aggregating all errors or partial successes.
297-310
: Remove unused exception variable
According to the static analysis tool, variablee
(line 303) is assigned but never used. You can either log the exception or remove the alias to avoid confusion.Apply this diff to remove the unused variable:
- except Exception as e: + except Exception: return "Wren Engine is not healthy"🧰 Tools
🪛 Ruff (0.8.2)
308-308: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
312-315
: Enhance server startup for broader usage
Currently, the script directly runsmcp.run(transport="stdio")
in the__main__
block. If you anticipate different transports (e.g., HTTP, gRPC), consider parameterizing or introducing a CLI argument to set the transport type for greater flexibility.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
mcp-server/uv.lock
is excluded by!**/*.lock
📒 Files selected for processing (9)
mcp-server/README.md
(1 hunks)mcp-server/app/dto.py
(1 hunks)mcp-server/app/utils.py
(1 hunks)mcp-server/app/wren.py
(1 hunks)mcp-server/docker/compose.yaml
(1 hunks)mcp-server/etc/config.properties
(1 hunks)mcp-server/justfile
(1 hunks)mcp-server/mdl.schema.json
(1 hunks)mcp-server/pyproject.toml
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
mcp-server/README.md
[grammar] ~67-~67: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv - **Windows**:
w...
(MAC_OS)
🪛 markdownlint-cli2 (0.17.2)
mcp-server/README.md
65-65: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🪛 YAMLlint (1.35.1)
mcp-server/docker/compose.yaml
[error] 24-24: no new line character at the end of file
(new-line-at-end-of-file)
[error] 24-24: trailing spaces
(trailing-spaces)
🪛 Ruff (0.8.2)
mcp-server/app/wren.py
308-308: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: ci
🔇 Additional comments (4)
mcp-server/app/utils.py (1)
1-3
: Import statements look good.The necessary imports for base64 encoding and JSON serialization are correctly included.
mcp-server/justfile (2)
1-2
: Default task is correctly implemented.The default task properly displays all available tasks in an unsorted manner.
7-7
: Core wheel path variable is correctly defined.The variable is properly defined to locate the wheel file for installation.
mcp-server/docker/compose.yaml (1)
1-9
: IBIS server configuration looks good.The ibis-server service is well-configured with appropriate image, port mapping, environment variables, and volume mounts.
There was a problem hiding this 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 (5)
mcp-server/README.md (5)
29-29
: Fix Typo in Heading.
The heading "### 1. Set the Python Envrionment" contains a typo. Please change "Envrionment" to "Environment".
32-41
: Specify Language for Code Block.
The fenced code block starting on line 32 does not specify a language. Adding a language identifier (e.g., ```bash) will improve readability and syntax highlighting.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
32-32: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
42-42
: Improve Command Description.
The sentence "Then, you can useCtrl + C
terminate the process." could be rephrased for clarity. Consider updating it to "Then, pressCtrl + C
to terminate the process."🧰 Tools
🪛 LanguageTool
[uncategorized] ~42-~42: Possible missing preposition found.
Context: ...re loaded. Then, you can useCtrl + C
terminate the process. ### 2. Start Wren Engine ...(AI_HYDRA_LEO_MISSING_TO)
80-80
: Remove Trailing Punctuation in Heading.
The heading "#### Notes:" on line 80 ends with a colon. For consistency with common Markdown style guidelines, please remove the trailing punctuation (change it to "#### Notes").🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
80-80: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
82-82
: Correct Operating System Naming.
On line 82, please change "MacOS/Linux:which uv
" to "macOS/Linux:which uv
" to reflect the standard styling of Apple's operating system name.🧰 Tools
🪛 LanguageTool
[grammar] ~82-~82: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv- **Windows**:
w...(MAC_OS)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
mcp-server/README.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
mcp-server/README.md
[uncategorized] ~42-~42: Possible missing preposition found.
Context: ...re loaded. Then, you can use Ctrl + C
terminate the process. ### 2. Start Wren Engine ...
(AI_HYDRA_LEO_MISSING_TO)
[grammar] ~82-~82: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv - **Windows**:
w...
(MAC_OS)
🪛 markdownlint-cli2 (0.17.2)
mcp-server/README.md
32-32: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
80-80: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @goldmedal. just some knitpick
| Variable | Description | | ||
|----------|------------| | ||
| `WREN_URL` | The URL of the **Wren Ibis server**. | | ||
| `CONNECTION_INFO_FILE` | The path to the **required connection info file**. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should specify that the connection information is stored in a JSON file and provide an example, as shown below
{
"connectionInfo": {
"host": "docker.for.mac.localhost",
"port": "5432",
"user": "test",
"password": "test",
"database": "test"
}
}
|----------|------------| | ||
| `WREN_URL` | The URL of the **Wren Ibis server**. | | ||
| `CONNECTION_INFO_FILE` | The path to the **required connection info file**. | | ||
| `MDL_PATH` | The path to the **MDL file**. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, we should note that the mdl is not the same as a standard engine mdl. it need datasource
field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pointing this out. I added a section to mention it. By the way, dataSource
is actually the standard MDL field.
There was a problem hiding this 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 (5)
mcp-server/README.md (5)
21-23
: Spelling Correction in Connection Info
The description contains a typo—please change “requried” to required to improve clarity.
34-36
: Heading Spelling and Formatting
The heading currently reads:-### The `dataSource` field is requried. +### The `dataSource` Field is RequiredPlease fix the typo (“requried” → “required”) and remove the trailing punctuation for consistency.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
34-34: Trailing punctuation in heading
Punctuation: '.'(MD026, no-trailing-punctuation)
46-48
: Python Environment Setup Instructions
The heading “### 1. Set the Python Envrionment” has a spelling error. Consider updating it as follows:-### 1. Set the Python Envrionment +### 1. Set the Python EnvironmentAdditionally, verify that the instructions for creating and activating the virtual environment maintain consistency.
49-58
: Fenced Code Block Language Specification
The fenced code block outlining theuv
command does not specify a language. Adding a language (e.g.,sh
) will enable proper syntax highlighting. For example:-``` +```sh > uv venv Using CPython 3.11.11 Creating virtual environment at: .venv Activate with: source .venv/bin/activate > source .venv/bin/activate > uv run app/wren.py Loaded MDL etc/mdl.json Loaded connection info etc/pg_conneciton.json -``` +```🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
49-49: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
97-103
: Formatting Adjustments in Notes Section
Please update the “Notes” heading by removing its trailing punctuation and adjust the OS naming for clarity. For example:-#### Notes: +#### NotesAnd update:
- - **MacOS/Linux**: `which uv` + - **macOS/Linux**: `which uv`This aligns with best practices and static analysis recommendations.
🧰 Tools
🪛 LanguageTool
[grammar] ~99-~99: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv- **Windows**:
w...(MAC_OS)
🪛 markdownlint-cli2 (0.17.2)
97-97: Trailing punctuation in heading
Punctuation: ':'(MD026, no-trailing-punctuation)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
mcp-server/README.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
mcp-server/README.md
[grammar] ~99-~99: The operating system from Apple is written “macOS”.
Context: ...d"field. You can find it using: - **MacOS/Linux**:
which uv - **Windows**:
w...
(MAC_OS)
🪛 markdownlint-cli2 (0.17.2)
mcp-server/README.md
34-34: Trailing punctuation in heading
Punctuation: '.'
(MD026, no-trailing-punctuation)
49-49: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
97-97: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: ci
🔇 Additional comments (13)
mcp-server/README.md (13)
1-4
: Introduction Clarity
The introduction provides a concise and clear overview of the Wren MCP Server and its purpose.
5-10
: Requirements Section Review
The dependency on the uv package is clearly stated with an appropriate link, ensuring users know what is needed.
11-20
: Environment Variables Section
The table layout for the required environment variables is well structured and easy to follow.
24-32
: JSON Example Clarity
The JSON snippet is well-formatted and effectively demonstrates the expected structure for connection info.
34-37
: Clarification on MDL Requirements
As noted in previous reviews, it would be beneficial to explicitly highlight that the MDL here differs from a standard engine MDL by requiring thedataSource
field. This additional context can help avoid confusion.🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
34-34: Trailing punctuation in heading
Punctuation: '.'(MD026, no-trailing-punctuation)
38-42
: .env File Support Section
This section clearly indicates that environment variables can be managed via a.env
file, which is helpful for users.
61-69
: Starting Wren Engine and Ibis Server
The Docker-based instructions for starting the Wren Engine and Ibis Server are straightforward and clear.
71-74
: Environment Variables Configuration
The guidance on setting environment variables is concise and instructive.
75-95
: MCP Server Configuration Instructions
The provided JSON configuration and associated explanations are detailed and clear. Reminder: ensure users understand to replace placeholder paths (e.g.,/ABSOLUTE/PATH/TO/PARENT/FOLDER/...
) with their actual file system paths.
104-110
: AI Agent Compatibility Section
The list of compatible AI agents is well presented with clear descriptions and helpful links.
111-113
: Wren Engine Connection Check
The step advising users to check the Wren Engine connection is succinct and informative.
115-118
: Conversation Initiation Guidance
Instructions for starting the conversation with the AI agent are clear and straightforward.
121-125
: Additional Resources
The final section effectively supplies further documentation links and resources that will be valuable to users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @goldmedal
Introduce the MCP server for Wren Engine.
See detaisl in
README.md
file.Summary by CodeRabbit
Documentation
New Features
Chores