Skip to content

Commit 8ea6098

Browse files
committed
feat(@angular/cli): add --read-only option to mcp command
This change introduces a `--read-only` flag to the `ng mcp` command. When this flag is present, the MCP server will only register tools that are explicitly marked as read-only. This provides a way for host applications to connect to the Angular CLI MCP server with a restricted set of capabilities, ensuring that no tools capable of modifying the user's workspace are exposed.
1 parent 7ade8fb commit 8ea6098

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

packages/angular/cli/src/commands/mcp/cli.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,22 @@ export default class McpCommandModule extends CommandModule implements CommandMo
3333
longDescriptionPath = undefined;
3434

3535
builder(localYargs: Argv): Argv {
36-
return localYargs;
36+
return localYargs.option('read-only', {
37+
type: 'boolean',
38+
default: false,
39+
describe: 'Only register read-only tools.',
40+
});
3741
}
3842

39-
async run(): Promise<void> {
43+
async run(options: { readOnly: boolean }): Promise<void> {
4044
if (isTTY()) {
4145
this.context.logger.info(INTERACTIVE_MESSAGE);
4246

4347
return;
4448
}
4549

4650
const server = await createMcpServer(
47-
{ workspace: this.context.workspace },
51+
{ workspace: this.context.workspace, readOnly: options.readOnly },
4852
this.context.logger,
4953
);
5054
const transport = new StdioServerTransport();

packages/angular/cli/src/commands/mcp/mcp-server.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { registerTools } from './tools/tool-registry';
2121
export async function createMcpServer(
2222
context: {
2323
workspace?: AngularWorkspace;
24+
readOnly?: boolean;
2425
},
2526
logger: { warn(text: string): void },
2627
): Promise<McpServer> {
@@ -63,14 +64,18 @@ export async function createMcpServer(
6364
},
6465
);
6566

66-
const toolDeclarations = [
67+
let toolDeclarations = [
6768
BEST_PRACTICES_TOOL,
6869
DOC_SEARCH_TOOL,
6970
LIST_PROJECTS_TOOL,
7071
MODERNIZE_TOOL,
7172
FIND_EXAMPLE_TOOL,
7273
];
7374

75+
if (context.readOnly) {
76+
toolDeclarations = toolDeclarations.filter((tool) => tool.isReadOnly);
77+
}
78+
7479
await registerTools(
7580
server,
7681
{

0 commit comments

Comments
 (0)