I know you said you didn't want to use SPICE, but since no one has posted an answer I thought I should mention this. I found a repository on ESA's site with SPICE kernel that contains the old Horizons reference data you're looking for (it says the data comes from Horizons in the README).
https://repos.cosmos.esa.int/socci/projects/SPICE_KERNELS/repos/jwst/browse
Given that .bsp, and a kernel for an Earth-centered Earth-fixed frame (pck00010.tpc contains IAU_EARTH), you would be able to do your calculations.
Here is a quick Python script that reads in the bsp and outputs a csv so you could just run this once and not use SPICE anymore. You would need to have your own copies of naif0012.tls (leapseconds kernel), de432s.bsp, pck00010.tpc, or you can use this repo that has them and the spice_data file in it contains the filepaths ( https://github.com/alfonsogonzalez/AWP ). The bsp has data from 2020-01-01 to 2024-01-01, so just depends on how much of it you want and your timestep.
import spice_data as sd
import spiceypy as spice
import numpy as np
if __name__ == '__main__':
spice.furnsh( sd.leapseconds_kernel )
spice.furnsh( sd.de432 )
spice.furnsh( sd.pck00010 )
spice.furnsh( 'jwst_horizons_20200101_20240101_v01.bsp' )
et0 = spice.str2et( '2022-01-01' )
etf = spice.str2et( '2022-01-15' )
dt = 3600
ets = np.arange( et0, etf, dt )
states = np.array( spice.spkezr(
'-170', ets, 'IAU_EARTH', 'NONE', '399' )[ 0 ] )
arr = np.zeros( ( len( ets ), 7 ) )
arr[ :, 0 ] = ets
arr[ :, 1: ] = states
np.savetxt( 'jwst-iau-earth.csv', arr, delimiter = ',' )
if False:
import plotting_tools as pt
pt.plot_orbits( [ states[ :, :3 ] ], { 'show': True } )

The SPICE function recrad converts from rectangular to range, right ascension, declination: https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/recrad_c.html
You can get the IAU_EARTH vector of a point on Earth defined by lat/lon using SPICE's reclat function (converts from rectangular to latitudinal coordinates: https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/reclat_c.html ).
I believe that implementation is straight forward to you wouldn't have to use SPICE here if you don't want.
Its been a while since I've looked at azimuth/elevation calculations, here is an attempt at the algorithm (feel free to edit and correct):
All vectors in IAU_EARTH reference frame.
Position vector pointing from site to JWST:
$\vec{r}_{rel}=\vec{r}_{JWST}-\vec{r}_{site}$
The site position vector $\vec{r}_{site}$ defines the local surface plane. Local north is equal to the projection of the z-unit vector onto local surface plane.
$\hat{N}=\hat{z}-(\hat{z} \cdot \hat{r}_{site})\hat{r}_{site}$
Similarly, the projection of $\vec{r}_{rel}$:
$p\vec{ro}j_{rel}=\hat{r}_{rel}-(\hat{r}_{rel} \cdot \hat{r}_{site})\hat{r}_{site}$
Azimuth is equal to the angle between local north and that projection (have to check for CW or CCW)
Elevation is equal to the angle between $\hat{r}_{rel}$ and $p\vec{ro}j_{rel}$. Again this would need a check for if JWST is visible at that time or on the other side of the Earth.