Skip to content

MCP for LLMs

Wick speaks the Model Context Protocol so any MCP-aware LLM client — Claude.ai, Claude Desktop, Cursor, custom agents — can call your connectors with structured input and output. There is no glue code on your side: register a connector, generate a token, paste a URL.

Why MCP

Traditional REST integrations require the LLM (or the prompt author) to know URLs, headers, and response shapes upfront. MCP standardizes the discovery + invocation handshake so the LLM negotiates capabilities at runtime: the server advertises a tool list and JSON Schema; the client picks a tool, supplies typed arguments, and receives a typed response. Auth is bearer-token only — no per-request signing dance.

Wick layers two more wins on top:

  • Per-call audit — every invocation writes a row to connector_runs with input, output, latency, IP, and user. See the history page on a connector row.
  • Tag-filtered visibility — a user only sees connector rows whose tags match. Sharing a row across teammates is /admin/users + /admin/connectors work, not code.

Endpoint

POST /mcp                                   JSON-RPC 2.0 over Streamable HTTP
GET  /.well-known/oauth-protected-resource  RFC 9728 metadata
GET  /.well-known/oauth-authorization-server RFC 8414 metadata

POST /mcp accepts both JSON and Streamable HTTP responses:

Request AcceptResponseUse case
application/json (default)Single JSON-RPC frame90% of tool calls
text/event-streamSSE — notifications/progress frames + final resultLong-running ops with progress events

Heartbeat :keepalive frames every 15 seconds keep reverse proxies from reaping idle SSE connections.

Meta-tool pattern

Wick does not advertise N×M static tools (one entry per connector × operation). It advertises a fixed set of meta-tools:

ToolAnnotationPurpose
wick_listreadOnlyHintList every connector instance and connected OAuth account visible to the caller. Each entry has id, connector (label), description, total_tools, status, kind, and parent_id. Pass session_id to also include this session's workspace connectors (sw_… entries) and a session_config_bases array (connectors that can be cloned into a session workspace but haven't been added yet).
wick_searchreadOnlyHintSubstring search over label, name, description. Pass session_id to also match this session's workspace connectors.
wick_getreadOnlyHintDrill into a connector one level at a time via an optional selector argument. Pass only id to list the connector's categories; add selector=<category title> to list that category's operations (no schemas yet); add selector=<op key> to get that one op's input_schema. Flat connectors with no named categories skip straight to listing ops. For session-workspace connectors (sw_… id), also pass session_id as a separate argument.
wick_executedestructiveHintRun an operation by tool_id + params, or run a batch of operations in one call by passing a calls array. See Batch execution. Composite tool IDs (conn:…/op@accountID) inject the account token automatically.
wick_inforeadOnlyHintReturn server version and build info
wick_encryptreadOnlyHintRedirect to the in-app encrypt UI — no crypto over MCP. See Encrypted credentials
wick_decryptreadOnlyHintRedirect to the in-app decrypt UI — no crypto over MCP
wick_session_inforeadOnlyHintRead the active session's metadata: session_id, title, title_custom, origin, status, project_id. Used by the agent to decide whether to set a title.
wick_set_titleidempotentHintSet the session's sidebar title and mark it as custom so the auto-derived first-message label never overwrites it. Title is truncated to 60 characters.
wick_session_workspaceSpin up throwaway connector instances scoped to one session (clone a base connector, point it at staging, use a different key). The agent creates blank instances; the user fills the config in a UI form; the agent never sees the values. Instances appear in wick_list for that session only and die with it. See Session workspace.

The selector argument accepts either a category title (from a prior id-only response) or an op key (from a category listing). The category and op_key argument names are accepted as aliases for selector — use whichever reads naturally in your tool call. An unknown selector returns an error listing what to try instead.

Why not a static list?

  • Dynamic instances — adding or removing a connector row in the admin UI must not invalidate the LLM client's cached tool list. With a small fixed set of meta-tools, the cache is always valid.
  • Token economywick_list does not return per-op input_schema. The LLM only pays the schema cost when it commits to calling a specific op via wick_get.
  • Scale — a server with hundreds of connectors still has a compact tools/list response.

Wick Manager top-level tools

The Wick Manager connector is a special case. Its operations are surfaced directly in tools/list as wick_manager_<op> tools — for example wick_manager_app_list, wick_manager_job_run_now, wick_manager_connector_list. The LLM can call them without the wick_listwick_getwick_execute discovery cycle.

