Skip to Content
Quick Start

Quick Start

This guide starts the gateway and agent as separate processes and verifies REST API, MCP, OpenAPI, and healthz.

1. Build Binaries

Build from the repository root.

make build

This produces two deployable units.

dist/onprest-gateway dist/onprest-agent

Docker is optional for the Onprest OSS core. This guide uses Docker only to provide a disposable local PostgreSQL database for the repository example capability.

Repository Example Files

The repository includes matching example files for local evaluation:

  • examples/gateway.env
  • examples/capability.postgres.yaml
  • examples/postgres.compose.yml
  • examples/postgres-init.sql

Those files contain a matching agent key pair and API key hash. If you use them, use the example plaintext API key in the verification steps and skip the key/config creation steps below.

Start the example PostgreSQL database.

make quickstart-db

This starts a local PostgreSQL container on 127.0.0.1:5432, creates the legacy database, creates the readonly_user account used by examples/capability.postgres.yaml, and seeds the customers table. If 127.0.0.1:5432 is already in use, stop that PostgreSQL instance or edit both examples/postgres.compose.yml and examples/capability.postgres.yaml to use the same alternate port.

For real deployments, generate fresh keys and edit your own capability.yaml.

2. Generate Agent Keys

Steps 2–5 create your own keys and config. If you are using the repository example files, skip steps 2–5 and continue at step 6.

The agent holds an Ed25519 private key. The gateway holds only the public key.

./dist/onprest-gateway create-agent-secret

Put the generated private key in gateway.agent_private_key in capability.yaml, and put the public key in GATEWAY_AGENT_PUBLIC_KEY in gateway.env.

The following compatibility command is also available.

./dist/onprest-gateway create-agent

3. Generate API Key

Create API keys for API users or MCP clients.

./dist/onprest-gateway create-key --name internal --capabilities "*" ./dist/onprest-gateway create-key --name partner-a --capabilities "get_customer,get_orders"

"*" grants all capabilities. Omitted or empty capabilities mean zero permissions.

4. Create gateway.env

gateway.env configures the gateway process.

# Required. GATEWAY_AGENT_PUBLIC_KEY=base64url-ed25519-public-key GATEWAY_API_KEYS_JSON='[{"name":"internal","key_hash":"$2a$10$xxxxx","capabilities":["*"]}]' # Optional. Omit these to use defaults or disabled behavior. # GATEWAY_ADDR=:8080 # GATEWAY_PUBLIC_URL=http://localhost:8080 # GATEWAY_CORS_ALLOWED_ORIGINS=http://localhost:8090 # GATEWAY_IP_ALLOW_LIST=203.0.113.0/24 # GATEWAY_TRUSTED_PROXY_CIDRS=172.16.0.0/12 # GATEWAY_RATE_LIMIT_REQUESTS_PER_SECOND=10 # GATEWAY_RATE_LIMIT_BURST=20 # GATEWAY_EMIT_OPENAPI_SNAPSHOT=false

The key_hash value in GATEWAY_API_KEYS_JSON is a bcrypt hash, so it contains $. Single-quote the whole JSON value when loading it through a shell.

5. Create capability.yaml

The agent treats capability.yaml as the only capability definition.

service: title: Example CRM Capabilities version: 0.1.0 description: Example agent-defined capabilities for a legacy CRM database. gateway: url: ws://localhost:8080/ws/agent agent_private_key: base64url-ed25519-private-key database: driver: postgres host: localhost port: 5432 name: legacy user: readonly_user password: onprest-example-password logging: max_size: 10MB max_files: 3 defaults: readonly: true timeout: 30s max_rows: 1000 max_bytes: 1MB capabilities: get_customer: description: Fetch one customer by id. sql: select id, name, email from customers where id = :customer_id params: customer_id: type: integer required: true minimum: 1 description: Customer ID. policy: timeout: 3s max_rows: 1 max_bytes: 256KB expose_in_openapi: true result: id: type: integer description: Customer ID. name: type: string description: Customer name. email: type: string description: Customer email address.

At startup, the agent runs YAML lint, DB ping, and SQL EXPLAIN verification. If startup validation fails, DB-specific detail and SQL text are not written to stderr; detail is written to onprest-agent.log next to the agent binary.

6. Start Gateway and Agent

The commands below use the repository example files. If you created your own files in steps 2-5, replace ./examples/gateway.env with ./gateway.env and ./examples/capability.postgres.yaml with ./capability.yaml.

Start the gateway.

set -a . ./examples/gateway.env set +a ./dist/onprest-gateway

Start the agent in another terminal.

./dist/onprest-agent --config ./examples/capability.postgres.yaml

If --config and AGENT_CAPABILITY_FILE are both omitted, the agent reads capability.yaml next to the onprest-agent binary.

The agent connects outbound to /ws/agent. During connection, the gateway verifies the signature with the agent public key. After connection, the gateway calls the internal meta capability to fetch the agent-generated OpenAPI spec and caches it in memory (see OpenAPI).

7. Verify Health

curl -s http://localhost:8080/healthz

/healthz can be called without an API key. It monitors the gateway process and agent connection state.

{ "ok": true, "agent_connected": true }

8. Verify REST

Set the plaintext API key in the shell that will call the gateway. If you are using the repository example files, use the example plaintext key.

export ONPREST_API_KEY='orjrqqPeX8FXhsECOnrnOr6oa70pOYjyeUWmxTbaZrM'
curl -s \ -X POST http://localhost:8080/api/v1/capabilities/get_customer \ -H "Authorization: Bearer ${ONPREST_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"customer_id":1}'

A successful call returns the rows the capability is allowed to expose:

{ "rows": [ { "id": 1, "name": "Ada Lovelace", "email": "ada@example.com" } ], "count": 1 }

The REST request body is the capability params object directly. Do not wrap it in {"params": {...}}.

9. Verify OpenAPI

curl -s \ -H "Authorization: Bearer ${ONPREST_API_KEY}" \ http://localhost:8080/openapi.json

OpenAPI is fetched from agent metadata, cached by the gateway, and filtered by the API key’s allowed capabilities. It does not include SQL text or DB connection information.

10. Verify MCP

curl -s \ -X POST http://localhost:8080/mcp \ -H "Authorization: Bearer ${ONPREST_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s \ -X POST http://localhost:8080/mcp \ -H "Authorization: Bearer ${ONPREST_API_KEY}" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_customer","arguments":{"customer_id":1}}}'

MCP tools/list is generated from the OpenAPI cache and filtered by the API key’s allowed capabilities.

11. Stop Example Database

make quickstart-db-down