Connecting to the Server

Describes how to connect to a running Cobalt CAPT server instance.

Once you have your CAPT server up and running, and have installed or generated the SDK for your project, you can connect to it by “dialing” a gRPC connection.

First, you need the address where the server is running: e.g. host:grpc_port. By default this is localhost:2727, and it is logged to the terminal when you start CAPT server as grpcAddr:

2026/09/10 03:57:51 info  {"msg":"server started","grpcAddr":"[::]:2727","httpApiAddr":"[::]:8080","httpOpsAddr":"[::]:8081"}

Default Connection

The following snippet connects to the server and queries its version, using an “insecure” gRPC channel. This would be the case if you have just started a local instance of CAPT server without TLS enabled.

import grpc
import cobaltspeech.capt.v1.capt_pb2 as capt
import cobaltspeech.capt.v1.capt_pb2_grpc as capt_grpc

serverAddress = "localhost:2727"

# Using a channel without TLS enabled.
channel = grpc.insecure_channel(serverAddress)
client = capt_grpc.CAPTServiceStub(channel)

# Get server version.
versionResp = client.Version(capt.VersionRequest())
print(versionResp)

# Get the list of models available on the server.
modelResp = client.ListModels(capt.ListModelsRequest())
for model in modelResp.models:
    print(model)
package main

import (
	"context"
	"fmt"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"

	captpb "github.com/your-org/your-module/gen/go/cobaltspeech/capt/v1"
)

func main() {
	const serverAddress = "localhost:2727"

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Using a channel without TLS enabled.
	conn, err := grpc.NewClient(serverAddress,
		grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		fmt.Printf("failed to dial gRPC connection: %v\n", err)
		os.Exit(1)
	}
	defer conn.Close()

	client := captpb.NewCAPTServiceClient(conn)

	// Get server version.
	versionResp, err := client.Version(ctx, &captpb.VersionRequest{})
	if err != nil {
		fmt.Printf("failed to get server version: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("%v\n", versionResp)

	// Get the list of models available on the server.
	modelResp, err := client.ListModels(ctx, &captpb.ListModelsRequest{})
	if err != nil {
		fmt.Printf("failed to list models: %v\n", err)
		os.Exit(1)
	}

	for _, m := range modelResp.GetModels() {
		fmt.Printf("%v\n", m)
	}
}

Connect with TLS

In our recommended setup for deployment, TLS is enabled in the gRPC connection, and clients validate the server’s SSL certificate to make sure they are talking to the right party. This is similar to how “https” connections work in web browsers.

TLS is enabled server-side by providing a certificate and key in capt-server.cfg.toml:

[server.grpc]
Address = ":2727"
CertFile = "capt-server.crt"
KeyFile = "capt-server.key"

The following snippets show how to connect to a CAPT server that has TLS enabled.

import grpc
import cobaltspeech.capt.v1.capt_pb2 as capt
import cobaltspeech.capt.v1.capt_pb2_grpc as capt_grpc

serverAddress = "capt.your-org.internal:2727"

# Setup a gRPC connection with TLS. You can optionally provide your own
# root certificates and private key to grpc.ssl_channel_credentials()
# for mutually authenticated TLS.
creds = grpc.ssl_channel_credentials()
channel = grpc.secure_channel(serverAddress, creds)
client = capt_grpc.CAPTServiceStub(channel)

# Get server version.
versionResp = client.Version(capt.VersionRequest())
print(versionResp)
package main

import (
	"context"
	"crypto/tls"
	"fmt"
	"os"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"

	captpb "github.com/your-org/your-module/gen/go/cobaltspeech/capt/v1"
)

func main() {
	const serverAddress = "capt.your-org.internal:2727"

	// Setup a gRPC connection with TLS. You can optionally provide your own
	// root certificates and private key through tls.Config for mutually
	// authenticated TLS.
	tlsCfg := tls.Config{}
	creds := credentials.NewTLS(&tlsCfg)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	conn, err := grpc.NewClient(serverAddress, grpc.WithTransportCredentials(creds))
	if err != nil {
		fmt.Printf("failed to dial gRPC connection: %v\n", err)
		os.Exit(1)
	}
	defer conn.Close()

	client := captpb.NewCAPTServiceClient(conn)

	versionResp, err := client.Version(ctx, &captpb.VersionRequest{})
	if err != nil {
		fmt.Printf("failed to get server version: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("%v\n", versionResp)
}

Client Authentication

In some setups it is desirable for the server to validate the clients connecting to it, and only respond to ones it can verify. If your CAPT server is configured to do client authentication, you will need to present the appropriate certificate and key when connecting to it.

Note that in client-authentication mode the client still also verifies the server’s certificate, so this setup uses mutually authenticated TLS.

creds = grpc.ssl_channel_credentials(
  root_certificates=root_certificates,  # PEM certificate as byte string
  private_key=private_key,              # PEM client key as byte string
  certificate_chain=certificate_chain,  # PEM client certificate as byte string
)
// Root PEM certificate for validating a self-signed server certificate.
var rootCert []byte

// Client PEM certificate and private key.
var certPem, keyPem []byte

caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(rootCert); !ok {
	fmt.Printf("unable to use given caCert\n")
	os.Exit(1)
}

clientCert, err := tls.X509KeyPair(certPem, keyPem)
if err != nil {
	fmt.Printf("unable to use given client certificate and key: %v\n", err)
	os.Exit(1)
}

tlsCfg := tls.Config{
	RootCAs:      caCertPool,
	Certificates: []tls.Certificate{clientCert},
}

creds := credentials.NewTLS(&tlsCfg)