Conduit
Conduit
Docsllms.txtHostingGitHubIntroduction

Getting Started

OverviewInstall ConduitMCP SetupYour First AppStart with AI

Learn

ArchitectureClient vs Admin APIConfiguration

Modules

OverviewAuthenticationAuthorizationDatabaseEmbeddingsStorageCommunicationsChatRouterFunctions

Guides

Next.js IntegrationReBAC Team ScopingGitOps State Export

Deployment

Deployment OverviewDocker ComposeKubernetes and HelmLocal from SourceContainer Images

Reference

CLI ReferenceClient APIAdmin APIgRPC SDKEnvironment VariablesMCP Tools

Resources

Migration v0.16 → v0.17Legacy DocumentationChangelogFAQGlossaryContributing

Embeddings

Text-to-vector generation, embedding configs, backfills, and text-in semantic search.

The embeddings module turns string fields into vectors and searches by query text. It does not own vector storage. Database owns Vector fields, vector indexes, capabilities, and raw-vector search. Client apps call authenticated POST /embeddings/search only.

Use cases

Search by meaning

Find articles or tickets from a natural-language query instead of keyword match

Keep vectors current

Generate embeddings on create/update and skip unchanged documents via source hashes

Backfill existing data

Queue a bounded onlyMissing backfill instead of scanning in the request thread

Operator canary

Run Admin text search against a scoped set before opening Client search

Fail-closed authz search

Authorization-enabled schemas still require an authenticated user or scope

Capabilities

  • Text-to-vector generation (OpenAI-compatible HTTPS provider)
  • Embedding configs (schema, source fields, target field)
  • Vector + source-hash schema extensions
  • Incremental jobs on database mutations
  • Queued backfills (onlyMissing, cancel, resume)
  • Text-in semantic search (Client + Admin)
  • Capability and status inspection
  • Convict enabled default false (workers and search)

Example: Config, backfill, then text search

Walkthrough

  1. Deploy the embeddings process with module convict enabled still false (compose --profile embeddings or Helm install.embeddings.enabled)
  2. Call get_embeddings_capabilities and confirm storage, indexing, and search for Atlas Vector Search or pgvector
  3. Patch the provider catalogue with patch_config_embeddings (endpoint, apiKey, models, defaultModel)
  4. Create an extendable, non-system schema (CMS enabled or cms unset) and post_embeddings_configs with enabled: false
  5. Wait until the target vector index is queryable (get_embeddings_status / get_embeddings_configs_id)
  6. Enable the config, then set convict enabled: true. Backfill, resume, and text search fail closed while convict enabled is false
  7. Start a bounded post_embeddings_backfills with onlyMissing: true
  8. App calls POST /embeddings/search with schemaName and text — never a raw vector, never caller-supplied userId, scope, or adminOperator
Client semantic search
curl -X POST http://localhost:3000/embeddings/search \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"schemaName":"Article","text":"how vector indexes become queryable","limit":10}'
Create config (disabled)
curl -X POST http://localhost:3030/embeddings/configs \
-H "Authorization: Bearer YOUR_ADMIN_JWT_OR_cdt_TOKEN" \
-H "Content-Type: application/json" \
-d '{"schemaName":"Article","sourceFields":["title","body"],"targetField":"embedding","enabled":false}'

How it works

Ownership

