- CLAUDE.md: developer guide for the marketplace repo - email/: generic IMAP+SMTP connector (stdlib only, config via env) - env[] array, auth.type: password, verify.py (IMAP+SMTP probe) - ssh/: SSH Remote Access connector ported from Skald, modified - ALIASES_FILE → ~/.ssh_aliases.json (was ./secrets/...) - optional env[] (TTL/timeout tunables) - auth.type: none (per-alias auth at runtime via elicitation) - tavily/: restructured with env[] (tavilyApiKey), verify.py, auth block - connectors.json: added email, ssh, and tavily verify.py entries - SKALD.md: documented env[], verify, password auth, SSH connector
66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the Tavily API key by making a minimal search request.
|
|
|
|
Reads TAVILY_API_KEY from the environment (the key skald collected from the
|
|
user and substituted into the {SECRET:tavilyApiKey} placeholder), POSTs a
|
|
minimal search to https://api.tavily.com/search, and prints a single JSON
|
|
object on stdout:
|
|
|
|
{"ok": true, "message": "Tavily API key is valid"}
|
|
{"ok": false, "message": "Tavily API key is invalid or unauthorized"}
|
|
|
|
Exit code is 0 on success, 1 on any failure. The API key is never printed.
|
|
|
|
stdlib only (urllib).
|
|
"""
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
|
|
def _result(ok, message):
|
|
print(json.dumps({"ok": ok, "message": message}))
|
|
sys.exit(0 if ok else 1)
|
|
|
|
|
|
def main():
|
|
api_key = os.environ.get("tavilyApiKey", "").strip()
|
|
if not api_key:
|
|
# Also accept the UPPER_SNAKE form some users may type.
|
|
api_key = os.environ.get("TAVILY_API_KEY", "").strip()
|
|
if not api_key:
|
|
_result(False, "No Tavily API key provided (tavilyApiKey env var is empty)")
|
|
|
|
body = json.dumps({
|
|
"api_key": api_key,
|
|
"query": "skald connectivity check",
|
|
"max_results": 1,
|
|
"search_depth": "basic",
|
|
}).encode("utf-8")
|
|
|
|
req = urllib.request.Request(
|
|
"https://api.tavily.com/search",
|
|
data=body,
|
|
headers={"Content-Type": "application/json"},
|
|
method="POST",
|
|
)
|
|
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=15) as resp:
|
|
if 200 <= resp.status < 300:
|
|
_result(True, "Tavily API key is valid")
|
|
_result(False, f"Tavily returned HTTP {resp.status}")
|
|
except urllib.error.HTTPError as e:
|
|
if e.code in (401, 403):
|
|
_result(False, "Tavily API key is invalid or unauthorized "
|
|
f"(HTTP {e.code})")
|
|
_result(False, f"Tavily returned HTTP {e.code}: {e.reason}")
|
|
except Exception as e:
|
|
_result(False, f"Tavily verify request failed: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|