Skip to content

gtc start

The gtc start command launches the Greentic runtime server. It starts all necessary services including the HTTP server, NATS bus, and flow executor.

Terminal window
gtc start [OPTIONS] <BUNDLE_PATH>
OptionDescriptionDefault
--host <HOST>Bind address0.0.0.0
--port <PORT>HTTP port8080
--cloudflared <on/off>Enable Cloudflare tunnelon
--ngrok <on/off>Enable ngrok tunneloff
--nats <on/off>Enable embedded NATSon
--skip-setupSkip provider setup flowsfalse
--force-setupForce re-run setup flowsfalse
-v, --verboseEnable verbose/debug loggingfalse
-q, --quietMinimal outputfalse
Terminal window
gtc start ./my-bundle

This starts:

  • HTTP server on 0.0.0.0:8080
  • Embedded NATS server
  • Cloudflared tunnel (if available)
Terminal window
# Use ngrok instead of cloudflared
gtc start ./my-bundle --cloudflared off --ngrok on
# With verbose logging
gtc start ./my-bundle --verbose
# Skip setup (if already configured)
gtc start ./my-bundle --skip-setup
Terminal window
# No tunnels, external NATS
gtc start ./my-bundle --cloudflared off --ngrok off
# Custom port
gtc start ./my-bundle --port 3000 --cloudflared off

Cloudflared creates a secure tunnel to Cloudflare’s network:

Terminal window
gtc start ./my-bundle --cloudflared on
# Output:
# Cloudflare tunnel started: https://random-words.trycloudflare.com
# Webhook URLs will use: https://random-words.trycloudflare.com

Use ngrok for a stable URL during development:

Terminal window
gtc start ./my-bundle --ngrok on
# Output:
# ngrok tunnel started: https://abc123.ngrok-free.app
# Webhook URLs will use: https://abc123.ngrok-free.app

For production with a public domain:

Terminal window
gtc start ./my-bundle --cloudflared off --ngrok off
# Make sure your server is publicly accessible
# and update provider webhooks with your domain
Terminal window
gtc start ./my-bundle --nats on
# Starts embedded NATS on localhost:4222
Terminal window
# Disable embedded, use external
gtc start ./my-bundle --nats off
# Set NATS URL via environment
GREENTIC_NATS_URL=nats://nats.example.com:4222 gtc start ./my-bundle --nats off

By default, gtc start runs setup flows if providers are not yet configured:

Terminal window
gtc start ./my-bundle
# Runs setup flows for unconfigured providers

Skip setup flows entirely (use existing configuration):

Terminal window
gtc start ./my-bundle --skip-setup

Force re-run all setup flows (useful after URL changes):

Terminal window
gtc start ./my-bundle --force-setup

When running, the server exposes:

EndpointPurpose
GET /healthHealth check
GET /readyReadiness probe
POST /webhook/{provider}/{tenant}/{team}Provider webhooks
GET /api/v1/sessionsSession management
POST /api/v1/messagesSend messages
GET /auth/configOAuth configuration endpoint
POST /oauth/token-exchangeServer-side OIDC token exchange proxy
Terminal window
curl http://localhost:8080/health
# {"status": "healthy"}

The runtime exposes two endpoints for OAuth/OIDC integration with messaging providers that require user authentication (such as WebChat or Teams).

Reads the OAuth configuration from the secrets store and returns it to the client. Clients use this endpoint to discover the identity provider settings needed to initiate an authorization flow.

Terminal window
curl http://localhost:8080/auth/config
# {
# "authority": "https://login.microsoftonline.com/{tenant-id}/v2.0",
# "client_id": "your-client-id",
# "redirect_uri": "https://your-public-url/auth/callback",
# "scope": "openid profile"
# }

A server-side token exchange proxy for OIDC authorization code exchange. This endpoint allows clients to exchange an authorization code for tokens without running into browser CORS restrictions that occur when calling identity provider token endpoints directly from the frontend.

Terminal window
curl -X POST http://localhost:8080/oauth/token-exchange \
-H "Content-Type: application/json" \
-d '{"code": "authorization_code_here", "redirect_uri": "https://your-public-url/auth/callback"}'

Static routes (such as health checks and OAuth endpoints) can be configured without requiring an explicit public base URL. This means these endpoints are available immediately when the server starts, even before a tunnel or public URL is established.

Terminal window
# Debug (most verbose)
GREENTIC_LOG_LEVEL=debug gtc start ./my-bundle
# Info (default)
GREENTIC_LOG_LEVEL=info gtc start ./my-bundle
# Warning
GREENTIC_LOG_LEVEL=warn gtc start ./my-bundle
Terminal window
gtc start ./my-bundle --verbose
# Equivalent to GREENTIC_LOG_LEVEL=debug
Terminal window
# JSON format (for production)
GREENTIC_LOG_FORMAT=json gtc start ./my-bundle
# Pretty format (for development, default)
GREENTIC_LOG_FORMAT=pretty gtc start ./my-bundle
SignalBehavior
SIGTERMGraceful shutdown
SIGINT (Ctrl+C)Graceful shutdown
SIGHUPReload configuration
VariableDescription
GREENTIC_HOSTBind address
GREENTIC_PORTHTTP port
GREENTIC_LOG_LEVELLog verbosity
GREENTIC_LOG_FORMATLog format (json/pretty)
GREENTIC_NATS_URLExternal NATS URL
GREENTIC_REDIS_URLRedis URL for sessions
Error: Address already in use (os error 48)

Another process is using port 8080. Either stop it or use a different port:

Terminal window
gtc start ./my-bundle --port 3000
Error: Failed to connect to NATS

If using external NATS, ensure it’s running and accessible. Otherwise, enable embedded:

Terminal window
gtc start ./my-bundle --nats on
Error: Failed to start cloudflared tunnel

Install cloudflared or use ngrok instead:

Terminal window
# Install cloudflared
brew install cloudflared
# Or use ngrok
gtc start ./my-bundle --cloudflared off --ngrok on
Error: Setup flow failed for messaging-telegram

Check your credentials in the answers file and ensure the public URL is accessible:

Terminal window
# Re-run setup
gtc start ./my-bundle --force-setup --verbose
Dockerfile
FROM rust:1.90 as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/gtc /usr/local/bin/
COPY my-bundle /app/bundle
WORKDIR /app
EXPOSE 8080
CMD ["gtc", "start", "/app/bundle", "--cloudflared", "off"]
Terminal window
docker build -t my-worker .
docker run -p 8080:8080 my-worker