SWIRLS_
Connections

Project Networks

Declare private connectivity boundaries, expose selected project interfaces, and identify outbound consumers that need a tailnet route.

What it is. A named, provider-neutral private connectivity boundary for a project. A project can declare multiple networks, and each network can later bind to a Swirls-managed or customer-owned tailnet.

Use it when customers need to reach a Swirls app, form, webhook, MCP channel, or database without publishing it to the public internet—or when a Swirls workflow or agent must call an on-prem or tailnet-only service.

Project Networks separate two decisions:

  • The network block owns what Swirls exposes into that private network.
  • Each outbound consumer chooses the network it reaches through with network: <name>.

Declare a network

network corporate {
  label: "Corporate network"
  description: "Private operations and internal systems"

  expose: {
    apps: [operations]
    channels: [support_mcp]
    forms: [employee_intake]
    webhooks: [internal_events]
    databases: [
      {
        database: crm
        connections: [application, analytics]
      }
    ]
  }
}

label, description, and the entire expose block are optional. An empty network is useful when the project only needs outbound access.

ExposureWhat the name refers to
appsTop-level app blocks
channelsmcp, web, or swirls channel blocks with a Swirls-hosted interface
formsTop-level form blocks
webhooksTop-level webhook blocks
databasesA managed database plus the exact nested named connections to expose
servicesReserved for the service primitive; currently rejected by validation

Database exposure is connection-granular on purpose. The network does not expose a database merely because the database exists; you must select the exact named credentials intended for that boundary.

Reach private services

Set network: on the consumer that owns the destination:

node fetch_customer {
  type: http
  url: "https://crm.internal/api/customer"
  network: corporate
}

mcp operations_tools {
  url: "https://mcp.internal/mcp"
  auth: static
  network: corporate
}

postgres warehouse {
  connection: WAREHOUSE_DATABASE_URL
  network: corporate

  table events {
    schema: @json { { "type": "object" } }
  }
}

Self-managed connection blocks also accept network: when they declare base_url: and auth:. Managed OAuth connections do not: their provider transport remains Swirls-managed.

A network-aware HTTP node must use a static absolute http or https URL. A dynamic @ts URL is rejected because Swirls must know the destination before it selects a private route.

Cloud inventory and bindings

After deployment, the project's Networks page shows every named declaration, the interfaces it exposes, and the outbound resources that consume it. This makes the private connectivity contract reviewable before infrastructure is attached.

Named tailnet bindings and live execution gateways are the next control-plane milestone. Until a network is bound, network-aware consumers fail closed with an explicit error and never fall back to the public internet.

Multiple networks

Declare as many networks as the project needs. For example, corporate might connect employee systems while customer_acme reaches a customer's tailnet. An interface or consumer is attached only where it is named, which keeps boundaries explicit in source review.

On this page