wick_manager_app_list          → list all app-level configuration variables
wick_manager_job_run_now       → trigger an out-of-cycle job run
wick_manager_connector_list    → list connector instances visible to the caller
… (one entry per enabled wickmanager op)

Because these tools appear directly, wickmanager is excluded from wick_list and wick_search to avoid double-exposure.

Visibility follows the same rules as every other connector: the caller only sees wick_manager_* tools when the wickmanager row is visible to their user (tag match or admin). Per-op access gates are unchanged — each call routes through wick_execute internally and re-validates the per-op enable state.

The wick_manager_* tools work over both the stdio transport and the Streamable HTTP/SSE transport.

Tool ID format

Standard (connector-level):

conn:{connector_id}/{op_key}

Account-scoped (personal OAuth identity):

conn:{connector_id}/{op_key}@{account_id}

UUID-based, opaque, stable across admin label renames. The conn: prefix is reserved for future module classes (e.g. prompt: for prompt templates). When wick_get is called with a composite connectorID/accountID id (from a kind="account" entry in wick_list), the returned tool_id values in the op listing and schema levels carry the @accountID suffix. Passing such a tool_id to wick_execute automatically injects that account's OAuth token and enforces its per-account disabled-op list.

Typical LLM flow

The three wick_get levels keep the LLM's context from ballooning — only the final level carries an input_schema:

# Level 1 — category list (no ops, no schemas)
wick_get({id: "conn-uuid"})
→ { categories: [{ category, description, total_tools }, …] }

# Level 2 — op list for one category (no schemas)
wick_get({id: "conn-uuid", selector: "Calendar"})
→ { tools: [{ tool_id, name, description, destructive }, …] }

# Level 3 — single op with schema
wick_get({id: "conn-uuid", selector: "calendar_create_event"})
→ { tools: [{ tool_id, name, description, destructive, input_schema }] }

For a flat connector with no named categories, level 1 falls through to an op list directly — skip straight to level 3 with an op key.

Shortcut when the LLM already knows the op key (e.g. from a prior wick_search hit):

wick_search({query: "loki query"})                             → matched tool_id
wick_get({id: "conn-uuid", selector: "loki_query_range"})      → input_schema
wick_execute({tool_id, params: {...}})                          → result

Multi-identity: connector vs account

wick_list returns two kinds of entries:

kindid formatWhat it represents
"connector"{connectorID}The shared instance — bot token, API key, or service account
"account"{connectorID}/{accountID}A personal OAuth account connected to that instance

When multiple users have connected personal accounts to one instance, the LLM sees one "connector" entry (shared identity) plus one "account" entry per user. Use kind to decide which identity to run as: "connector" for shared/bot credentials, "account" for personal identity. Pass the composite id to wick_get to get account-scoped tool_id values, then call wick_execute as usual — the server injects the right token automatically.

Auth check on every call

wick_execute and wick_get re-validate IsVisibleTo(connector_id, user_tag_ids, is_admin) on every call — they never trust a list-time cache. The connector_operations enable state is also re-checked. Removing a user's tag or disabling an op takes effect on the very next call.

Batch execution

wick_execute accepts either a single tool call or a batch in one round-trip. Pass a calls array instead of tool_id/params at the top level:

json
{
  "calls": [
    { "tool_id": "conn:uuid/op_a", "params": { "x": 1 } },
    { "tool_id": "conn:uuid/op_b", "params": { "y": 2 } },
    { "tool_id": "conn:uuid/op_c", "params": {}, "session_id": "sw_..." }
  ],
  "timeout_ms": 60000
}

Calls run in parallel, independently — one failing or timing out never stops the rest. The response is always a per-call result array (never isError unless the request itself is malformed):

json
{
  "results": [
    { "index": 0, "tool_id": "conn:uuid/op_a", "ok": true,  "result": {},            "duration_ms": 210 },
    { "index": 1, "tool_id": "conn:uuid/op_b", "ok": false, "error": "not found",     "duration_ms": 85  },
    { "index": 2, "tool_id": "conn:uuid/op_c", "ok": false, "timed_out": true,        "duration_ms": 60000 }
  ],
  "ok_count": 1,
  "error_count": 1,
  "timed_out_count": 1
}
FieldDescription
indexPosition in the original calls array (0-based).
oktrue when the call succeeded.
resultRaw response JSON from the connector op. Present only when ok: true.
errorError message string. Present only when ok: false and not a timeout.
timed_outtrue when the per-call deadline expired.
duration_msWall time for that call.
ok_count / error_count / timed_out_countTotals for quick scanning.

