AlistGo/alist · error

MCP manage not permitted

Error message

MCP manage not permitted

What it means

Returned by checkManage (server/mcp/auth.go:143) when a write-oriented MCP operation is attempted by a non-admin whose merged permissions lack PermMCPManage. It fires after checkAccess has already passed, so path access and the MCP access bit are fine — the additional 'manage' (write-level) grant is missing.

Source

Thrown at server/mcp/auth.go:143

	meta, _ := op.GetNearestMeta(reqPath)
	if !common.CanAccessWithRoles(user, meta, reqPath, "") {
		return fmt.Errorf("permission denied")
	}
	perm := common.MergeRolePermissions(user, reqPath)
	if !user.IsAdmin() && !common.HasPermission(perm, common.PermMCPAccess) {
		return fmt.Errorf("MCP access not permitted")
	}
	return nil
}

// checkManage checks if user can perform write operations via MCP.
func checkManage(user *model.User, reqPath string, permBit uint) error {
	if err := checkAccess(user, reqPath); err != nil {
		return err
	}
	perm := common.MergeRolePermissions(user, reqPath)
	if !user.IsAdmin() && !common.HasPermission(perm, common.PermMCPManage) {
		return fmt.Errorf("MCP manage not permitted")
	}
	if !user.IsAdmin() && !common.HasPermission(perm, permBit) {
		return fmt.Errorf("permission denied for this operation")
	}
	return nil
}

// UserContextFunc returns an HTTPContextFunc that injects a specific user (for STDIO mode).
func userContextMiddleware(user *model.User) func(ctx context.Context) context.Context {
	return func(ctx context.Context) context.Context {
		return context.WithValue(ctx, userKey, user)
	}
}

// resolveUserForStdio resolves a user by username for STDIO mode.
func resolveUserForStdio(username string) (*model.User, error) {
	username = strings.TrimSpace(username)
	if username == "" || username == "admin" {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Grant the MCP manage permission to the role performing write operations
  2. Use separate read-only and read-write roles so the manage bit is deliberate
  3. Verify with the permission matrix in the admin UI before scripting writes
Defensive patterns

Strategy: validation

Validate before calling

// before scripting write operations, assert the role carries both mcp access and mcp manage

Prevention

When it happens

Trigger: A non-admin user with mcp access but not mcp manage calls a mutating MCP tool (write, rename, or delete flows) that routes through checkManage.

Common situations: Read-only MCP roles being reused for maintenance scripts; permission sets cloned from a read role and never given the manage bit.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/9fe5601664f1bf07. Report an issue: GitHub.