Polycallfile reference¶
Polycallfile (exactly that capitalization, no extension) is the single,
explicit source of runtime topology and policy
(CFG-001).
There is no include mechanism, no parent-directory search, no home-directory
discovery, and no environment-variable override of its contents. The CLI
selects ./Polycallfile when no path is given, or an explicit final
positional argument otherwise.
Not this project's Polycallfile, despite the name
docs/CONFIGURATION_STANDARD.md and the project's original README
describe an older, unrelated three-layer scheme (Polycallfile +
Polycallrc + Polycallrc.<language>, bare server LANG PORT:PORT
lines, config rc show/config rc validate commands). None of that
matches the current grammar, and none of those extra commands exist in
the current CLI reference. It is preserved as
historical material in the migration guide;
this page documents the schema main actually parses.
Grammar¶
A small, deliberately restricted, TOML-like declarative syntax (CFG-004):
file = { line } ;
line = ws, [ section | assignment ], ws, [ comment ], newline ;
section = "[", identifier, { ".", identifier }, "]" ;
assignment = identifier, ws, "=", ws, value ;
value = string | integer | boolean | array ;
array = "[", ws, [ scalar, { ws, ",", ws, scalar } ], ws, "]" ;
identifier = letter, { letter | digit | "_" | "-" } ;
Identifiers are ASCII, case-sensitive. Strings are double-quoted, with only
\", \\, \n, \r, \t as valid escapes. No multiline strings, no
hex/float/date/null literals, no inline objects. Comments start with #
outside a string. Duplicate keys, repeated sections, and unknown
sections/keys are errors — there is no last-value-wins merging.
Sections and fields¶
| Section | Key | Type / meaning |
|---|---|---|
| root | schema |
integer, exactly 1 |
[runtime] |
name |
nonempty string, ≤128 UTF-8 bytes |
[runtime] |
listen |
tcp://127.0.0.1:PORT or tcp://[::1]:PORT |
[runtime] |
max_connections |
1–4096, default 128 |
[runtime] |
workers |
1–256, default 4 |
[runtime] |
queue_capacity |
1–65536, default 1024 |
[runtime] |
max_frame_bytes |
1024–16777216, default 1048576 |
[runtime] |
max_inflight_per_connection |
1–1024, default 64 |
[runtime] |
call_timeout_ms |
1–3600000, default 30000 |
[runtime] |
drain_timeout_ms |
1–3600000, default 10000 |
[runtime] |
startup_timeout_ms |
1–3600000, default 10000 |
[security] |
mode |
"token", "local-auto", or "mtls" — see below |
[security] |
token_env |
env var name holding the secret, when mode = "token" |
[security] |
allow_remote |
boolean, default false |
[telemetry] |
enabled |
boolean, default true |
[telemetry] |
include_payloads |
boolean, must be false in baseline |
[service.ID] |
language |
one of c, python, node, lua, go, java, cobol — informational only, see below |
[service.ID] |
mode |
"external" (baseline) or "spawn" |
[service.ID] |
max_concurrency |
1–1024, default 1 |
[method.SERVICE.METHOD] |
params |
array of type strings, positional |
[method.SERVICE.METHOD] |
result |
type string |
[method.SERVICE.METHOD] |
idempotent |
boolean, default false |
[grant.ID] |
principal |
authenticated principal name |
[grant.ID] |
service, methods |
what this grant covers |
[grant.ID] |
actions |
array containing "invoke" and/or "register" |
Type strings for params/result: null, bool, i32, i64, u32,
u64, f64, string, bytes, or list<T> of one scalar type (no
nested lists).
[service.ID].language does not gate registration — nothing stops a
provider written in a different language from registering for that
service's methods. It documents intent, not an enforced constraint.
security.mode¶
"token"— the baseline profile. The secret comes from the named environment variable and must be supplied out of band."local-auto"— implemented, verified, not yet written into the published LPV1-04 text (the code refers to it as CFG-021). The runtime generates a shared secret and stores it via the OS credential facility (Windows Credential Manager, or~/.polycall-credentials/<name>on Linux); the CLI, an in-process provider, andprovider.pyall read the same entry automatically. This is what the shipped root Polycallfile uses, and what Your first Python call runs."mtls"— parses, butruntime startdeliberately refuses to bind when it sees this mode rather than opening a plaintext socket under a label that implies certificate-based security it doesn't provide.
The shipped example¶
The repository root's own Polycallfile (used by every tutorial on this
site):
schema = 1
[runtime]
name = "polycall-dev"
listen = "tcp://127.0.0.1:8080"
max_connections = 1000
call_timeout_ms = 5000
[security]
mode = "local-auto"
allow_remote = false
[telemetry]
enabled = true
include_payloads = false
[service.math]
language = "python"
mode = "external"
max_concurrency = 4
[method.math.add]
params = ["i64", "i64"]
result = "i64"
idempotent = true
[grant.local]
principal = "token-principal"
service = "math"
methods = ["add"]
actions = ["invoke", "register"]
(It also declares placeholder [service.node], [service.python],
[service.java], [service.go] entries with no matching [method.*] —
those are unused by any current tutorial.)
CLI commands that touch it¶
polycall config validate <Polycallfile>— parses and validates only; never connects to anything.polycall config show --json <Polycallfile>— prints the validated effective model. This is also howprovider.pyobtains connection parameters (see Core concepts) — secret values never appear in this output, only variable names where applicable.polycall config migrate --from <old> <new-Polycallfile>— registered, reportsunsupported. No historical-format reader is implemented yet; do not depend on this to convert an old-style config.polycall runtime reload— accepted by the CLI, but the server side isn't built yet; the only fields schema 1 defines as ever reloadable without a restart aretelemetry.enabledandtelemetry.sample_per_million.