Forge External Runtime Protocol¶
Forge apps can import and call services written outside TypeScript through a
forge.manifest.json compatible manifest. The manifest is the source of truth
for external commands and queries:
- validate and import external service metadata;
- expose external services in generated inspect/API/agent artifacts;
- execute external commands and queries through the Forge runtime bridge.
This lets Java/Spring, Go, Rust, C#, Python, and other runtimes join the Forge contract without requiring the Forge compiler to parse every language AST.
Manifest¶
External services publish JSON that matches
schemas/forge-manifest.schema.json.
{
"forgeProtocol": "1.0",
"language": "java",
"framework": "spring-boot",
"service": {
"name": "billing",
"transport": "http",
"baseUrl": "http://localhost:8080",
"health": "/actuator/health"
},
"entries": [
{
"name": "createInvoice",
"kind": "command",
"path": "/invoices",
"policy": "billing.write",
"transaction": "external-managed",
"risk": "write",
"needsApproval": true,
"effects": ["invoice.created"]
},
{
"name": "listInvoices",
"kind": "query",
"path": "/invoices",
"policy": "billing.read",
"transaction": "read-only",
"risk": "read",
"tenantScoped": true
}
]
}
Queries must stay read-only. Commands can declare write, destructive, or external risk. Policies are metadata until the runtime bridge enforces them for the external transport.
CLI¶
Validate a manifest:
forge manifest validate ./forge.manifest.json --json
Import or update a service in the app registry:
forge manifest import ./forge.manifest.json --json
Imports are stored in .forge/external-manifests.json. A root
forge.manifest.json is also discovered automatically for single-service
experiments.
Generated Artifacts¶
After forge generate, external services are emitted to:
src/forge/_generated/externalServices.jsonsrc/forge/_generated/api.jsonunderexternalsrc/forge/_generated/agentContract.jsonsrc/forge/_generated/agentTools.jsonsrc/forge/_generated/capabilityMap.json
External auto-tools use execution: "external-runtime-endpoint". Forge exposes
runtime bridge endpoints for these tools:
POST /external/:service/commands/:name
POST /external/:service/queries/:name
The generated client exposes the same bridge through:
await client.externalCommand("billing.createInvoice", args);
await client.externalQuery(api.external.queries["billing.listInvoices"], args);
Command entries can also be invoked from the CLI with a qualified external name:
forge run billing.createInvoice --args '{"title":"Invoice"}'
forge query billing.listInvoices --args '{}'
forge run query billing.listInvoices --args '{}'
Java Adapter¶
Forge ships a minimal Java adapter under adapters/java. The adapter is a small
SDK for JVM services that want to join the Forge external runtime protocol
without requiring Forge to parse Java source code.
ForgeRegistry app = Forge.service("billing",
Forge.framework("java/jdk-http"),
Forge.baseUrl("http://127.0.0.1:8788"));
app.command("createInvoice",
Forge.handle(CreateInvoiceInput.class, Billing::createInvoice),
Forge.policy("billing.manage"),
Forge.tenantScoped(true),
Forge.needsApproval(true));
app.query("listInvoices",
Forge.handle(EmptyInput.class, Billing::listInvoices),
Forge.policy("billing.manage"),
Forge.tenantScoped(true),
Forge.readOnly());
The adapter exposes GET /manifest, GET /health, POST /commands/:name, and
POST /queries/:name. The examples/java-billing app demonstrates manifest
export, HTTP serving, policy enforcement through the Forge bridge, generated
client calls, and agent tool registration.
Spring Boot users can start from adapters/java-spring-boot-starter, which
provides @ForgeExternalService, @ForgeCommand, and @ForgeQuery annotations
plus a ForgeRegistry auto-configuration hook.
Runtime Bridge¶
Forge accepts the normal JSON body:
{ "args": {} }
For HTTP services, Forge forwards a JSON envelope:
{
"args": {},
"auth": { "kind": "user", "userId": "u1", "tenantId": "t1", "role": "member" },
"forge": {
"service": "billing",
"entry": "createInvoice",
"kind": "command",
"traceId": "trace_..."
}
}
Forge also forwards runtime headers such as x-forge-trace-id,
x-forge-auth-kind, x-forge-user-id, x-forge-tenant-id, x-forge-role,
and the inbound Authorization header when present.
External services can return either a Forge envelope:
{ "ok": true, "result": { "id": "inv_1" } }
or a raw JSON value, which Forge treats as the result for successful HTTP
responses. Error envelopes should include ok: false, diagnostics, or
error.
Supported runtime transports:
http: callsservice.baseUrl + entry.path.stdio: startsservice.command, writes the JSON envelope to stdin, and reads a JSON envelope or raw JSON result from stdout.grpc: accepted in manifests for forward compatibility, but not executable by the built-in runtime bridge yet.
Manifest policy values are added to Forge policy bindings during generation.
Use a named Forge policy, or public, user, or system.