angular/angular-cli · error · Error

Workspace path is outside the allowed MCP roots: ${workspace

Error message

Workspace path is outside the allowed MCP roots: ${workspacePath}. You can use 'list_projects' to find available workspaces.

What it means

Before serving version-specific Angular best practices, the tool verifies the resolved workspace path is inside the allowed MCP roots. If workspacePath falls outside every root, it throws with a hint to use list_projects to find accessible workspaces.

Source

Thrown at packages/angular/cli/src/commands/mcp/tools/best-practices.ts:113

  workspacePath: string,
  logger: McpToolContext['logger'],
  server: McpToolContext['server'],
): Promise<{ content: string; source: string } | undefined> {
  if (server) {
    let isAllowed: boolean;
    try {
      isAllowed = await isAllowedWorkspacePath(server, workspacePath);
    } catch (e) {
      logger.warn(
        `Failed to verify workspace path '${workspacePath}': ` +
          `${e instanceof Error ? e.message : e}. Falling back to the bundled guide.`,
      );

      return undefined;
    }

    if (!isAllowed) {
      throw new Error(
        `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` +
          "You can use 'list_projects' to find available workspaces.",
      );
    }
  }

  // 1. Resolve the path to package.json
  let pkgJsonPath: string;
  try {
    const workspaceRequire = createRequire(workspacePath);
    pkgJsonPath = workspaceRequire.resolve('@angular/core/package.json');
  } catch (e) {
    logger.warn(
      `Could not resolve '@angular/core/package.json' from '${workspacePath}'. ` +
        'Is Angular installed in this project? Falling back to the bundled guide.',
    );

    return undefined;

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Run the MCP server with the Angular workspace directory as the working directory or add it to the roots.
  2. Call setRoots with the workspace path before invoking the tool.
  3. Use the list_projects tool to find which workspaces are actually accessible.
  4. Remove symlinks so the real workspace path is inside an allowed root.

Example fix

// before
getVersionSpecificBestPractices({ workspacePath: '/shared/legacy-app' });
// after
host.setRoots(['/home/dev/legacy-app']);
getVersionSpecificBestPractices({ workspacePath: '/home/dev/legacy-app' });
Defensive patterns

Strategy: validation

Validate before calling

import { relative, isAbsolute } from 'node:path';
function workspaceAllowed(workspacePath: string, roots: string[]): boolean {
  return roots.some((root) => {
    const rel = relative(root, workspacePath);
    return !rel.startsWith('..') && !isAbsolute(rel);
  });
}
if (!workspaceAllowed(ws, allowedRoots)) {
  console.warn('use list_projects to find accessible workspaces');
}

Type guard

function isInAllowedWorkspace(p: string, roots: string[]): p is string {
  return roots.some((r) => !relative(r, p).startsWith('..') && !isAbsolute(relative(r, p)));
}

Try / catch

try {
  await versionSpecificBestPractices({ workspacePath });
} catch (e) {
  if ((e as Error).message.includes('outside the allowed MCP roots')) {
    const projects = await listProjects();
    await versionSpecificBestPractices({ workspacePath: projects[0].path });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a version-specific best-practices tool when the target workspace path (from the tool input or an inferred cwd) resolves outside the roots configured on the MCP host.

Common situations: MCP client opened on a directory different from the Angular workspace; workspace inside a symlink that resolves outside roots; multi-root setups where only some projects are registered as roots.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/538ae44fde18a7a1. Report an issue: GitHub.