Foral — the runner
Charters for software without public APIs. Foral turns the systems your team already logs into into typed, governed capabilities for your AI agents — served over MCP, with no public API required, no browser puppeteering, and no generated code that rots.
This package is the runner: the commodity client that runs on your infrastructure. It loads a contract, serves its read capabilities to your agent as MCP tools, and keeps writes human-approved. The discovery engine that proposes a contract is not in here — the runner is small and auditable on purpose.
- Website: https://foral.dev
- Docs: https://foral.dev/docs
- Contact: founders@foral.dev
Install
# base — serve / verify / update (no browser)
pipx install foral # or: npm i -g @foral/cli
# to also sign in locally (foral login), add the browser extra, once:
pipx install --include-deps 'foral[login]'
playwright install chromium
Quickstart
# 1) the three things the runner needs — it is fail-closed and never guesses
export FORAL_TENANT=your-org # isolates your sessions & contracts
export SESSION_ENCRYPTION_KEY="$(foral keygen)" # encrypts the saved session — keep it safe
export CONTRATOS_DIR=~/foral/contracts # where your contract YAML lives
# put the contract you downloaded from the sandbox here, named after the system:
# ~/foral/contracts/acme.yaml → foral serve acme (lowercase)
# 2) sign in once (opens your system's login in a browser; the session stays on this
# machine, ~30 days) and serve it as an MCP server
foral login acme
foral serve acme
Point your agent at it
# Claude Code
claude mcp add foral -- foral serve acme
// Cursor — ~/.cursor/mcp.json
{ "mcpServers": { "foral": { "command": "foral", "args": ["serve", "acme"] } } }
# Codex — ~/.codex/config.toml
[mcp_servers.foral]
command = "foral"
args = ["serve", "acme"]
Any MCP client works — your own app connects to the same server and calls the system's capabilities as typed tools.
Commands
| Command | What it does |
|---|---|
foral serve <system> |
Serve the system's contract as an MCP server (stdio). |
foral login <system> |
Sign in once; save the session locally, encrypted (~30 days). Needs foral[login]. |
foral update <system> --from <url> |
Adopt a new contract version — validated before it is applied (fail-closed). |
foral verify <system> |
Validate the contract and exit. |
foral keygen |
Print a fresh SESSION_ENCRYPTION_KEY. |
How it behaves
- Reads run with no browser. Read capabilities call the system's own internal API using your saved session and return typed rows — in milliseconds, no Chromium.
- Writes stay human-approved. Write capabilities are never served as MCP tools and never execute here: the runner returns the declared confirmation phrase instead. Approval happens in your app's harness, never silently.
- The session never leaves your machine.
foral loginsaves an encrypted session locally; it is never sent to Foral. Your password is typed into your own system's form. - Contracts stay alive. Every read carries a fingerprint of the system's shape. When the
system changes, the next read raises an alarm before wrong data can flow — your cue to run
foral update. - Fail-closed by default. An invalid contract does not load; a missing tenant is refused; a missing key is refused. Errors are explicit, never a silent, wrong success.
Environment
| Variable | Required | Purpose |
|---|---|---|
FORAL_TENANT |
serve, login | Isolates your sessions and contracts. No default (fail-closed). |
SESSION_ENCRYPTION_KEY |
login, serve | Encrypts the saved session. Generate with foral keygen. |
CONTRATOS_DIR |
serve, update | Directory holding <system>.yaml. |
SESSION_DATA_DIR |
optional | Where sessions are stored (default ./sessions). |
Development
pip install -e '.[test]'
pytest
License
Apache-2.0 — see LICENSE.
Metadata
Release files for foral 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| foral-0.4.0.tar.gz | 21.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| foral-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.5 kB
Release files / foral-0.4.0.tar.gz
| Download URL | foral-0.4.0.tar.gz |
|---|---|
| Size | 21.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
851cd65286db0c6b6ee380d61ce28f53f17af6dac38b6e9f3157f00d4d53ffb3
|
|
BLAKE2b-256 checksum How to use checksums |
fe25cbc87ac41f2ca517b41efa640584a2064fe1ff1012a5be6ed15d21012487
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / foral-0.4.0-py3-none-any.whl
| Download URL | foral-0.4.0-py3-none-any.whl |
|---|---|
| Size | 26.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b51eb310de0235321aed3048490bc280b3fdb1ff1fd1afcced2d0bc620dd002c
|
|
BLAKE2b-256 checksum How to use checksums |
bb36e09fd53d0847219df8cd1b44bf80ee764dfba53532fba5dad5c389070bd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|