URL login (HTML)
For old-school websites without a public API. appctl logs in through a form, stores the session cookie, and discovers any forms and links it can reach.
Prerequisites
Section titled “Prerequisites”- A login URL that accepts username and password as form fields.
- A session cookie flow after login. Pure JavaScript single-page apps are not in scope; use their backing API with
--openapiinstead. appctlinstalled.
The demo in this repo
Section titled “The demo in this repo”examples/demos/url-login/ is a short Flask app with one login form (/login) and one protected page (/).
1. Start the server
Section titled “1. Start the server”cd examples/demos/url-loginpython3 -m venv .venvsource .venv/bin/activatepip install -r requirements.txtpython app.pySanity check:
curl -s -c /tmp/cookie -X POST http://127.0.0.1:5009/login \ -d "user=alice&password=secret" -o /dev/null \ -w "status=%{http_code}\n"# status=302
curl -s -b /tmp/cookie http://127.0.0.1:5009/# <p>ok alice</p><a href=/logout>logout</a>2. Run the sync
Section titled “2. Run the sync”appctl sync --url http://127.0.0.1:5009/ \ --login-url http://127.0.0.1:5009/login \ --login-user alice --login-password secret --forceReal output:
INFO logging in at http://127.0.0.1:5009/login as aliceSynced Url: 0 resources, 0 tools written to .appctlThe login worked, but the post-login page here has no discoverable structure beyond a logout link. For the crawler to produce tools, the post-login page needs forms, tables, or links with an action attribute it can interpret.
What appctl does in this mode
Section titled “What appctl does in this mode”- Issues a
POSTto the login URL withuserandpasswordfields by default. Change the field names with--login-user-fieldand--login-password-field. - Stores cookies in memory for the duration of the sync.
- Starts from the base URL and follows links up to a small depth, turning each form it finds into a tool.
Known limits
Section titled “Known limits”- Sites that sign requests (CSRF tokens, CAPTCHAs, two-factor) will not work with this source. Use a real integration.
- Single-page apps that fetch JSON over XHR after load are invisible to a static crawler. Intercept the XHR calls and feed the resulting API to
--openapi. - Session cookies are not rotated during a chat session. Long-running
appctl servedeployments may need to re-login periodically.