Getting started
August 3, 2026 ยท View on GitHub
Last modified: 2026-07-31
This walkthrough runs one local upstream through three gateway configurations. It needs SBproxy, curl, and jq. It makes no network request to an AI provider and needs no API key.
On Windows, run the commands in Git Bash, or replace curl with curl.exe in PowerShell: the bare name is an alias for Invoke-WebRequest there and rejects flags like -H.
SBproxy currently binds its data listener to all host interfaces. Run this
walkthrough on a trusted development machine or behind a host firewall. The
commands connect through 127.0.0.1, and the cleanup section stops both
listeners when you finish.
Install SBproxy first if sbproxy --version does not print a version:
curl -fsSL https://download.sbproxy.dev | sh
export PATH="$HOME/.local/bin:$PATH"
sbproxy --version
Add the export to your shell profile if ~/.local/bin was not already on
PATH.
Clone the repository so the example files are available:
git clone https://github.com/soapbucket/sbproxy
cd sbproxy
The example has four configurations. upstream.yml starts a fixed local service on port 8091. The other files use port 8080 and add one traffic type at a time: HTTP API, MCP, then AI.
for config in upstream.yml api.yml mcp.yml sb.yml; do
sbproxy validate "examples/enterprise-ai-gateway/$config"
done
sbproxy validate parses and compiles the configuration without opening a listener. Fix a validation error before starting the process.
Start the local upstream
In the first terminal, run the fixture and leave it running:
sbproxy serve -f examples/enterprise-ai-gateway/upstream.yml
upstream.yml sets proxy.http_bind_port to 8091. Its 127.0.0.1 origin uses a mock action that returns a fixed OpenAI-compatible JSON response on every path. The fields used later are gateway, object, model, and choices[0].message.content.
Stage 1: proxy an HTTP API
In a second terminal, start the API configuration:
sbproxy serve -f examples/enterprise-ai-gateway/api.yml
api.yml binds the gateway to port 8080. Its api.example.com origin has a proxy action whose upstream URL is http://127.0.0.1:8091. The Host header selects that origin, so the client can reach a local listener while still exercising hostname routing.
SBproxy blocks proxy upstreams that resolve to private IP addresses by
default. This local example opts into only the IPv4 loopback range with
proxy.extensions.upstream.allow_private_cidrs: [127.0.0.0/8]. Keep that
allowlist as narrow as possible; a production service on a public address
does not need it. The AI provider in stage 3 has a separate
allow_private_base_url: true switch because model-provider egress is
configured independently from a conventional proxy action.
Send a request from a third terminal:
curl -sS \
-H 'Host: api.example.com' \
http://127.0.0.1:8080/status | jq '{gateway, object, model}'
The response includes "gateway": "sbproxy". That value comes from the local upstream and proves the request passed through the gateway.
Stop the stage-1 gateway with Ctrl-C in the second terminal. Keep the upstream terminal running.
Stage 2: add an MCP tool
Start the next configuration in the second terminal:
sbproxy serve -f examples/enterprise-ai-gateway/mcp.yml
mcp.yml keeps the API origin and adds mcp.example.com. Its mcp action derives a tool from the local upstream's OpenAPI description. The server is given the local prefix and uses an always-on namespace, so its GET /status operation appears as local.gateway_status.
An MCP client initializes the connection before it lists or calls tools. This example leaves sessions disabled, so the gateway does not return a session ID that you need to save.
Initialize the client:
curl -sS \
-H 'Host: mcp.example.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl-demo","version":"1.0.0"}}}' \
http://127.0.0.1:8080/ | jq .
Then tell the gateway initialization is complete:
curl -sS -o /dev/null -w 'initialized: HTTP %{http_code}\n' \
-H 'Host: mcp.example.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
http://127.0.0.1:8080/
List the tool catalog:
curl -sS \
-H 'Host: mcp.example.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
http://127.0.0.1:8080/ | jq '.result.tools[] | select(.name == "local.gateway_status")'
The command prints the local.gateway_status tool. Call it with another JSON-RPC request:
curl -sS \
-H 'Host: mcp.example.com' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"local.gateway_status","arguments":{}}}' \
http://127.0.0.1:8080/ | jq '.result.content'
The returned content contains sbproxy. Stop this gateway with Ctrl-C before the next stage.
Stage 3: add an AI endpoint
Start the complete configuration:
sbproxy serve -f examples/enterprise-ai-gateway/sb.yml
sb.yml keeps the API and MCP origins, then adds ai.example.com. Its ai_proxy action uses local-demo as the default model. The local-openai provider speaks the OpenAI protocol at http://127.0.0.1:8091/v1; allow_private_base_url: true permits this loopback provider. The fixture answers the request, so no model weights or provider credentials are involved.
Send a chat completion:
curl -sS \
-H 'Host: ai.example.com' \
-H 'Content-Type: application/json' \
-d '{"model":"local-demo","messages":[{"role":"user","content":"Say hello."}]}' \
http://127.0.0.1:8080/v1/chat/completions \
| jq '{object, model, content: .choices[0].message.content}'
The response has "object": "chat.completion" and a nonempty content value.
Stop and clean up
Press Ctrl-C in the gateway terminal, then press Ctrl-C in the upstream terminal. The walkthrough starts no background process, writes no credentials, and leaves no model cache. Keep the checked-out example files for later runs.
Continue
Read core concepts for the shared request pipeline, then use configuration.md to change the example. MCP and AI gateway explain the two actions in depth. To connect a LangChain application, model calls and tools both, follow langchain.md. To run actual local model weights, use Run your first managed model.