Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/mcp/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { coreTools } from "./core/index.js";
import { storageTools } from "./storage/index.js";
import { messagingTools } from "./messaging/index.js";
import { remoteConfigTools } from "./remoteconfig/index.js";

/** availableTools returns the list of MCP tools available given the server flags */
export function availableTools(fixedRoot: boolean, activeFeatures?: ServerFeature[]): ServerTool[] {
Expand All @@ -17,10 +18,10 @@
toolDefs.push(...directoryTools);
}
if (!activeFeatures?.length) {
activeFeatures = Object.keys(tools) as ServerFeature[];

Check warning on line 21 in src/mcp/tools/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

'tools' was used before it was defined
}
for (const key of activeFeatures) {
toolDefs.push(...tools[key]);

Check warning on line 24 in src/mcp/tools/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

'tools' was used before it was defined
}
return toolDefs;
}
Expand All @@ -31,6 +32,7 @@
dataconnect: addPrefixToToolName("dataconnect_", dataconnectTools),
storage: addPrefixToToolName("storage_", storageTools),
messaging: addPrefixToToolName("messaging_", messagingTools),
remoteconfig: addPrefixToToolName("remoteconfig_", remoteConfigTools),
};

function addPrefixToToolName(prefix: string, tools: ServerTool[]): ServerTool[] {
Expand Down
25 changes: 25 additions & 0 deletions src/mcp/tools/remoteconfig/get_template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { z } from "zod";
import { tool } from "../../tool.js";
import { toContent } from "../../util.js";
import { getTemplate } from "../../../remoteconfig/get.js";

export const get_rc_template = tool(
{
name: "get_template",
description: "Retrieves a remote config template for the project",
inputSchema: z.object({
versionNumber: z.string().optional(),
}),
annotations: {
title: "Get remote config template",
readOnlyHint: true,
},
_meta: {
requiresAuth: true,
requiresProject: true,
},
},
async ({ versionNumber }, { projectId }) => {
return toContent(await getTemplate(projectId!, versionNumber));

Check warning on line 23 in src/mcp/tools/remoteconfig/get_template.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Forbidden non-null assertion
},
);
4 changes: 4 additions & 0 deletions src/mcp/tools/remoteconfig/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { ServerTool } from "../../tool.js";
import { get_rc_template } from "./get_template.js";

export const remoteConfigTools: ServerTool[] = [get_rc_template];
1 change: 1 addition & 0 deletions src/mcp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export const SERVER_FEATURES = [
"dataconnect",
"auth",
"messaging",
"remoteconfig",
] as const;
export type ServerFeature = (typeof SERVER_FEATURES)[number];
2 changes: 2 additions & 0 deletions src/mcp/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
dataconnectOrigin,
firestoreOrigin,
messagingApiOrigin,
remoteConfigApiOrigin,
storageOrigin,
} from "../api";
import { check } from "../ensureApiEnabled";

export function toContent(data: any, options?: { format: "json" | "yaml" }): CallToolResult {

Check warning on line 16 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type

Check warning on line 16 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
if (typeof data === "string") return { content: [{ type: "text", text: data }] };

let text: string = "";

Check warning on line 19 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Type string trivially inferred from a string literal, remove type annotation
const format = options?.format || "yaml"; // use YAML because it's a little more prose-like for the LLM to parse
switch (format) {
case "json":
Expand All @@ -30,7 +31,7 @@
};
}

export function mcpError(message: Error | string | unknown, code?: string): CallToolResult {

Check warning on line 34 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
let errorMessage = "unknown error";
if (message instanceof Error) {
errorMessage = message.message;
Expand All @@ -44,7 +45,7 @@
};
}

export function commandExistsSync(command: string): boolean {

Check warning on line 48 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing JSDoc comment
try {
const isWindows = platform() === "win32";
// For Windows, `where` is more appropriate. It also often outputs the path.
Expand All @@ -69,6 +70,7 @@
dataconnect: dataconnectOrigin(),
auth: authManagementOrigin(),
messaging: messagingApiOrigin(),
remoteconfig: remoteConfigApiOrigin(),
};
/**
* Detects whether an MCP feature is active in the current project root. Relies first on
Expand All @@ -77,10 +79,10 @@
export async function checkFeatureActive(
feature: ServerFeature,
projectId?: string,
options?: any,

Check warning on line 82 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unexpected any. Specify a different type
): Promise<boolean> {
// if the feature is configured in firebase.json, it's active
if (feature in (options?.config?.data || {})) return true;

Check warning on line 85 in src/mcp/util.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .config on an `any` value
// if the feature's api is active in the project, it's active
try {
if (projectId) return await check(projectId, SERVER_FEATURE_APIS[feature], "", true);
Expand Down
Loading