⓪ Connectors index — "+ New connector" dropdown
Entry point. Tambah satu tombol di kanan-atas list. Dropdown reveals three sources. Existing search + filter chrome tetap.
Connectors
LLM-callable connectors that wrap external APIs.
GitHub
Built-inRead repos, issues, and pull requests on GitHub.
5 operations · 1 active
Stripe (custom)
CustomPayments — imported from cURL on 2026-06-05.
3 operations · 1 active · needs reload
Internal Tools MCP
Custom · MCP ● ConnectedLive proxy of internal-tools mcp — 7 tools (1 excluded).
7 operations · 7 active
① Flow A — paste · cURL or AI-assisted parser
Two parsers behind one paste box. cURL parser is deterministic (regex grammar, fast, no LLM call) — pick this when you have a real cURL string.
AI parser handles anything else: raw API docs, fetch() snippet, JS axios call, Postman export blob. Falls back to LLM extraction.
cURL parser — deterministic, $0, sync
Wick reads -X, -H, -d, -u, the URL, query string, and basic Bash escaping. Tokens that look like secrets are auto-flagged.
Tip: copy from browser DevTools → Network → Copy as cURL. Bash and PowerShell variants both supported.
More cURL shapes you can paste (click to try)
curl 'https://api.github.com/repos/anthropics/claude-code/issues?state=open&per_page=10' \ -H 'Authorization: Bearer ghp_xxxxxxxxxxxx' \ -H 'Accept: application/vnd.github+json'
Extracts to state + per_page Inputs; auth_value auto-secret.
curl -X POST https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer sk-proj-xxx" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4","messages":[{"role":"user","content":"hi"}],"temperature":0.7}'
Body keys flattened: model, messages (json), temperature.
curl -X PUT 'https://api.example.com/v1/users/42' \
-H 'X-API-Key: abc123' \
-d '{"name":"Andrian","role":"admin"}'
Numeric path segment /42 → user_id input (heuristic).
curl -u 'admin:hunter2' \ https://elastic.internal:9200/_cluster/health \ -H 'Accept: application/json'
-u → split jadi basic_user + basic_pass (pass auto-secret).
Same paste box, LLM extracts. Same review form. Tab hidden if no provider configured. Raw paste not persisted.
Inputs that AI parser accepts (cURL parser tolak semua ini)
fetch("https://api.stripe.com/v1/charges", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_xxx",
"Content-Type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams({
amount: "2000",
currency: "usd",
customer: "cus_123"
})
})
axios.post('https://api.example.com/api/v3/messages', {
room_id: 12345,
message: 'hello',
type: 'text'
}, {
headers: {
'ID': 'my-app',
'Key': 'sk_xxx'
}
})
POST https://api.internal/v2/tickets Headers: Authorization: Bearer <your-token> X-Workspace-Id: required Body (JSON): title (string, required) priority (low|medium|high) assignee_id (uuid, optional) Returns the created ticket object.
Saya mau call POST ke api.notion.com/v1/pages, auth pakai Bearer token, body JSON dengan field "parent" (database id), "properties" (object berisi title dan tags). Header "Notion-Version: 2022-06-28" wajib.
Apa pun input di atas, AI parser keluarin shape ini → review form
{
"method": "POST",
"url": "https://api.notion.com/v1/pages",
"headers": [
{ "key": "Authorization", "value": "Bearer …", "secret": true },
{ "key": "Notion-Version", "value": "2022-06-28" }
],
"body": { "content_type": "application/json", "keys": ["parent", "properties"] },
"suggested_op_name": "create_page",
"suggested_inputs": [
{ "key": "parent", "widget": "text", "required": true },
{ "key": "properties", "widget": "textarea", "required": true }
]
}
Show failure / fallback state
→ Switch to cURL parser tab, or paste only ONE endpoint at a time.
② Flow A — review · Configs vs Inputs split
Left: extracted fields with widget pickers and secret toggles. Right: live JSON preview of what gets written to custom_connectors (one row — ops embedded in the ops JSON column).
Admin sets Meta (Key / Name / Icon) at the top before saving.
Used in MCP tool_id. Lowercase, kebab/snake.
Auto-flagged: header value matched Bearer …. Encrypted-at-rest + masked in MCP responses.
post_charges
Destructive
Whitelist funcs: urlquery, js, printf, default, lower, upper. No shell, no file IO.
// one row in custom_connectors — ops embedded as JSON array
{
"key": "stripe",
"name": "Stripe (custom)",
"icon": "💳",
"source": "curl",
"source_meta": { "category": "Development", "health_op": "get_balance", "health_expect": "\"object\":\"balance\"" },
"configs": [
{ "key": "base_url", "widget": "url", "required": true },
{ "key": "auth_value", "widget": "secret", "secret": true, "required": true }
],
"ops": [
{
"key": "post_charges",
"name": "Create charge",
"destructive": true,
"inputs": [
{ "key": "amount", "widget": "number", "required": true },
{ "key": "currency", "widget": "text", "default": "usd" },
{ "key": "customer", "widget": "text", "required": true }
],
"request": {
"method": "POST",
"url_template": "{{.cfg.base_url}}/charges",
"headers": { "Authorization": "Bearer {{.cfg.auth_value}}" },
"body_template": "amount={{.in.amount}}&…",
"content_type": "application/x-www-form-urlencoded"
}
}
]
}
Wick will auto-create the filter tag custom:stripe on save.
By default only admins see this connector — non-admins can't see or call it.
You can open it up later under /admin/tags.
IsFilter=true, IsSystem=false. No user carries it at save, so the filter rule hides the connector from every non-admin /manager surface and MCP wick_list.
Grant access in two ways: (a) assign tag to user groups at /admin/tags, or (b) remove the filter tag entirely to open to all approved users.
③ Flow B — MCP server registration (HTTP forwarder)
Register an MCP server by URL + auth headers. Wick is a forwarder — no process spawn, no lifecycle to babysit. Per-call outbound JSON-RPC over HTTP.
Stdio MCPs are out of scope for v1; expose them via a sidecar (mcp-proxy / supergateway) if needed.
Display name — becomes the connector's name (and its key, slugified).
Streamable-HTTP endpoint. Wick POSTs JSON-RPC (initialize, tools/list, tools/call) here per request.
OAuth = standard MCP authorization (server replies 401 invalid_token): discovery + dynamic client registration + PKCE popup login on Test now. Accounts are per instance — save attaches the signed-in account as the first instance; more accounts connect from each instance page ("Connect account →"). Tokens stored encrypted per instance, auto-refreshed.
Each scheme shows different inputs below. Switching schemes preserves any extra Headers row you've added.
All four auth panels (one is rendered at runtime depending on radio)
Content-Type and Accept.
Content-Type: application/json
Accept: application/json
Recommended only inside a private network or behind a service mesh that handles auth.
Stored as wick_enc_…. Decrypted server-side per request, masked in audit logs.
Authorization: Bearer ••••••••
Content-Type: application/json
Most common shared-secret case (OAuth access token, API key in Bearer form, etc).
Define arbitrary header KV pairs. Toggle Sec per row — secret values encrypt at rest.
X-API-Key: ••••••••
X-Tenant-Id: example-tenant
Use for APIs that don't fit Bearer (e.g. Azure AAD Ocp-Apim-Subscription-Key, AWS sigv4 isn't covered here, providers with paired ID + secret headers).
Wick mints a short-lived (5-min) ED25519-signed JWT representing the user who triggered the MCP call and forwards it as X-Wick-User. MCP server validates against wick's pubkey at /.well-known/wick-pubkey.pem.
Defaults to MCP URL host. MCP server should validate this.
Re-minted per request — short TTL OK.
X-Wick-User: eyJhbGciOi… // signed, per-caller, 5-min
Content-Type: application/json
✓ Why SSO: no shared secret stored in wick; MCP can do per-user RBAC + audit; revoking a wick user revokes downstream access instantly (no token rotation needed).
⚠ Server requirement:
MCP server must implement JWT validation against /.well-known/wick-pubkey.pem. Not supported by stock open-source MCP servers — typically only your in-house ones.
For routing / tenancy headers that aren't auth. Each row is independently markable as secret.
Test connection
Fires initialize + tools/list with the current URL + headers. Save is blocked until at least one successful test.
Show failure example
④ Flow B — tools exclude-list (part of the server form)
After a successful test, the form shows the live tools/list catalog. Every tool is exposed automatically — ticking a row excludes it. Ops are never persisted: each module build (boot / re-sync / save) re-probes, so new server-side tools appear on their own. JSON Schema maps to wick widgets at build time.
| Excl. | Tool | Description | Inputs | Destructive? |
|---|---|---|---|---|
| lookup_user | Find a user by email or id. | email?, id? | no | |
| disable_user | Disable a user account. | user_id | Destructive | |
| audit_query | Query the audit log with time-range + filter. | since, until, action? | no | |
| delete_records | Delete N records matching a filter. | filter, limit | Destructive |
One server = one connector. Saving creates it immediately; re-sync from the connector page picks up upstream tool changes.
⑤ Flow C — manual builder
Three-step stepper for greenfield definitions. Each step persists draft state; admin can leave + resume.
Step 2 · Configs
Define per-instance fields shared across every operation. Use secret for credentials — wick auto-encrypts at rest and masks in MCP responses.
⑥ Custom connector detail (same chrome as built-in + reload banner)
Same pages as built-in — list page (/manager/connectors/<key>) and instance page (…/<id>): instance Configs editor, per-op toggles, history. Multi-instance by default: no row is auto-seeded at save — admins click + New row (and Duplicate) like any connector, each row with its own credentials; "Single instance only" is an opt-in checkbox on the review form. Custom additions in the header: "Custom · <source>" badge, a status chip for MCP defs (● Connected / ● Disconnected from the last probe — stays until a re-sync, reconnect, or disable; ● Disabled wins for any source; cURL/manual defs show no connection chip), "Edit definition" link, "↻ Re-sync tools" (MCP), a "needs reload" banner when dirty, and a definition danger zone with Disable (zero ops served, pages stay) and Delete.
Payments — imported from cURL on 2026-06-05 by yoga@example.com. (cURL source — no connection chip; MCP defs show ● Connected / ● Disconnected here.)
Stored as wick_enc_…. Decryption happens server-side per call.
custom:stripe is the per-def auto-tag — its filter flag is what makes this connector admin-only by default. Remove it to open to all approved users.
custom:stripe. Assign at /admin/tags/custom:stripe, or
open to all (removes the filter tag from this connector).
Operation call passes only when: row tags allow AND op enabled AND (admin OR not admin-only). Three independent off-switches.
Token legend (design-system compliance)
Spacing follows 8-grid; cards use rounded-xl (12px); inputs rounded-lg (8px); chips rounded-full.
Dark-mode pair: navy-700 surfaces with white-100 text and navy-600 borders.