Skip to content
Conduit

mcp server

tock-mcp-server

MCP server over Tock web connectors.

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 23, 2026

tock-mcp-server

MCP server for T.O.C.K. web-connector

flowchart LR
        
    subgraph T.O.C.K.
        web_connector_One[Web Connector for bot One]
        web_connector_Two[Web Connector for bot Two]
    end
    MCP_Server_One[T.O.C.K. MCP Server]
    MCP_Server_Two[T.O.C.K. MCP Server]
    AI_Client_One[Agent / Copilot / AI Client]

    AI_Client_One --> MCP_Server_One
    AI_Client_One --> MCP_Server_Two
    MCP_Server_One --> web_connector_One
    MCP_Server_Two --> web_connector_Two

Building the server

make build-servers

Running the server

make run-tock-mcp

Endpoints

MethodPathDescription
POST/mcpJSON-RPC (stateless, used by most MCP clients)
GET/mcpSSE stream (server-sent events, used by streaming-capable clients)
GET/healthHealth check — returns {"status":"ok"}

Both transports support all standard MCP methods including ping, initialize, and tools/call.

Configuration

The server expects a YAML configuration file with the following structure:

tock:
  # Base URL of the Tock instance (no trailing slash)
  base_url: "https://<bot-api-host>"
  # Tock namespace
  namespace: "app"
  # Bot name
  bot: "howtonet"
  # Web-connector identifier
  connector: "web"
  # User ID sent to Tock with every request
  user_id: "mcp-user-001"
  # Optional extra HTTP headers forwarded to the Tock web-connector.
  # The value is the default used when the MCP caller does not provide one.
  # Leave empty ("") to make the header optional with no default.
  # extra_headers:
  #  X-Toki-Origin: "github-copilot"   # always sent; can be overridden by the caller
  #  X-Toki-Filter: ""                 # no default — provided by the caller if needed

server:
  # HTTP listen address of the MCP server
  addr: ":8083"
  # Name of the MCP tool exposed to AI clients.
  # Defaults to "ask_tock" if empty or omitted.
  tool_name: "ask_tock"
  # Description of the MCP tool shown to AI clients.
  # This text helps the AI decide when and how to call the tool.
  # Defaults to a built-in description if empty or omitted.
  tool_description: "Ask a question to the Tock documentary chatbot (RAG). Returns the text response and links to source documents."
  # Description of the "question" parameter expected by the tool.
  # This text guides the AI on what information to include in the question for better answers.
  input_question_description: "Question about Tock. Include context, error messages, version, environment or goal if available."
  # HTTP server timeouts (Go duration format: "5s", "1m30s", …).
  # All fields are optional — the values below are the defaults.
  # read_header_timeout: "5s"
  # read_timeout: "15s"
  # write_timeout: "30s"
  # idle_timeout: "60s"
  # shutdown_timeout: "10s"

# OAuth 2.1 Resource Server (optional).
# When enabled, every request to /mcp must carry a valid Bearer token.
# The /health endpoint is never protected.
oauth:
  enabled: false
  # Token issuer (iss claim). Also used for OIDC Discovery when jwks_url is empty.
  # Example: "https://auth.example.com/realms/my-realm"
  issuer: ""
  # Explicit JWKS endpoint URL.
  # If empty, the server derives it automatically via OIDC Discovery ({issuer}/.well-known/openid-configuration).
  # Example: "https://auth.example.com/realms/my-realm/protocol/openid-connect/certs"
  jwks_url: ""
  # Expected audience (aud claim). Leave empty to skip audience verification.
  audience: ""
  # Scopes that must be present in the token's "scope" claim.
  # Leave empty to skip scope verification.
  required_scopes: []

Tip: Customise tool_name and tool_description to match the domain of your Tock bot so that AI assistants can better decide when to invoke the tool.

Server timeouts reference

KeyDefaultDescription
server.read_header_timeout5sMaximum time to read request headers
server.read_timeout15sMaximum time to read the full request body
server.write_timeout30sMaximum time to write the response
server.idle_timeout60sMaximum keep-alive idle time between requests
server.shutdown_timeout10sGraceful shutdown deadline for in-flight requests

All timeouts accept the Go duration format: "5s", "1m", "1m30s", etc.

OAuth 2.1 reference

KeyDefaultDescription
oauth.enabledfalseEnable Bearer token validation on /mcp
oauth.issuer""Expected iss claim; used for OIDC Discovery when jwks_url is empty
oauth.jwks_url""Explicit JWKS endpoint URL (overrides OIDC Discovery)
oauth.audience""Expected aud claim — leave empty to skip
oauth.required_scopes[]Scopes that must appear in the token's scope claim

Environment variable equivalents (override any file value):