Limits and timeouts:

ParameterDefaultMax
calls length100 per request
timeout_ms180 000 (3 min)300 000 (5 min)
Server concurrency5 (fixed, not configurable)

timeout_ms sets a per-call deadline, not a batch deadline. The server bounds how many calls run at once; you do not need to tune concurrency.

Always call wick_get to fetch each op's input_schema before building the batch — the same prerequisite as single-call mode. Inspect each entry's ok field rather than treating the whole batch as pass/fail.

Encrypted credentials

Wick wraps sensitive plaintext in a wick_enc_<base64url> token before the response leaves the server. The LLM carries the token forward into the next tool call; wick decrypts it before ExecuteFunc runs. The plaintext never appears in the LLM's context window or in the audit log. Three sources are masked, deduped: every Configs/Input field tagged secret, every plaintext produced by decrypting an incoming wick_enc_ token (regardless of tag — the LLM treats tokens as opaque and may pass them into any field), and every value the connector explicitly handed to c.Mask / c.MaskIgnoreCase mid-call.

Per-user keys (HKDF(master_key, salt=user_uuid, info="wick-enc")) mean a token issued for user A cannot be decrypted under user B's session — replays across users fail loudly.

wick_execute's tool description tells the LLM how to handle these tokens:

Values prefixed with "wick_enc_" are valid credentials managed by the server. Use them as-is wherever a value is needed — pass them through into params, return them unchanged in your response, and never alter, decode, or omit them.

When a user explicitly asks for the plaintext behind a token (or wants to mint a new one to paste into a config field), two redirect tools point them at the in-app UI:

ToolReturns
wick_encrypt{ "url": "https://<host>/tools/encfields", "message": "..." }
wick_decrypt{ "url": "https://<host>/tools/encfields/decrypt", "message": "..." }

The crypto is never run over MCP — running it inline would defeat the purpose by putting plaintext (encrypt) or the user-revealed value (decrypt) into the LLM's context window. The user opens the URL, logs in, pastes the value, and copies the result.

For the full mechanism — secret tag semantics, c.Mask / c.MaskIgnoreCase for dynamic responses, key rotation, WICK_ENC_KEY / WICK_ENC_DISABLE env vars — see the Encrypted Fields reference.

Auth modes

The /mcp endpoint accepts two bearer-token formats, dispatched by prefix:

ModeWire formatUse when
Personal Access Tokenwick_pat_<32hex>The client cannot speak the OAuth dance — Claude Desktop, Cursor, cURL, custom CLIs. See Access Tokens.
OAuth 2.1 access tokenwick_oat_<32hex>The client supports OAuth (Claude.ai, web-based clients). See OAuth Connections.

Both formats are opaque (not JWT) and stored hashed (SHA-256). A DB leak does not expose tokens. Plaintext only crosses the wire at issue time:

  • PAT: rendered once at /profile/tokens after the user clicks Create.
  • OAuth: returned in the /oauth/token response body to the client.

Install snippets

MCP install page

/profile/mcp install snippets — OAuth section + Bearer section with all 4 ready-to-paste snippets.

The in-app /profile/mcp page shows the URL and four install snippets ready to copy. Below is the same content for reference.

Claude.ai (OAuth)

Paste this URL into Claude.ai's MCP server settings:

https://<your-wick-host>/mcp

Claude.ai will:

  1. POST /oauth/register to obtain a client_id (Dynamic Client Registration, RFC 7591 — no pre-shared secret).
  2. Redirect the browser through /oauth/authorize for consent.
  3. Exchange the code at /oauth/token for an access + refresh token.
  4. Cache the tokens; refresh on its own as needed.

If the user is not logged in to wick when the redirect lands, wick captures the destination, bounces through /auth/login (password or Google SSO), then resumes the consent flow.

Claude Desktop / Cursor / VSCode (Bearer)

Generate a Personal Access Token at /profile/tokens, then paste it into the client config.

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

