I don't believe there is a direct way to do this, but there is a horrible and ugly indirect way I can think of that was a fun challenge to come up with:
So, JMP reacts predictably when you try to evaluate a function with the right and wrong number of arguments. For instance:
beta density()
will give us:

But, the following will not error and will return "." because Beta Density needs 3 arguments ( x, alpha, and beta).
beta density(empty(),empty(),empty())
In fact, until we reach the max number of arguments the function expects, we will continue to get "." That is, until we hit the 1+ the max number of arguments, which is 6:
beta density(empty(),empty(),empty(),empty(),empty(),empty())
Which gives us:

So, let's exploit this by building a (ugly) function that tests up to 10 potential arguments and returns the min and max arguments (and of course, you could generalize this if you feel like it to an arbitrarily large number of args, I thought 10 would cover all of them so I just did it by brute force). The function responds like this:

Some functions, like Random Normal() seem to behave strangely, perhaps because they have no min number of arguments, or because there is something different about them. I'm not sure. And some functions, like Interest Rate() seem to be happy accepting any number of arguments up to the max tested. So, far from perfect, and it would be nice to have a jsl lookup function that would return details directly. In any case, here's the code below, and attached as a script.
getRecArgs = Function( {funcHead},
min = .;
max = .;
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 1,
max = 1
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 2,
max = 2
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 3,
max = 3
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 4,
max = 4
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 5,
max = 5
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 6,
max = 6
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 7,
max = 7
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 8,
max = 8
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 8,
max = 8
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 9,
max = 9
)
);
If( Eval( Parse( Eval Insert( "if(isMissing(try(^funcHead^(empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty(),empty()),0)),1,0);" ) ) ),
If( Is Missing( min ),
min = 10,
max = 10
)
);
If( Is Missing( min ),
min = 0
);
Return( min, max );
);
Here is a function that takes Julian's cool idea and shortens the code a bit.
The function has an optional 2nd argument, specifying when to quit (default is 10 arguments).
getNumArgBand = Function( {str, max = 10},
{default local},
fctExpr = Parse( Eval Insert( "^str^()" ) );
res = [];
For Each( {i}, 0 :: max,
Insert Into( res,
Try( Eval( Name Expr( fctExpr ) ); 1, 0 )
);
Insert Into( fctExpr, Empty() );
);
Return( Eval List( {Min( Loc( res ) ), Max( Loc( res ) )} - 1 ) ); //account for 0-indexing
);
Results match those provided by Julian, except in the random normal case. Didn't look into why mine reports {0,2} and his reports {0,. }