TOCK_MCP_OAUTH_ENABLED=true
TOCK_MCP_OAUTH_ISSUER=https://auth.example.com/realms/my-realm
TOCK_MCP_OAUTH_JWKS_URL=https://auth.example.com/realms/my-realm/protocol/openid-connect/certs
TOCK_MCP_OAUTH_AUDIENCE=tock-mcp-server
TOCK_MCP_OAUTH_REQUIRED_SCOPES=read,write

Docker image (scratch)

The image is built with a scratch runtime and expects a configuration file available at /config/config.yaml.

config.yaml

tock:
  # Base URL of the Tock instance (no trailing slash)
  base_url: "https://<bot-api-endpoint>"
  # Tock namespace
  namespace: "app"
  # Bot name
  bot: "howtonet"
  # Web-connector identifier
  connector: "web"
  # User ID sent to Tock with every request
  user_id: "mcp-user-001"

server:
  # HTTP listen address of the MCP server
  addr: ":8083"
  # Name and description of the MCP tool (optional — defaults shown below)
  tool_name: "ask_tock"
  tool_description: "Ask a question to the Tock documentary chatbot (RAG). Returns the text response and links to source documents."
  input_question_description: "Question about Tock. Include context, error messages, version, environment or goal if available."
  # HTTP timeouts are optional — uncomment to override defaults
  # read_header_timeout: "5s"
  # read_timeout: "15s"
  # write_timeout: "30s"
  # idle_timeout: "60s"
  # shutdown_timeout: "10s"

# OAuth 2.1 — optional, disabled by default
# oauth:
#   enabled: true
#   issuer: "https://auth.example.com/realms/my-realm"
#   audience: "tock-mcp-server"
#   required_scopes: []
docker run --rm -p 8083:8083 \
  -v "$(pwd)/config.yaml:/config/config.yaml:ro" \
  ghcr.io/theopenconversationkit/tock-mcp-server:v0.5.0

Build locally:

docker build -t tock-mcp-server:local .

Run locally with a mounted config file:

docker run --rm -p 8083:8083 \
  -v "$(pwd)/config.yaml:/config/config.yaml:ro" \
  tock-mcp-server:local

Deploying on Kubernetes (ConfigMap)

with manifest

The container does not embed config.yaml, so each environment can mount its own ConfigMap.

Use the provided manifest:

kubectl apply -f k8s/tock-mcp-server.yaml

Example (extract):

apiVersion: v1
kind: ConfigMap
metadata:
  name: tock-mcp-config
data:
  config.yaml: |
    tock:
      base_url: "https://demo.tock.ai"
      namespace: "app"
      bot: "howtonet"
      connector: "howtonetweb"
      user_id: "mcp-user-001"
    server:
      addr: ":8083"
      tool_name: "ask_tock"
      tool_description: "Ask a question to the Tock documentary chatbot (RAG). Returns the text response and links to source documents."
      input_question_description: "Question about Tock. Include context, error messages, version, environment or goal if available."
      # read_header_timeout: "5s"
      # read_timeout: "15s"
      # write_timeout: "30s"
      # idle_timeout: "60s"
      # shutdown_timeout: "10s"
    # oauth:
    #   enabled: true
    #   issuer: "https://auth.example.com/realms/my-realm"
    #   audience: "tock-mcp-server"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tock-mcp-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tock-mcp-server
  template:
    metadata:
      labels:
        app: tock-mcp-server
    spec:
      containers:
        - name: tock-mcp-server
          image: ghcr.io/theopenconversationkit/tock-mcp-server:v0.7.1
          args: ["-config", "/config/config.yaml", "-addr", ":8083"]
          volumeMounts:
            - name: config
              mountPath: /config
              readOnly: true
      volumes:
        - name: config
          configMap:
            name: tock-mcp-config

With Helm chart

The Helm chart is published to the GHCR OCI registry on every version tag and is also available locally in k8s/chart/.

Install from the OCI registry (recommended):

helm install tock-mcp oci://ghcr.io/theopenconversationkit/charts/tock-mcp-server \
  --version <version> -f values.yaml

Install from local source:

helm install tock-mcp ./k8s/chart -f values.yaml
config:
  tock:
    base_url: "https://tock.my-company.com"
    namespace: "app"
    bot: "my-bot"
    connector: "web"
    user_id: "mcp-prod"
  server:
    tool_name: "ask_tock"
    tool_description: "Ask a question to the Tock documentary chatbot (RAG). Returns the text response and links to source documents."
    input_question_description: "Question about Tock. Include context, error messages, version, environment or goal if available."
    # read_header_timeout: "5s"
    # read_timeout: "15s"
    # write_timeout: "30s"
    # idle_timeout: "60s"
    # shutdown_timeout: "10s"
  # oauth:
  #   enabled: true
  #   issuer: "https://auth.example.com/realms/my-realm"
  #   audience: "tock-mcp-server"

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: tock-mcp.my-company.com
      paths:
        - path: /mcp
          pathType: Prefix
  tls:
    - secretName: tock-mcp-tls
      hosts:
        - tock-mcp.my-company.com
↑↓ navigate openesc close