ConcernModuleSurface
Text → vector, configs, backfills, text-in searchEmbeddingsAdmin /embeddings/*, Client POST /embeddings/search
Vector fields, indexes, capabilities, raw-vector searchDatabaseSchema fields; Admin POST /database/schemas/:schemaName/vector-search

Embeddings adds a vector schema extension for targetField and a hidden source-hash field used to skip unchanged documents. Changing dimensions in place is rejected — create a new targetField and run an explicit backfill.

similarity is cosine (default), euclidean, or dotProduct. Changing similarity recreates the vector index. Changing sourceFields does not.

Two enablement flags

FlagDefaultEffect
Workload: compose --profile embeddings or Helm install.embeddings.enabledoffStarts or stops the embeddings process. Health can stay serving while workers are off so you can configure the module.
Convict enabledfalseStarts generation workers and mutation subscriptions. Backfill start, backfill resume, and text search fail closed while this is false. This is not the Helm flag.

Production containers require a non-empty GRPC_KEY.

Safe lifecycle

  1. Deploy the process disabled. docker compose --profile mongodb --profile embeddings up with a non-empty GRPC_KEY, or Helm install.embeddings.enabled=true. Leave convict enabled: false. Confirm the process is registered with Core.
  2. Inspect capabilities. get_embeddings_capabilities (or GET /embeddings/capabilities). Database storage, indexing, and search must be true for MongoDB Atlas Vector Search or Postgres pgvector. Saving a disabled config may succeed with capability warnings; activation must not.
  3. Configure the provider catalogue. patch_config_embeddings with endpoint, apiKey, and a models catalogue (name + dimensions). GRPC_KEY comes from the deployment, not from module settings.
  4. Create the config disabled. post_embeddings_configs with schemaName, sourceFields, targetField, and enabled: false. The first upsert provisions the vector index when Database indexing is available. If indexing is unavailable, status reports a manual index lifecycle warning — create the index before enabling.
  5. Wait for a queryable index. Poll get_embeddings_status / get_embeddings_configs_id until the index for targetField is ready (not pending or failed).
  6. Enable the config and the module. Set the config enabled: true, then patch_config_embeddings with convict enabled: true. Backfill, resume, and text search stay fail-closed until convict enabled is true.
  7. Bounded onlyMissing backfill. post_embeddings_backfills with onlyMissing: true and a bounded batchSize (capped by queue.maxBatchSize, default 500). Backfills persist BackfillRun state and never scan in the request thread. Cancel and resume from the stored cursor.
  8. Monitor. Watch get_embeddings_backfills_id counts (scanned / queued / processed / failed) and get_embeddings_status queue depths.
  9. Canary text search. Admin post_embeddings_search or Client POST /embeddings/search with a scoped query. Confirm authorization-enabled schemas fail closed without an authenticated user or scope.

Rollback: set convict enabled: false and per-config enabled: false (generation and search stop; vectors remain), then stop the workload (docker compose stop embeddings or Helm install.embeddings.enabled=false). Rollback retains vector fields, indexes, EmbeddingConfig documents, BackfillRun records, and Redis/BullMQ queue state. Data and index removal is a separate operator action.

Target schema

The schema must be:

  • CMS enabled or cms unset (conduit.cms.enabled true, or cms omitted)
  • Extendable (conduit.permissions.extendable: true)
  • Non-system — not Database internals (_DeclaredSchema, CustomEndpoints, …), not core/router/authorization-owned, not embeddings-owned (EmbeddingConfig, BackfillRun), not names starting with _, not auth secret schemas (AccessToken, RefreshToken, AdminApiToken, …)

Owner-controlled business schemas, including authentication User / Team, are allowed when they pass those checks.

Source fields

Each sourceFields entry must exist on the schema, be string-like (String or an array of strings), and use a valid field name. Hidden fields (select: false) and sensitive-looking names (password, secret, token, apiKey, …) are rejected unless they appear on security.sourceFieldAllowlist (or a platform-admin sourceFieldAllowlist on upsert). Caller-supplied allowlists are ignored for non-admin gRPC callers.

Backfill filter

Admin/MCP backfill filter is a document query, not a search query. Allowed: equality, comparisons ($eq, $ne, $gt, $gte, $lt, $lte), bounded $in/$nin, and $and. Rejected: regex, $or, $not, $like. Semantic-search filter does not use this allowlist — it is passed through as a Database vector-search filter.

Config deletion

delete_embeddings_configs_id removes the config document only. Vector fields and indexes stay on the schema until you delete them through Database.

Search split

CallerPathBodyIdentityLimit
Client appPOST /embeddings/searchRequired schemaName + text. Optional targetField, filter, limit.Router user / scope. Body must not include userId, scope, or adminOperator.Max 50
Admin / MCPpost_embeddings_searchSame body shape.Operator contextNot the Client cap
Database AdminPOST /database/schemas/:schemaName/vector-searchRaw vector arrayOperatorDatabase vector-search limits

Do not send a raw vector on either embeddings search path. Client search requires authMiddleware. Both embeddings search paths generate a query embedding, then delegate to Database vector search.

Configure

Two independent switches:

SwitchDefaultWhat it does
Helm install.embeddings.enabled / compose --profile embeddingsoffDeploys or removes the embeddings process. Does not start workers.
Module convict enabledfalseTurns on generation workers, mutation subscriptions, and search. Backfill start, backfill resume, and text search fail closed while this is false. Patch via MCP after the index is queryable.

Production images require a non-empty GRPC_KEY. Image tags and the compose profile are on Docker Compose.

Enable MCP with ?modules=embeddings, then patch via patch_config_embeddings:

KeyDefaultMeaning
enabledfalseWorkers, mutation subscriptions, and search
defaultProvideropenai-compatibleProvider id used when a config omits provider
providers.openai-compatible.endpoint""HTTPS embeddings endpoint
providers.openai-compatible.apiKey""Provider API key (sensitive)
providers.openai-compatible.models[]Catalogue of { name, dimensions }
providers.openai-compatible.defaultModel""Default model from the catalogue
queue.concurrency2Generation worker concurrency
queue.attempts3Generation retry attempts
queue.maxBatchSize500Max jobs accepted from one enqueue or backfill request
security.sourceFieldAllowlist[]Source fields allowed even when hidden or sensitive-named

provider, model, and dimensions on a config default from this catalogue when omitted. Provider output dimensions must match the configured vector dimensions.

similarity is cosine (default), euclidean, or dotProduct. Changing similarity recreates the vector index. Changing sourceFields does not.

Client API

Authenticated only (authMiddleware). User and scope come from the router context.

MethodPathBody
POST/embeddings/search{ schemaName, text, targetField?, filter?, limit? }
RuleDetail
VectorsDo not send a raw vector.
IdentityDo not send userId, scope, or adminOperator.
LimitPositive integer; Client max 50.
AuthzSearch requires an authenticated user or scope from context.

Configs, backfills, capabilities, and status are not Client routes.

Admin API

Operator routes on ADMIN_BASE_URL/embeddings/... (admin JWT or cdt_ token):

MethodPathPurpose
GET/embeddings/configsList configs (schemaName, id)
POST/embeddings/configsCreate or update a config
GET/embeddings/configs/:idGet one config
DELETE/embeddings/configs/:idDelete config — does not drop vector fields or indexes
GET/embeddings/capabilitiesDatabase vector storage, indexing, and search
GET/embeddings/statusReadiness, provider/index warnings, queue counts
GET/embeddings/backfillsList BackfillRun records
POST/embeddings/backfillsStart a queued backfill (onlyMissing, batchSize, configId, optional filter)
GET/embeddings/backfills/:idGet one backfill (counts, cursor, state)
POST/embeddings/backfills/:id/cancelCancel a queued or running run
POST/embeddings/backfills/:id/resumeResume from the stored cursor
POST/embeddings/searchOperator text-in search (no raw vectors)

Admin backfill filter allows equality, comparisons, bounded $in/$nin, and $and. It rejects regex, $or, $not, and $like. This subset applies to backfill only — semantic-search filter is a Database vector-search filter (JSON object), not that allowlist.

Database raw-vector search stays on Admin POST /database/schemas/:schemaName/vector-search.

MCP

Enable with ?modules=embeddings in your MCP server URL. Hermes converts every embeddings Admin route (none set mcp: false).

ToolPurpose
get_embeddings_configsList embedding configs
post_embeddings_configsCreate or update a config. First upsert provisions the vector index when Database indexing is available. Save enabled: false until the index is queryable.
get_embeddings_configs_idGet one config by id
delete_embeddings_configs_idDelete a config. Does not drop vector fields or indexes.
get_embeddings_capabilitiesVector storage, index, and search capabilities plus warnings
get_embeddings_statusModule readiness, provider/index warnings, generation and backfill queue counts
get_embeddings_backfillsList persisted backfill runs
post_embeddings_backfillsStart a queued cursor-based backfill. Prefer onlyMissing: true and a bounded batchSize. Optional filter uses the backfill allowlist (not the search filter).
get_embeddings_backfills_idGet one backfill run
post_embeddings_backfills_id_cancelCancel a queued or running backfill
post_embeddings_backfills_id_resumeResume a failed or canceled run from its cursor
post_embeddings_searchOperator semantic search by text
get_config_embeddingsRead module convict config
patch_config_embeddingsPatch module convict config (provider, enabled, queue)

That is 12 embedding route tools plus the two core-injected config tools.

Next steps

  • Database (Vector fields & indexes)
  • Docker Compose
  • Kubernetes / Helm
  • MCP setup
  • Client API

Database

Schemas, CRUD, custom endpoints, indexes, query trees, and GitOps export.

Storage

File uploads, cloud providers (S3, Azure, GCS), signed URLs, public access, folder markers, and Prometheus metrics.

On this page

Use casesCapabilitiesExample: Config, backfill, then text searchHow it worksConfigureClient APIAdmin APIMCP