-
Notifications
You must be signed in to change notification settings - Fork 1k
[MCP] implement {get,set}_data and {validate,get}_rules for RTDB MCP #8854
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
base: master
Are you sure you want to change the base?
Conversation
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.
Summary of Changes
Hello @antholeole, 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 introduces a comprehensive set of new tools within the Multi-Cloud Platform (MCP) specifically designed for interacting with Firebase Realtime Database (RTDB). The changes enable users to programmatically perform common RTDB operations such as reading and writing data, as well as retrieving and validating security rules, thereby enhancing automation and management capabilities for RTDB instances through the MCP.
Highlights
- New Realtime Database (RTDB) Tools: Four new tools have been implemented for Realtime Database:
get_data
,set_data
,get_rules
, andvalidate_rules
. These tools expand the MCP's capabilities for RTDB management. - Data Management:
get_data
allows fetching data from a specified RTDB path, whileset_data
enables writing JSON data to a given path. Both support custom database URLs and emulators. - Security Rules Management:
get_rules
provides functionality to retrieve the security rules of an RTDB instance, andvalidate_rules
allows for dry-run validation of RTDB security rules without applying them. - Code Refactoring and Integration: The core logic for updating RTDB rules has been refactored into a reusable
updateRulesWithClient
function. The MCP framework has been extended to include 'database' as a new server feature, integrating these new RTDB tools.
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 is currently in preview and 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 to provide feedback.
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
-
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. ↩
51c66d1
to
bff5222
Compare
/gemini review |
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.
Code Review
This pull request introduces new MCP tools for Firebase Realtime Database, allowing users to get/set data and get/validate rules. The implementation includes adding the tool definitions, integrating them into the MCP framework, and refactoring some existing RTDB code. My review identified a critical bug in the refactored rtdb.ts
file that would break existing functionality. Additionally, all new RTDB tools share a high-severity issue with hardcoded database URLs, limiting them to a single region. I've also pointed out a couple of medium-severity maintainability issues that should be addressed. Resolving these issues is essential for the correctness and stability of these new features.
@@ -32,6 +28,20 @@ export async function updateRules( | |||
"", | |||
); | |||
const client = new Client({ urlPrefix: origin }); | |||
|
|||
return updateRulesWithClient(client, options); |
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.
The call to updateRulesWithClient
is missing the src
argument. The function is being called with (client, options)
, but its signature is (client, src, options)
. This will result in the options
object being passed as the rules content, which is incorrect and will break the rule update functionality.
return updateRulesWithClient(client, options); | |
return updateRulesWithClient(client, src, options); |
const dbUrl = new url.URL( | ||
databaseUrl | ||
? `${databaseUrl}/${path}.json` | ||
: `https://${projectId}-default-rtdb.us-central1.firebasedatabase.app/${path}.json`, | ||
); |
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.
const dbUrl = | ||
databaseUrl ?? `https://${projectId}-default-rtdb.us-central1.firebasedatabase.app`; |
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.
const dbUrl = new url.URL( | ||
databaseUrl | ||
? `${databaseUrl}/${path}.json` | ||
: `https://${projectId}-default-rtdb.us-central1.firebasedatabase.app/${path}.json`, | ||
); |
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.
const dbUrl = | ||
databaseUrl ?? `https://${projectId}-default-rtdb.us-central1.firebasedatabase.app`; |
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.
/* | ||
* Wraps a throwing function with a safe conversion to mcpError. | ||
*/ |
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.
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.
Code Review
This pull request implements several Realtime Database tools for the MCP server, including getting/setting data and getting/validating rules. The changes are well-structured, but I've found a few issues. There's a critical bug in the refactored updateRules
function where arguments are passed incorrectly. I've also identified some minor issues like malformed error messages, a stray comment, and a duplicated file that should be removed. Please see my detailed comments for suggestions.
@@ -32,6 +28,20 @@ export async function updateRules( | |||
"", | |||
); | |||
const client = new Client({ urlPrefix: origin }); | |||
|
|||
return updateRulesWithClient(client, options); |
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.
The call to updateRulesWithClient
is missing the src
argument and is passing options
in its place. This will cause the function to fail at runtime.
The signature for updateRulesWithClient
is (client: Client, src: unknown, options: { dryRun?: boolean } = {})
.
return updateRulesWithClient(client, options); | |
return updateRulesWithClient(client, src, options); |
import { z } from "zod"; | ||
import { Client } from "../../../apiv2"; | ||
import { tool } from "../../tool"; | ||
import { mcpError, toContent } from "../../util"; | ||
import { updateRulesWithClient } from "../../../rtdb"; | ||
import { getErrMsg } from "../../../error"; | ||
|
||
export const validate_rules = tool( | ||
{ | ||
name: "validate_rules", | ||
description: "Validates an RTDB database's rules", | ||
inputSchema: z.object({ | ||
databaseUrl: z | ||
.string() | ||
.optional() | ||
.describe( | ||
"connect to the database at url. If omitted, use default database instance <project>-default-rtdb.firebaseio.com. Can point to emulator URL (e.g. localhost:6000/<instance>)", | ||
), | ||
rules: z | ||
.string() | ||
.describe('The rules object, as a string (ex: {".read": false, ".write": false})'), | ||
}), | ||
annotations: { | ||
title: "Validate Realtime Database rules", | ||
idempotentHint: true, | ||
}, | ||
|
||
_meta: { | ||
requiresAuth: true, | ||
requiresProject: false, | ||
}, | ||
}, | ||
async ({ databaseUrl, rules }, { projectId, host }) => { | ||
const dbUrl = | ||
databaseUrl ?? `https://${projectId}-default-rtdb.us-central1.firebasedatabase.app`; | ||
|
||
const client = new Client({ urlPrefix: dbUrl }); | ||
|
||
try { | ||
await updateRulesWithClient(client, rules, { dryRun: true }); | ||
} catch (e: unknown) { | ||
host.logger.debug(`failed to update rules at url ${dbUrl}`); | ||
return mcpError(getErrMsg(e)); | ||
} | ||
|
||
return toContent("the inputted rules are valid!"); | ||
}, | ||
); |
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.
}, | ||
async ({ path, databaseUrl }, { projectId, host }) => { | ||
if (!path.startsWith("/")) { | ||
return mcpError(`paths must start with '/' (you passed ''${path}')`); |
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.
The error message for an invalid path has unbalanced single quotes. This will result in a confusing message for the user, for example: paths must start with '/' (you passed ''/mypath')
.
return mcpError(`paths must start with '/' (you passed ''${path}')`); | |
return mcpError(`paths must start with '/' (you passed '${path}')`); |
return mcpError(`Failed to fetch current rules. Code: ${response.status}`); | ||
} | ||
|
||
const rules = await response.response.text(); |
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.
}, | ||
async ({ path, databaseUrl, data }, { projectId, host }) => { | ||
if (!path.startsWith("/")) { | ||
return mcpError(`paths must start with '/' (you passed ''${path}')`); |
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.
The error message for an invalid path has unbalanced single quotes. This will result in a confusing message for the user, for example: paths must start with '/' (you passed ''/mypath')
.
return mcpError(`paths must start with '/' (you passed ''${path}')`); | |
return mcpError(`paths must start with '/' (you passed '${path}')`); |
/* | ||
* Wraps a throwing function with a safe conversion to mcpError. | ||
*/ |
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.
No description provided.