Not just a four fours puzzle
Python 3, 265 bytes



def f(x,n):
 for e in g(x,x-(x&gt;7)):
  try:
   if eval(e)==n:return e
  except:1
g=lambda x,d:{str(x)*-~i for i in range(d)}|{s%(a,b)for a in g(x,d-1)for b in g(x,d-a.count(str(x)))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}if d else{}


Try it online!

Works for all numbers in the reference linked by Engineer Toast.

Runs up to x=8 on tio, x=9 takes a couple of minutes on my machine.



The function g returns a set of all combinations with at most x number of x's. f then loops through them and returns the first which evaluates to the number n.

The number of possible values i found for each x are:

x  possible numbers
------
2  5
3  17
4  35
5  56
6  83
7  101
8  101
9  101


All the numbers above can be generated from (a+b), (a-b), (a+b), a*b, a/b, (a/b), and a^b.
a+b and a-b do not give more numbers.

a^b is also only used once, as otherwise huge numbers are created (this is also verified in the reference document above)



An alternate version which short-circuits as soon as it finds a solution (not as golfed):

This is much faster as for x=7..9 all numbers can be created.

Python 3, 338 289 bytes



def f(x,n,d=-1):
 d=[d,x][d&lt;0];X=str(x);r=set()
 for E in{X*-~i for i in range(d)}|{s%(a,b)for a in[0]*d and f(x,n,d-1)for b in f(x,n,d-a.count(X))for s in'%s**%s (%s/%s) (%s+%s) (%s-%s) %s*%s %s/%s'.split()['**'in a+b:]}:
  try:e=eval(E)
  except:e=-1
  if e==n:exit(E)
  r|={E}
 return r


Try it online!