json
{
  "mcpServers": {
    "wick": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://<your-wick-host>/mcp",
               "--header", "Authorization: Bearer ${WICK_PAT}"],
      "env": {
        "WICK_PAT": "wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

Cursor (~/.cursor/mcp.json):

json
{
  "mcpServers": {
    "wick": {
      "url": "https://<your-wick-host>/mcp",
      "headers": {
        "Authorization": "Bearer wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

VSCode (settings.json):

json
{
  "mcp.servers": {
    "wick": {
      "url": "https://<your-wick-host>/mcp",
      "headers": {
        "Authorization": "Bearer wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

cURL

bash
curl -X POST https://<your-wick-host>/mcp \
  -H "Authorization: Bearer wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

Expect a response containing the wick_* meta-tools (plus any wick_manager_* tools if the wickmanager connector is visible to your token's user). Then call wick_list to enumerate the connector rows visible to your token's user.

bash
curl -X POST https://<your-wick-host>/mcp \
  -H "Authorization: Bearer wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","id":2,
       "params":{"name":"wick_list","arguments":{}}}'

Local MCP (stdio)

Wick ships a built-in stdio transport so any MCP client that spawns a child process — Claude Desktop, Cursor, Gemini CLI, Codex CLI, Claude Code — can connect directly to your local project without a hosted server or PAT.

The local server runs as a synthetic local admin: all connectors are visible, no auth middleware, no token required.

Commands

wick mcp serve

Starts the MCP JSON-RPC server over stdin/stdout. Normally invoked automatically by the client; you rarely run this by hand.

wick mcp serve [--mode auto|dev|build|rebuild]
FlagDefaultDescription
--modeautoBuild mode (see table below)
--project(cwd)Project root — set automatically by mcp install, not needed when running from the project dir

Build modes:

ModeBehavior
autoRebuild only when HEAD commit changed or any .go file is newer than binary
devgo run . — always recompiles; no binary cache. Good while actively developing connectors
buildBuild once if binary missing, reuse otherwise
rebuildAlways force a full rebuild

wick mcp config

Print the ready-to-paste mcpServers JSON snippet for any client, plus show config file locations for all supported clients.

wick mcp config [--name <server-name>] [--mode auto|dev|build|rebuild]

wick mcp install

Write the mcpServers entry directly into the target client's config file.

wick mcp install [--client <target>] [--name <server-name>] [--mode auto|dev|build|rebuild]
--clientConfig file written
claudeClaude Desktop — claude_desktop_config.json
cursorCursor IDE — settings.json
geminiGemini CLI — ~/.gemini/settings.json
codexCodex CLI — ~/.codex/config.toml
claude-codeClaude Code — ~/.claude.json
allAll five targets

Default --client is claude.

Wiring Claude Code

From the project root:

sh
wick mcp install --client claude-code
# ✓ Claude Code
#   ~/.claude.json

Or for dev mode (always recompiles — no stale binary surprises):

sh
wick mcp install --client claude-code --mode dev

The merged entry inside ~/.claude.json:

json
{
  "mcpServers": {
    "myproject": {
      "command": "go",
      "args": ["run", ".", "mcp", "serve"],
      "cwd": "/path/to/myproject"
    }
  }
}

For auto / build / rebuild modes the entry uses the compiled wick binary with --project so the client can spawn it from any working directory:

json
{
  "mcpServers": {
    "myproject": {
      "command": "/path/to/wick",
      "args": ["mcp", "serve", "--mode", "auto", "--project", "/path/to/myproject"]
    }
  }
}

After saving, restart Claude Code (or reload MCP servers via /mcp). The wick_* meta-tools appear in Claude Code's tool list with no token required.

Workflow & agent access (loopback)

When a workflow agent node (or a chat agent) spawns Claude as a subprocess, wick points it at the already-running MCP server over loopback (http://127.0.0.1:<PORT>/mcp) so it can use connectors without cold-starting a separate stdio mcp serve per run. This is automatic — no PAT, no manual config:

  • wick mints a random per-boot internal token (in-memory) and injects it into the spawned agent's MCP config as the Authorization: Bearer … header.
  • The agent connects over the full MCP Streamable HTTP transport: POST /mcp (JSON-RPC), GET /mcp (the server→client SSE channel), DELETE /mcp (teardown).
  • By default the wick server merges with the user's own MCP servers (~/.claude.json, .mcp.json) — set WICK_STRICT_MCP to isolate, or WICK_DISABLE_SHARED_MCP to turn the loopback injection off entirely (falling back to the user's stdio config).

If a spawned agent reports MCP servers are still connecting: wick and the wick_* tools never register, the loopback handshake isn't completing — confirm the server build is current and that GET /mcp returns 200 (a streaming text/event-stream), not 404/500.

End-to-end test from a fresh project

  1. Register a connector — the scaffolded template ships connectors/crudcrud/. Confirm it's registered in main.go.
  2. Boot: wick dev. Wick auto-seeds one row at /manager/connectors/crudcrud.
  3. Fill credentials. For crudcrud, claim a sandbox URL at https://crudcrud.com and paste it into the row's BaseURL field.
  4. Smoke test in-browser. Open the row, click [Test] next to any operation, run, verify the result panel.
  5. Generate a PAT. Visit /profile/tokens, click Create, copy the token from the render-once banner.
  6. Wire up Claude Desktop. Drop the snippet above into claude_desktop_config.json, restart Claude Desktop.

Claude Desktop tool permissions for wick

Claude Desktop Tools dialog showing the 4 wick_* tools registered after wiring a PAT.

  1. Try it. Ask Claude: "Use wick_list to see what connectors are available, then use wick_execute to list documents from the books resource on crudcrud."

Sessions

The Mcp-Session-Id header is generated on the first initialize call and held in-memory only — no DB row. On server restart, sessions are dropped; clients re-initialize and receive a fresh ID transparently. Auth (PAT or OAuth) is the load-bearing identity binding; the session ID is just a protocol marker.

Streaming

Default response is Content-Type: application/json — single round-trip. Wick switches to Content-Type: text/event-stream when:

  • The client requested it via Accept: text/event-stream.
  • The connector calls c.ReportProgress(...) mid-execution.

Server-initiated push (GET /mcp) is not currently used. The tool list only changes when connector rows are added/removed in the admin UI; clients can re-fetch tools/list on demand, so notifications/tools/list_changed is not emitted.

Audit trail

Every MCP tools/call writes a row to connector_runs with:

  • connector_id, operation_key, user_id
  • source = "mcp" (vs "test" for the in-app panel, "retry" for prefill replays)
  • Request and response JSON (truncatable)
  • status, error_msg, latency_ms, http_status
  • Caller IP and User-Agent
  • parent_run_id for retry lineage

The data backs the history page on each connector row. Retention is enforced by the Connector Runs Purge job — default 7 days.

wick_info

Returns the running server's version and build metadata. Useful for verifying which wick version is active without leaving the LLM context.

bash
curl -X POST https://<your-wick-host>/mcp \
  -H "Authorization: Bearer wick_pat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","id":3,
       "params":{"name":"wick_info","arguments":{}}}'

Response:

json
{
  "wick_version": "v0.4.1",
  "server_build_time": "2026-05-02T10:03:30Z",
  "server_commit": "924efec"
}
FieldDescription
wick_versionWick framework version — from the VERSION file at build time, or from the embedded Go module info when wick is used as a library dependency
server_build_timeWhen this server binary was compiled (RFC 3339 UTC)
server_commitShort git commit hash of the server binary at build time

wick_version is injected automatically by wick mcp serve — no ldflags needed in downstream projects. When wick is imported as a library (require github.com/yogasw/wick v1.x.x), the version is read from Go's embedded module build info at startup.

Session title tools

The wick-agent server exposes two tools that let the agent manage the session's sidebar title without touching the admin UI.

wick_session_info

Read-only. Returns the active session's metadata.

FieldTypeDescription
session_idstringSession identifier
titlestringCurrent sidebar title (empty string until first message arrives)
title_custombooltrue when the title was set explicitly (by a human or by wick_set_title); false when it is still the auto-derived first-message label
originstringChannel origin, e.g. slack, web, rest
statusstringSession status, e.g. idle, busy
project_idstringProject the session belongs to, if any

wick_set_title

Writes an explicit title to session.meta.label and sets title_custom = true. Once set, the auto-derived first-message label is permanently skipped for this session — even after a restart.

ParameterRequiredDescription
session_idyesID of the active wick agent session
titleyesShort human-readable title. Truncated to 60 characters.

Returns the written session_id, title, and title_custom: true.

Auto-title behavior

When the agent system prompt is active (wick-agent server), the immutable system prompt instructs the agent to:

  1. Call wick_session_info near the start of a conversation.
  2. If title_custom is false, derive a short title (3–7 words, ≤ 50 characters) from the user's request and call wick_set_title.
  3. If title_custom is already true, leave the title alone.

This means sessions get a descriptive label automatically without prompting the user, while a title set manually by the user or by a previous agent turn is never clobbered.

Session workspace

wick_session_workspace lets an agent (or the user, via the session Workspace tab) spin up ephemeral connector instances scoped to one session: a private clone of a base connector — an httprest pointed at staging, a second API key — that behaves like a brand-new connector but lives and dies with the session. The saved connector rows are never touched.

Use it when the user wants to hit an endpoint or use a credential that only matters right now. Once added and configured, the instance's id shows in wick_list (pass the same session_id) and you wick_execute it like any connector. A session instance reports kind: "session" in the list response. When its config is incomplete its status is needs_setup_workspace (distinct from a saved connector's needs_setup) — direct the user to the Workspace tab, not the admin dashboard.

The tool is human-driven for config. The agent creates blank instances and can open the fill modal, but the user types the values; secrets are encrypted server-side with a system-only master key, and the agent only ever learns which keys were filled, never the values. This keeps connector credentials and endpoints off the agent's context entirely.

Eligibility

A connector can be cloned into a session instance only when both hold:

  1. its module declares AllowSessionConfig: true (capability, set in code / the custom-connector definition), and
  2. the Allow per-session config override toggle is on for a visible instance (Manager → Connectors → {instance} → Per-session config).

Condition 2 defaults to on for any instance whose module has the capability — so eligible built-in connectors (e.g. httprest) are ready without a manual admin toggle. Admins can still turn a row off explicitly.

action=list returns the available_bases you may add. wick_list (with session_id) exposes the same set as session_config_bases so the agent can proactively offer to add one.

Actions

actionWhat it does
listThis session's instances (id, status, missing keys) + available_bases.
addCreate a blank instance from a base_key. By default pops the fill modal for the user right away (prompt: false to skip).
duplicateCopy an existing session instance (config and all) into a new one.
configureReopen the fill modal so the user edits an instance's config. Blocks until submit (like ask_user).
testVerify setup — runs the base connector's health check, or pass operation (+ params) to run a real call.
removeDelete a session instance.

The agent can neither read nor set config values directly — config is always entered by the user. Secret values are stored as system-only master tokens and decrypted only at execution time, never returned.

Parameters

ParameterDescription
session_idThe active session ID (required for every action)
actionlist / add / duplicate / configure / test / remove
base_keyadd: the base connector key to clone (from available_bases)
connector_idThe session instance id (sw_…) for duplicate / configure / test / remove
labeladd / duplicate: optional human label
promptadd: open the fill modal immediately (default true)
keysadd / configure: limit the fill modal to these keys
operation, paramstest: run this operation as the probe instead of the health check
reasonadd / configure: short text shown to the user explaining what the connector is for

Workspace tab (UI)

The Workspace rail tab on the session slide-over is the user-facing equivalent of wick_session_workspace. It lists every session connector as a collapsible card, with a count badge that mirrors the number of active instances.

From the tab a user can:

  • Add a session connector — pick a base from the dropdown; a blank instance is created immediately and its card expands so you can fill it in.
  • Rename an instance inline — click the pencil icon next to the label, edit in place, confirm with Enter or blur.
  • Edit config — expand a card, type values into the fields. Only changed fields are marked dirty. The Save button sends only the fields you actually edited; a Reset button (shown while edits are pending) reverts the card to its last-saved state. An autofilled-but-untouched field is never sent.
  • Test — runs the connector's health check (or a named operation via ?operation=) against the config values currently on screen, not only what is saved. Live field values overlay the stored config for this probe only; nothing is persisted. This lets you verify a new key before committing.
  • Duplicate / Delete — copy an instance with its config, or remove it.

How instances run at execution time

When wick_execute (or wick_get) is called with a session_id and a sw_… connector id, the server resolves the instance from sessions/<id>/workspace.json, clones the base module, and runs against the instance's own config — no DB row, no tag visibility (the session itself is the authorization scope). Secret values (master tokens) are decrypted just before the call and re-masked in the response. A session-config-purge job sweeps stale workspace files by age as a TTL backstop.

Reference

Built with ❤️ by a developer, for developers.