@unclick/mcp-server 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -153
- package/dist/airtable-tool.d.ts +2 -0
- package/dist/airtable-tool.d.ts.map +1 -0
- package/dist/airtable-tool.js +154 -0
- package/dist/airtable-tool.js.map +1 -0
- package/dist/algolia-tool.d.ts +5 -0
- package/dist/algolia-tool.d.ts.map +1 -0
- package/dist/algolia-tool.js +121 -0
- package/dist/algolia-tool.js.map +1 -0
- package/dist/anthropic-tool.d.ts +3 -0
- package/dist/anthropic-tool.d.ts.map +1 -0
- package/dist/anthropic-tool.js +123 -0
- package/dist/anthropic-tool.js.map +1 -0
- package/dist/asana-tool.d.ts +8 -0
- package/dist/asana-tool.d.ts.map +1 -0
- package/dist/asana-tool.js +218 -0
- package/dist/asana-tool.js.map +1 -0
- package/dist/assemblyai-tool.d.ts +7 -0
- package/dist/assemblyai-tool.d.ts.map +1 -0
- package/dist/assemblyai-tool.js +127 -0
- package/dist/assemblyai-tool.js.map +1 -0
- package/dist/calendly-tool.d.ts +6 -0
- package/dist/calendly-tool.d.ts.map +1 -0
- package/dist/calendly-tool.js +182 -0
- package/dist/calendly-tool.js.map +1 -0
- package/dist/circleci-tool.d.ts +7 -0
- package/dist/circleci-tool.d.ts.map +1 -0
- package/dist/circleci-tool.js +133 -0
- package/dist/circleci-tool.js.map +1 -0
- package/dist/clickup-tool.d.ts +2 -0
- package/dist/clickup-tool.d.ts.map +1 -0
- package/dist/clickup-tool.js +153 -0
- package/dist/clickup-tool.js.map +1 -0
- package/dist/cohere-tool.d.ts +7 -0
- package/dist/cohere-tool.d.ts.map +1 -0
- package/dist/cohere-tool.js +225 -0
- package/dist/cohere-tool.js.map +1 -0
- package/dist/connectors/figma.d.ts +3 -0
- package/dist/connectors/figma.d.ts.map +1 -0
- package/dist/connectors/figma.js +18 -0
- package/dist/connectors/figma.js.map +1 -0
- package/dist/connectors/index.d.ts +3 -1
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +5 -1
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/line.d.ts +3 -0
- package/dist/connectors/line.d.ts.map +1 -0
- package/dist/connectors/line.js +18 -0
- package/dist/connectors/line.js.map +1 -0
- package/dist/convertkit-tool.d.ts +7 -0
- package/dist/convertkit-tool.d.ts.map +1 -0
- package/dist/convertkit-tool.js +213 -0
- package/dist/convertkit-tool.js.map +1 -0
- package/dist/datadog-tool.d.ts +7 -0
- package/dist/datadog-tool.d.ts.map +1 -0
- package/dist/datadog-tool.js +121 -0
- package/dist/datadog-tool.js.map +1 -0
- package/dist/deepl-tool.d.ts +5 -0
- package/dist/deepl-tool.d.ts.map +1 -0
- package/dist/deepl-tool.js +137 -0
- package/dist/deepl-tool.js.map +1 -0
- package/dist/ebay-tool.d.ts +5 -0
- package/dist/ebay-tool.d.ts.map +1 -0
- package/dist/ebay-tool.js +179 -0
- package/dist/ebay-tool.js.map +1 -0
- package/dist/elevenlabs-tool.d.ts +6 -0
- package/dist/elevenlabs-tool.d.ts.map +1 -0
- package/dist/elevenlabs-tool.js +166 -0
- package/dist/elevenlabs-tool.js.map +1 -0
- package/dist/etsy-tool.d.ts +6 -0
- package/dist/etsy-tool.d.ts.map +1 -0
- package/dist/etsy-tool.js +125 -0
- package/dist/etsy-tool.js.map +1 -0
- package/dist/exchangerate-tool.d.ts +5 -0
- package/dist/exchangerate-tool.d.ts.map +1 -0
- package/dist/exchangerate-tool.js +139 -0
- package/dist/exchangerate-tool.js.map +1 -0
- package/dist/figma-tool.d.ts +8 -0
- package/dist/figma-tool.d.ts.map +1 -0
- package/dist/figma-tool.js +231 -0
- package/dist/figma-tool.js.map +1 -0
- package/dist/flyio-tool.d.ts +6 -0
- package/dist/flyio-tool.d.ts.map +1 -0
- package/dist/flyio-tool.js +158 -0
- package/dist/flyio-tool.js.map +1 -0
- package/dist/gdelt-tool.d.ts +5 -0
- package/dist/gdelt-tool.d.ts.map +1 -0
- package/dist/gdelt-tool.js +177 -0
- package/dist/gdelt-tool.js.map +1 -0
- package/dist/github-tool.d.ts +2 -0
- package/dist/github-tool.d.ts.map +1 -0
- package/dist/github-tool.js +165 -0
- package/dist/github-tool.js.map +1 -0
- package/dist/gitlab-tool.d.ts +2 -0
- package/dist/gitlab-tool.d.ts.map +1 -0
- package/dist/gitlab-tool.js +127 -0
- package/dist/gitlab-tool.js.map +1 -0
- package/dist/groq-tool.d.ts +3 -0
- package/dist/groq-tool.d.ts.map +1 -0
- package/dist/groq-tool.js +109 -0
- package/dist/groq-tool.js.map +1 -0
- package/dist/gumroad-tool.d.ts +6 -0
- package/dist/gumroad-tool.d.ts.map +1 -0
- package/dist/gumroad-tool.js +90 -0
- package/dist/gumroad-tool.js.map +1 -0
- package/dist/heygen-tool.d.ts +5 -0
- package/dist/heygen-tool.d.ts.map +1 -0
- package/dist/heygen-tool.js +134 -0
- package/dist/heygen-tool.js.map +1 -0
- package/dist/higgsfield-tool.d.ts +5 -0
- package/dist/higgsfield-tool.d.ts.map +1 -0
- package/dist/higgsfield-tool.js +120 -0
- package/dist/higgsfield-tool.js.map +1 -0
- package/dist/igdb-tool.d.ts +6 -0
- package/dist/igdb-tool.d.ts.map +1 -0
- package/dist/igdb-tool.js +140 -0
- package/dist/igdb-tool.js.map +1 -0
- package/dist/keychain-crypto.d.ts +24 -0
- package/dist/keychain-crypto.d.ts.map +1 -0
- package/dist/keychain-crypto.js +60 -0
- package/dist/keychain-crypto.js.map +1 -0
- package/dist/keychain-secure-input.d.ts +17 -0
- package/dist/keychain-secure-input.d.ts.map +1 -0
- package/dist/keychain-secure-input.js +229 -0
- package/dist/keychain-secure-input.js.map +1 -0
- package/dist/keychain-tool.d.ts +3 -0
- package/dist/keychain-tool.d.ts.map +1 -0
- package/dist/keychain-tool.js +516 -0
- package/dist/keychain-tool.js.map +1 -0
- package/dist/kling-tool.d.ts +3 -0
- package/dist/kling-tool.d.ts.map +1 -0
- package/dist/kling-tool.js +102 -0
- package/dist/kling-tool.js.map +1 -0
- package/dist/lemonsqueezy-tool.d.ts +7 -0
- package/dist/lemonsqueezy-tool.d.ts.map +1 -0
- package/dist/lemonsqueezy-tool.js +220 -0
- package/dist/lemonsqueezy-tool.js.map +1 -0
- package/dist/line-tool.d.ts +7 -0
- package/dist/line-tool.d.ts.map +1 -0
- package/dist/line-tool.js +188 -0
- package/dist/line-tool.js.map +1 -0
- package/dist/linear-tool.d.ts +2 -0
- package/dist/linear-tool.d.ts.map +1 -0
- package/dist/linear-tool.js +186 -0
- package/dist/linear-tool.js.map +1 -0
- package/dist/local-catalog-handlers.d.ts +3 -0
- package/dist/local-catalog-handlers.d.ts.map +1 -0
- package/dist/local-catalog-handlers.js +1254 -0
- package/dist/local-catalog-handlers.js.map +1 -0
- package/dist/mailchimp-tool.d.ts +8 -0
- package/dist/mailchimp-tool.d.ts.map +1 -0
- package/dist/mailchimp-tool.js +138 -0
- package/dist/mailchimp-tool.js.map +1 -0
- package/dist/mapbox-tool.d.ts +6 -0
- package/dist/mapbox-tool.d.ts.map +1 -0
- package/dist/mapbox-tool.js +106 -0
- package/dist/mapbox-tool.js.map +1 -0
- package/dist/mistral-tool.d.ts +4 -0
- package/dist/mistral-tool.d.ts.map +1 -0
- package/dist/mistral-tool.js +145 -0
- package/dist/mistral-tool.js.map +1 -0
- package/dist/mixpanel-tool.d.ts +6 -0
- package/dist/mixpanel-tool.d.ts.map +1 -0
- package/dist/mixpanel-tool.js +162 -0
- package/dist/mixpanel-tool.js.map +1 -0
- package/dist/monday-tool.d.ts +7 -0
- package/dist/monday-tool.d.ts.map +1 -0
- package/dist/monday-tool.js +206 -0
- package/dist/monday-tool.js.map +1 -0
- package/dist/neon-tool.d.ts +7 -0
- package/dist/neon-tool.d.ts.map +1 -0
- package/dist/neon-tool.js +156 -0
- package/dist/neon-tool.js.map +1 -0
- package/dist/openai-tool.d.ts +6 -0
- package/dist/openai-tool.d.ts.map +1 -0
- package/dist/openai-tool.js +227 -0
- package/dist/openai-tool.js.map +1 -0
- package/dist/pagerduty-tool.d.ts +8 -0
- package/dist/pagerduty-tool.d.ts.map +1 -0
- package/dist/pagerduty-tool.js +185 -0
- package/dist/pagerduty-tool.js.map +1 -0
- package/dist/paypal-tool.d.ts +3 -0
- package/dist/paypal-tool.d.ts.map +1 -0
- package/dist/paypal-tool.js +157 -0
- package/dist/paypal-tool.js.map +1 -0
- package/dist/perplexity-tool.d.ts +2 -0
- package/dist/perplexity-tool.d.ts.map +1 -0
- package/dist/perplexity-tool.js +93 -0
- package/dist/perplexity-tool.js.map +1 -0
- package/dist/pika-tool.d.ts +4 -0
- package/dist/pika-tool.d.ts.map +1 -0
- package/dist/pika-tool.js +102 -0
- package/dist/pika-tool.js.map +1 -0
- package/dist/pinecone-tool.d.ts +6 -0
- package/dist/pinecone-tool.d.ts.map +1 -0
- package/dist/pinecone-tool.js +148 -0
- package/dist/pinecone-tool.js.map +1 -0
- package/dist/pinterest-tool.d.ts +7 -0
- package/dist/pinterest-tool.d.ts.map +1 -0
- package/dist/pinterest-tool.js +219 -0
- package/dist/pinterest-tool.js.map +1 -0
- package/dist/plaid-tool.d.ts +6 -0
- package/dist/plaid-tool.d.ts.map +1 -0
- package/dist/plaid-tool.js +149 -0
- package/dist/plaid-tool.js.map +1 -0
- package/dist/postman-tool.d.ts +2 -0
- package/dist/postman-tool.d.ts.map +1 -0
- package/dist/postman-tool.js +92 -0
- package/dist/postman-tool.js.map +1 -0
- package/dist/postmark-tool.d.ts +7 -0
- package/dist/postmark-tool.d.ts.map +1 -0
- package/dist/postmark-tool.js +148 -0
- package/dist/postmark-tool.js.map +1 -0
- package/dist/pushover-tool.d.ts +6 -0
- package/dist/pushover-tool.d.ts.map +1 -0
- package/dist/pushover-tool.js +146 -0
- package/dist/pushover-tool.js.map +1 -0
- package/dist/qc-tool.d.ts +4 -0
- package/dist/qc-tool.d.ts.map +1 -0
- package/dist/qc-tool.js +415 -0
- package/dist/qc-tool.js.map +1 -0
- package/dist/quickbooks-tool.d.ts +5 -0
- package/dist/quickbooks-tool.d.ts.map +1 -0
- package/dist/quickbooks-tool.js +160 -0
- package/dist/quickbooks-tool.js.map +1 -0
- package/dist/render-tool.d.ts +7 -0
- package/dist/render-tool.d.ts.map +1 -0
- package/dist/render-tool.js +158 -0
- package/dist/render-tool.js.map +1 -0
- package/dist/replicate-tool.d.ts +7 -0
- package/dist/replicate-tool.d.ts.map +1 -0
- package/dist/replicate-tool.js +172 -0
- package/dist/replicate-tool.js.map +1 -0
- package/dist/runway-tool.d.ts +4 -0
- package/dist/runway-tool.d.ts.map +1 -0
- package/dist/runway-tool.js +110 -0
- package/dist/runway-tool.js.map +1 -0
- package/dist/segment-tool.d.ts +6 -0
- package/dist/segment-tool.d.ts.map +1 -0
- package/dist/segment-tool.js +129 -0
- package/dist/segment-tool.js.map +1 -0
- package/dist/sendgrid-tool.d.ts +7 -0
- package/dist/sendgrid-tool.d.ts.map +1 -0
- package/dist/sendgrid-tool.js +124 -0
- package/dist/sendgrid-tool.js.map +1 -0
- package/dist/sentry-tool.d.ts +2 -0
- package/dist/sentry-tool.d.ts.map +1 -0
- package/dist/sentry-tool.js +123 -0
- package/dist/sentry-tool.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -1
- package/dist/speedrun-tool.d.ts +6 -0
- package/dist/speedrun-tool.d.ts.map +1 -0
- package/dist/speedrun-tool.js +192 -0
- package/dist/speedrun-tool.js.map +1 -0
- package/dist/spotify-tool.d.ts +8 -0
- package/dist/spotify-tool.d.ts.map +1 -0
- package/dist/spotify-tool.js +274 -0
- package/dist/spotify-tool.js.map +1 -0
- package/dist/square-tool.d.ts +5 -0
- package/dist/square-tool.d.ts.map +1 -0
- package/dist/square-tool.js +133 -0
- package/dist/square-tool.js.map +1 -0
- package/dist/stability-tool.d.ts +5 -0
- package/dist/stability-tool.d.ts.map +1 -0
- package/dist/stability-tool.js +190 -0
- package/dist/stability-tool.js.map +1 -0
- package/dist/steam-tool.d.ts +6 -0
- package/dist/steam-tool.d.ts.map +1 -0
- package/dist/steam-tool.js +222 -0
- package/dist/steam-tool.js.map +1 -0
- package/dist/stripe-tool.d.ts +7 -0
- package/dist/stripe-tool.d.ts.map +1 -0
- package/dist/stripe-tool.js +181 -0
- package/dist/stripe-tool.js.map +1 -0
- package/dist/tiktok-tool.d.ts +4 -0
- package/dist/tiktok-tool.d.ts.map +1 -0
- package/dist/tiktok-tool.js +129 -0
- package/dist/tiktok-tool.js.map +1 -0
- package/dist/togetherai-tool.d.ts +5 -0
- package/dist/togetherai-tool.d.ts.map +1 -0
- package/dist/togetherai-tool.js +129 -0
- package/dist/togetherai-tool.js.map +1 -0
- package/dist/toilets-tool.js +2 -2
- package/dist/tool-wiring.d.ts +7982 -18
- package/dist/tool-wiring.d.ts.map +1 -1
- package/dist/tool-wiring.js +5084 -18
- package/dist/tool-wiring.js.map +1 -1
- package/dist/trello-tool.d.ts +2 -0
- package/dist/trello-tool.d.ts.map +1 -0
- package/dist/trello-tool.js +166 -0
- package/dist/trello-tool.js.map +1 -0
- package/dist/turso-tool.d.ts +6 -0
- package/dist/turso-tool.d.ts.map +1 -0
- package/dist/turso-tool.js +158 -0
- package/dist/turso-tool.js.map +1 -0
- package/dist/twilio-tool.d.ts +8 -0
- package/dist/twilio-tool.d.ts.map +1 -0
- package/dist/twilio-tool.js +243 -0
- package/dist/twilio-tool.js.map +1 -0
- package/dist/upstash-tool.d.ts +8 -0
- package/dist/upstash-tool.d.ts.map +1 -0
- package/dist/upstash-tool.js +191 -0
- package/dist/upstash-tool.js.map +1 -0
- package/dist/whatsapp-tool.d.ts +6 -0
- package/dist/whatsapp-tool.d.ts.map +1 -0
- package/dist/whatsapp-tool.js +200 -0
- package/dist/whatsapp-tool.js.map +1 -0
- package/dist/woocommerce-tool.d.ts +4 -0
- package/dist/woocommerce-tool.d.ts.map +1 -0
- package/dist/woocommerce-tool.js +140 -0
- package/dist/woocommerce-tool.js.map +1 -0
- package/dist/youtube-tool.d.ts +7 -0
- package/dist/youtube-tool.d.ts.map +1 -0
- package/dist/youtube-tool.js +196 -0
- package/dist/youtube-tool.js.map +1 -0
- package/package.json +1 -1
- package/server.json +37 -37
- package/LICENSE +0 -216
- package/dist/cloudflare-worker.d.ts +0 -12
- package/dist/cloudflare-worker.d.ts.map +0 -1
- package/dist/cloudflare-worker.js +0 -50
- package/dist/cloudflare-worker.js.map +0 -1
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// HeyGen API integration for the UnClick MCP server.
|
|
2
|
+
// Uses the HeyGen REST API via fetch - no external dependencies.
|
|
3
|
+
// Users must supply an API key from app.heygen.com/settings.
|
|
4
|
+
const HG_API_BASE = "https://api.heygen.com";
|
|
5
|
+
// ─── Auth validation ──────────────────────────────────────────────────────────
|
|
6
|
+
function requireKey(args) {
|
|
7
|
+
const key = String(args.api_key ?? "").trim();
|
|
8
|
+
if (!key)
|
|
9
|
+
throw new Error("api_key is required. Get one at app.heygen.com/settings.");
|
|
10
|
+
return key;
|
|
11
|
+
}
|
|
12
|
+
// ─── API helpers ──────────────────────────────────────────────────────────────
|
|
13
|
+
async function hgGet(apiKey, path) {
|
|
14
|
+
const res = await fetch(`${HG_API_BASE}${path}`, {
|
|
15
|
+
headers: {
|
|
16
|
+
"x-api-key": apiKey,
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const data = await res.json();
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
const msg = data.message ?? data.error ?? `HTTP ${res.status}`;
|
|
23
|
+
throw new Error(`HeyGen error (${res.status}): ${msg}`);
|
|
24
|
+
}
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
async function hgPost(apiKey, path, body) {
|
|
28
|
+
const res = await fetch(`${HG_API_BASE}${path}`, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: {
|
|
31
|
+
"x-api-key": apiKey,
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify(body),
|
|
35
|
+
});
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const msg = data.message ?? data.error ?? `HTTP ${res.status}`;
|
|
39
|
+
throw new Error(`HeyGen error (${res.status}): ${msg}`);
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
// ─── Operations ───────────────────────────────────────────────────────────────
|
|
44
|
+
export async function heygen_create_avatar_video(args) {
|
|
45
|
+
const apiKey = requireKey(args);
|
|
46
|
+
const avatarId = String(args.avatar_id ?? "").trim();
|
|
47
|
+
const script = String(args.script ?? "").trim();
|
|
48
|
+
if (!avatarId)
|
|
49
|
+
throw new Error("avatar_id is required.");
|
|
50
|
+
if (!script)
|
|
51
|
+
throw new Error("script is required (the text the avatar will speak).");
|
|
52
|
+
const voiceId = args.voice_id ? String(args.voice_id) : undefined;
|
|
53
|
+
const backgroundUrl = args.background_url ? String(args.background_url) : undefined;
|
|
54
|
+
const width = args.width ? Number(args.width) : 1280;
|
|
55
|
+
const height = args.height ? Number(args.height) : 720;
|
|
56
|
+
const body = {
|
|
57
|
+
video_inputs: [
|
|
58
|
+
{
|
|
59
|
+
character: {
|
|
60
|
+
type: "avatar",
|
|
61
|
+
avatar_id: avatarId,
|
|
62
|
+
avatar_style: args.avatar_style ?? "normal",
|
|
63
|
+
},
|
|
64
|
+
voice: voiceId
|
|
65
|
+
? { type: "text", input_text: script, voice_id: voiceId }
|
|
66
|
+
: { type: "text", input_text: script },
|
|
67
|
+
background: backgroundUrl
|
|
68
|
+
? { type: "image", url: backgroundUrl }
|
|
69
|
+
: { type: "color", value: "#ffffff" },
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
dimension: { width, height },
|
|
73
|
+
};
|
|
74
|
+
if (args.title)
|
|
75
|
+
body.title = String(args.title);
|
|
76
|
+
if (args.test !== undefined)
|
|
77
|
+
body.test = Boolean(args.test);
|
|
78
|
+
const result = await hgPost(apiKey, "/v2/video/generate", body);
|
|
79
|
+
const videoId = (result.data?.video_id ?? result.video_id);
|
|
80
|
+
return {
|
|
81
|
+
video_id: videoId ?? null,
|
|
82
|
+
status: "submitted",
|
|
83
|
+
note: "Use heygen_get_video_status with the video_id to poll for completion.",
|
|
84
|
+
raw: result,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export async function heygen_list_avatars(args) {
|
|
88
|
+
const apiKey = requireKey(args);
|
|
89
|
+
const data = await hgGet(apiKey, "/v2/avatars");
|
|
90
|
+
const avatars = data.data?.avatars ?? [];
|
|
91
|
+
return {
|
|
92
|
+
count: avatars.length,
|
|
93
|
+
avatars: avatars.map((a) => ({
|
|
94
|
+
avatar_id: a.avatar_id,
|
|
95
|
+
name: a.avatar_name,
|
|
96
|
+
gender: a.gender ?? null,
|
|
97
|
+
preview_image_url: a.preview_image_url ?? null,
|
|
98
|
+
})),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export async function heygen_get_video_status(args) {
|
|
102
|
+
const apiKey = requireKey(args);
|
|
103
|
+
const videoId = String(args.video_id ?? "").trim();
|
|
104
|
+
if (!videoId)
|
|
105
|
+
throw new Error("video_id is required.");
|
|
106
|
+
const data = await hgGet(apiKey, `/v1/video_status.get?video_id=${encodeURIComponent(videoId)}`);
|
|
107
|
+
const info = data.data ?? data;
|
|
108
|
+
return {
|
|
109
|
+
video_id: videoId,
|
|
110
|
+
status: info.status ?? null,
|
|
111
|
+
video_url: info.video_url ?? null,
|
|
112
|
+
thumbnail_url: info.thumbnail_url ?? null,
|
|
113
|
+
duration: info.duration ?? null,
|
|
114
|
+
created_at: info.created_at ?? null,
|
|
115
|
+
error: info.error ?? null,
|
|
116
|
+
raw: data,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export async function heygen_list_voices(args) {
|
|
120
|
+
const apiKey = requireKey(args);
|
|
121
|
+
const data = await hgGet(apiKey, "/v2/voices");
|
|
122
|
+
const voices = data.data?.voices ?? [];
|
|
123
|
+
return {
|
|
124
|
+
count: voices.length,
|
|
125
|
+
voices: voices.map((v) => ({
|
|
126
|
+
voice_id: v.voice_id,
|
|
127
|
+
name: v.name,
|
|
128
|
+
language: v.language,
|
|
129
|
+
gender: v.gender,
|
|
130
|
+
preview_audio: v.preview_audio ?? null,
|
|
131
|
+
})),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=heygen-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heygen-tool.js","sourceRoot":"","sources":["../src/heygen-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function higgsfield_generate_video(args: Record<string, unknown>): Promise<unknown>;
|
|
2
|
+
export declare function higgsfield_generate_image(args: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function higgsfield_get_styles(args: Record<string, unknown>): Promise<unknown>;
|
|
4
|
+
export declare function higgsfield_get_status(args: Record<string, unknown>): Promise<unknown>;
|
|
5
|
+
//# sourceMappingURL=higgsfield-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"higgsfield-tool.d.ts","sourceRoot":"","sources":["../src/higgsfield-tool.ts"],"names":[],"mappings":"AAoDA,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB/F;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB/F;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3F;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB3F"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Higgsfield AI API integration for the UnClick MCP server.
|
|
2
|
+
// Uses the Higgsfield REST API via fetch - no external dependencies.
|
|
3
|
+
// Users must supply an API key from higgsfield.ai.
|
|
4
|
+
const HF_API_BASE = "https://api.higgsfield.ai/v1";
|
|
5
|
+
// ─── Auth validation ──────────────────────────────────────────────────────────
|
|
6
|
+
function requireKey(args) {
|
|
7
|
+
const key = String(args.api_key ?? "").trim();
|
|
8
|
+
if (!key)
|
|
9
|
+
throw new Error("api_key is required. Get one at higgsfield.ai.");
|
|
10
|
+
return key;
|
|
11
|
+
}
|
|
12
|
+
// ─── API helpers ──────────────────────────────────────────────────────────────
|
|
13
|
+
async function hfGet(apiKey, path) {
|
|
14
|
+
const res = await fetch(`${HF_API_BASE}${path}`, {
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${apiKey}`,
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const data = await res.json();
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
const msg = data.message ?? data.error ?? `HTTP ${res.status}`;
|
|
23
|
+
throw new Error(`Higgsfield error (${res.status}): ${msg}`);
|
|
24
|
+
}
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
async function hfPost(apiKey, path, body) {
|
|
28
|
+
const res = await fetch(`${HF_API_BASE}${path}`, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: `Bearer ${apiKey}`,
|
|
32
|
+
"Content-Type": "application/json",
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify(body),
|
|
35
|
+
});
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const msg = data.message ?? data.error ?? `HTTP ${res.status}`;
|
|
39
|
+
throw new Error(`Higgsfield error (${res.status}): ${msg}`);
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
// ─── Operations ───────────────────────────────────────────────────────────────
|
|
44
|
+
export async function higgsfield_generate_video(args) {
|
|
45
|
+
const apiKey = requireKey(args);
|
|
46
|
+
const prompt = String(args.prompt ?? "").trim();
|
|
47
|
+
if (!prompt)
|
|
48
|
+
throw new Error("prompt is required.");
|
|
49
|
+
const body = { prompt };
|
|
50
|
+
if (args.style)
|
|
51
|
+
body.style = String(args.style);
|
|
52
|
+
if (args.duration)
|
|
53
|
+
body.duration = Number(args.duration);
|
|
54
|
+
if (args.aspect_ratio)
|
|
55
|
+
body.aspect_ratio = String(args.aspect_ratio);
|
|
56
|
+
if (args.negative_prompt)
|
|
57
|
+
body.negative_prompt = String(args.negative_prompt);
|
|
58
|
+
if (args.seed !== undefined)
|
|
59
|
+
body.seed = Number(args.seed);
|
|
60
|
+
const result = await hfPost(apiKey, "/video/generate", body);
|
|
61
|
+
return {
|
|
62
|
+
generation_id: result.id ?? result.generation_id ?? null,
|
|
63
|
+
status: result.status ?? "submitted",
|
|
64
|
+
prompt,
|
|
65
|
+
note: "Use higgsfield_get_status with the generation_id to poll for completion.",
|
|
66
|
+
raw: result,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export async function higgsfield_generate_image(args) {
|
|
70
|
+
const apiKey = requireKey(args);
|
|
71
|
+
const prompt = String(args.prompt ?? "").trim();
|
|
72
|
+
if (!prompt)
|
|
73
|
+
throw new Error("prompt is required.");
|
|
74
|
+
const body = { prompt };
|
|
75
|
+
if (args.style)
|
|
76
|
+
body.style = String(args.style);
|
|
77
|
+
if (args.width)
|
|
78
|
+
body.width = Number(args.width);
|
|
79
|
+
if (args.height)
|
|
80
|
+
body.height = Number(args.height);
|
|
81
|
+
if (args.negative_prompt)
|
|
82
|
+
body.negative_prompt = String(args.negative_prompt);
|
|
83
|
+
if (args.seed !== undefined)
|
|
84
|
+
body.seed = Number(args.seed);
|
|
85
|
+
const result = await hfPost(apiKey, "/image/generate", body);
|
|
86
|
+
return {
|
|
87
|
+
generation_id: result.id ?? result.generation_id ?? null,
|
|
88
|
+
status: result.status ?? "submitted",
|
|
89
|
+
image_url: result.image_url ?? result.url ?? null,
|
|
90
|
+
prompt,
|
|
91
|
+
raw: result,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export async function higgsfield_get_styles(args) {
|
|
95
|
+
const apiKey = requireKey(args);
|
|
96
|
+
const data = await hfGet(apiKey, "/styles");
|
|
97
|
+
const styles = data.styles ?? data.data ?? [];
|
|
98
|
+
return {
|
|
99
|
+
count: Array.isArray(styles) ? styles.length : 0,
|
|
100
|
+
styles,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export async function higgsfield_get_status(args) {
|
|
104
|
+
const apiKey = requireKey(args);
|
|
105
|
+
const generationId = String(args.generation_id ?? "").trim();
|
|
106
|
+
if (!generationId)
|
|
107
|
+
throw new Error("generation_id is required.");
|
|
108
|
+
const result = await hfGet(apiKey, `/generation/${encodeURIComponent(generationId)}`);
|
|
109
|
+
return {
|
|
110
|
+
generation_id: generationId,
|
|
111
|
+
status: result.status ?? null,
|
|
112
|
+
video_url: result.video_url ?? result.url ?? null,
|
|
113
|
+
image_url: result.image_url ?? null,
|
|
114
|
+
created_at: result.created_at ?? null,
|
|
115
|
+
completed_at: result.completed_at ?? null,
|
|
116
|
+
error: result.error ?? null,
|
|
117
|
+
raw: result,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=higgsfield-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"higgsfield-tool.js","sourceRoot":"","sources":["../src/higgsfield-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function igdbSearchGames(args: Record<string, unknown>): Promise<unknown>;
|
|
2
|
+
export declare function igdbGetGame(args: Record<string, unknown>): Promise<unknown>;
|
|
3
|
+
export declare function igdbListPlatforms(args: Record<string, unknown>): Promise<unknown>;
|
|
4
|
+
export declare function igdbListGenres(args: Record<string, unknown>): Promise<unknown>;
|
|
5
|
+
export declare function igdbGetCompany(args: Record<string, unknown>): Promise<unknown>;
|
|
6
|
+
//# sourceMappingURL=igdb-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"igdb-tool.d.ts","sourceRoot":"","sources":["../src/igdb-tool.ts"],"names":[],"mappings":"AAsEA,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAarF;AAGD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAajF;AAGD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAYvF;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAUpF;AAGD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBpF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// IGDB games database API (powered by Twitch).
|
|
2
|
+
// Docs: https://api-docs.igdb.com/
|
|
3
|
+
// Auth: IGDB_CLIENT_ID + IGDB_CLIENT_SECRET (Twitch OAuth2 app credentials)
|
|
4
|
+
// Base: https://api.igdb.com/v4
|
|
5
|
+
// Token endpoint: https://id.twitch.tv/oauth2/token (client_credentials grant)
|
|
6
|
+
const IGDB_BASE = "https://api.igdb.com/v4";
|
|
7
|
+
const TWITCH_TOKEN_URL = "https://id.twitch.tv/oauth2/token";
|
|
8
|
+
// Simple in-process token cache (resets on restart)
|
|
9
|
+
let cachedToken = null;
|
|
10
|
+
function getCredentials(args) {
|
|
11
|
+
const clientId = String(args.client_id ?? process.env.IGDB_CLIENT_ID ?? "").trim();
|
|
12
|
+
const clientSecret = String(args.client_secret ?? process.env.IGDB_CLIENT_SECRET ?? "").trim();
|
|
13
|
+
if (!clientId)
|
|
14
|
+
throw new Error("client_id is required (or set IGDB_CLIENT_ID env var).");
|
|
15
|
+
if (!clientSecret)
|
|
16
|
+
throw new Error("client_secret is required (or set IGDB_CLIENT_SECRET env var).");
|
|
17
|
+
return { clientId, clientSecret };
|
|
18
|
+
}
|
|
19
|
+
async function getTwitchToken(clientId, clientSecret) {
|
|
20
|
+
if (cachedToken && Date.now() < cachedToken.expires)
|
|
21
|
+
return cachedToken.token;
|
|
22
|
+
const res = await fetch(`${TWITCH_TOKEN_URL}?client_id=${encodeURIComponent(clientId)}&client_secret=${encodeURIComponent(clientSecret)}&grant_type=client_credentials`, { method: "POST" });
|
|
23
|
+
if (res.status === 400 || res.status === 401) {
|
|
24
|
+
throw new Error("Invalid IGDB credentials. Check your client_id and client_secret.");
|
|
25
|
+
}
|
|
26
|
+
if (!res.ok) {
|
|
27
|
+
const body = await res.text().catch(() => "");
|
|
28
|
+
throw new Error(`Twitch token request failed HTTP ${res.status}: ${body}`);
|
|
29
|
+
}
|
|
30
|
+
const json = await res.json();
|
|
31
|
+
const token = String(json.access_token ?? "");
|
|
32
|
+
const expiresIn = Number(json.expires_in ?? 3600);
|
|
33
|
+
cachedToken = { token, expires: Date.now() + (expiresIn - 60) * 1000 };
|
|
34
|
+
return token;
|
|
35
|
+
}
|
|
36
|
+
async function igdbPost(clientId, token, endpoint, body) {
|
|
37
|
+
const res = await fetch(`${IGDB_BASE}${endpoint}`, {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: {
|
|
40
|
+
"Client-ID": clientId,
|
|
41
|
+
Authorization: `Bearer ${token}`,
|
|
42
|
+
"Content-Type": "text/plain",
|
|
43
|
+
Accept: "application/json",
|
|
44
|
+
},
|
|
45
|
+
body,
|
|
46
|
+
});
|
|
47
|
+
if (res.status === 401) {
|
|
48
|
+
cachedToken = null;
|
|
49
|
+
throw new Error("IGDB token expired or invalid. Try again.");
|
|
50
|
+
}
|
|
51
|
+
if (res.status === 429)
|
|
52
|
+
throw new Error("IGDB rate limit exceeded.");
|
|
53
|
+
if (!res.ok) {
|
|
54
|
+
const b = await res.text().catch(() => "");
|
|
55
|
+
throw new Error(`IGDB HTTP ${res.status}: ${b || res.statusText}`);
|
|
56
|
+
}
|
|
57
|
+
return res.json();
|
|
58
|
+
}
|
|
59
|
+
// igdb_search_games
|
|
60
|
+
export async function igdbSearchGames(args) {
|
|
61
|
+
try {
|
|
62
|
+
const { clientId, clientSecret } = getCredentials(args);
|
|
63
|
+
const token = await getTwitchToken(clientId, clientSecret);
|
|
64
|
+
const query = String(args.query ?? "").trim();
|
|
65
|
+
if (!query)
|
|
66
|
+
return { error: "query is required." };
|
|
67
|
+
const limit = Math.min(Number(args.limit ?? 10), 50);
|
|
68
|
+
const body = `search "${query}"; fields id,name,summary,genres.name,platforms.name,release_dates.human,rating,rating_count,cover.url,url; limit ${limit};`;
|
|
69
|
+
return igdbPost(clientId, token, "/games", body);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// igdb_get_game
|
|
76
|
+
export async function igdbGetGame(args) {
|
|
77
|
+
try {
|
|
78
|
+
const { clientId, clientSecret } = getCredentials(args);
|
|
79
|
+
const token = await getTwitchToken(clientId, clientSecret);
|
|
80
|
+
const gameId = String(args.game_id ?? "").trim();
|
|
81
|
+
if (!gameId)
|
|
82
|
+
return { error: "game_id is required." };
|
|
83
|
+
const body = `fields id,name,summary,storyline,genres.name,platforms.name,involved_companies.company.name,involved_companies.developer,involved_companies.publisher,release_dates.human,rating,rating_count,aggregated_rating,aggregated_rating_count,cover.url,screenshots.url,websites.url,url; where id = ${gameId};`;
|
|
84
|
+
const result = await igdbPost(clientId, token, "/games", body);
|
|
85
|
+
return result[0] ?? { error: "Game not found." };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// igdb_list_platforms
|
|
92
|
+
export async function igdbListPlatforms(args) {
|
|
93
|
+
try {
|
|
94
|
+
const { clientId, clientSecret } = getCredentials(args);
|
|
95
|
+
const token = await getTwitchToken(clientId, clientSecret);
|
|
96
|
+
const limit = Math.min(Number(args.limit ?? 30), 500);
|
|
97
|
+
const offset = Number(args.offset ?? 0);
|
|
98
|
+
const body = `fields id,name,abbreviation,alternative_name,platform_family.name,generation; sort name asc; limit ${limit}; offset ${offset};`;
|
|
99
|
+
return igdbPost(clientId, token, "/platforms", body);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// igdb_list_genres
|
|
106
|
+
export async function igdbListGenres(args) {
|
|
107
|
+
try {
|
|
108
|
+
const { clientId, clientSecret } = getCredentials(args);
|
|
109
|
+
const token = await getTwitchToken(clientId, clientSecret);
|
|
110
|
+
const body = `fields id,name,slug,url; sort name asc; limit 50;`;
|
|
111
|
+
return igdbPost(clientId, token, "/genres", body);
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// igdb_get_company
|
|
118
|
+
export async function igdbGetCompany(args) {
|
|
119
|
+
try {
|
|
120
|
+
const { clientId, clientSecret } = getCredentials(args);
|
|
121
|
+
const token = await getTwitchToken(clientId, clientSecret);
|
|
122
|
+
const name = String(args.name ?? "").trim();
|
|
123
|
+
const companyId = String(args.company_id ?? "").trim();
|
|
124
|
+
if (!name && !companyId)
|
|
125
|
+
return { error: "Either name or company_id is required." };
|
|
126
|
+
let body;
|
|
127
|
+
if (companyId) {
|
|
128
|
+
body = `fields id,name,description,developed.name,published.name,country,start_date,websites.url,logo.url; where id = ${companyId};`;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
body = `fields id,name,description,developed.name,published.name,country,start_date,websites.url,logo.url; search "${name}"; limit 5;`;
|
|
132
|
+
}
|
|
133
|
+
const result = await igdbPost(clientId, token, "/companies", body);
|
|
134
|
+
return companyId ? (result[0] ?? { error: "Company not found." }) : result;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=igdb-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"igdb-tool.js","sourceRoot":"","sources":["../src/igdb-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypt a plaintext string using AES-256-GCM.
|
|
3
|
+
* Key is derived from the caller's UnClick API key via PBKDF2.
|
|
4
|
+
*/
|
|
5
|
+
export declare function encrypt(plaintext: string, apiKey: string): {
|
|
6
|
+
encrypted_value: string;
|
|
7
|
+
iv: string;
|
|
8
|
+
auth_tag: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Decrypt a value previously encrypted with encrypt().
|
|
12
|
+
*/
|
|
13
|
+
export declare function decrypt(encrypted_value: string, iv: string, auth_tag: string, apiKey: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the first 12 hex characters of the SHA-256 hash of the API key.
|
|
16
|
+
* Used as a human-readable namespace in logs and error messages.
|
|
17
|
+
*/
|
|
18
|
+
export declare function hashKey(apiKey: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the full SHA-256 hex hash of the API key.
|
|
21
|
+
* Used as the lookup key in Supabase (never store the raw API key).
|
|
22
|
+
*/
|
|
23
|
+
export declare function hashKeyFull(apiKey: string): string;
|
|
24
|
+
//# sourceMappingURL=keychain-crypto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain-crypto.d.ts","sourceRoot":"","sources":["../src/keychain-crypto.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAU3D;AAED;;GAEG;AACH,wBAAgB,OAAO,CACrB,eAAe,EAAE,MAAM,EACvB,EAAE,EAAe,MAAM,EACvB,QAAQ,EAAS,MAAM,EACvB,MAAM,EAAW,MAAM,GACtB,MAAM,CAQR;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// ─── Keychain Crypto ──────────────────────────────────────────────────────────
|
|
2
|
+
// AES-256-GCM encryption for platform credentials.
|
|
3
|
+
// Key derivation: PBKDF2 with a deterministic salt derived from the API key.
|
|
4
|
+
// No external dependencies - Node.js built-in crypto only.
|
|
5
|
+
import * as crypto from "crypto";
|
|
6
|
+
const PBKDF2_ITERATIONS = 100_000;
|
|
7
|
+
const KEY_BYTES = 32; // AES-256
|
|
8
|
+
const IV_BYTES = 12; // 96-bit IV recommended for GCM
|
|
9
|
+
// Deterministic salt: avoids storing a per-credential salt while still
|
|
10
|
+
// using PBKDF2 for slow key derivation. The secret material is the API key.
|
|
11
|
+
const KEYCHAIN_PEPPER = "unclick-keychain-v1";
|
|
12
|
+
function deriveKey(apiKey) {
|
|
13
|
+
const salt = crypto
|
|
14
|
+
.createHash("sha256")
|
|
15
|
+
.update(`${KEYCHAIN_PEPPER}:${apiKey}`)
|
|
16
|
+
.digest();
|
|
17
|
+
return crypto.pbkdf2Sync(apiKey, salt, PBKDF2_ITERATIONS, KEY_BYTES, "sha256");
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Encrypt a plaintext string using AES-256-GCM.
|
|
21
|
+
* Key is derived from the caller's UnClick API key via PBKDF2.
|
|
22
|
+
*/
|
|
23
|
+
export function encrypt(plaintext, apiKey) {
|
|
24
|
+
const key = deriveKey(apiKey);
|
|
25
|
+
const iv = crypto.randomBytes(IV_BYTES);
|
|
26
|
+
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
|
27
|
+
const enc = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
28
|
+
return {
|
|
29
|
+
encrypted_value: enc.toString("hex"),
|
|
30
|
+
iv: iv.toString("hex"),
|
|
31
|
+
auth_tag: cipher.getAuthTag().toString("hex"),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Decrypt a value previously encrypted with encrypt().
|
|
36
|
+
*/
|
|
37
|
+
export function decrypt(encrypted_value, iv, auth_tag, apiKey) {
|
|
38
|
+
const key = deriveKey(apiKey);
|
|
39
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", key, Buffer.from(iv, "hex"));
|
|
40
|
+
decipher.setAuthTag(Buffer.from(auth_tag, "hex"));
|
|
41
|
+
return Buffer.concat([
|
|
42
|
+
decipher.update(Buffer.from(encrypted_value, "hex")),
|
|
43
|
+
decipher.final(),
|
|
44
|
+
]).toString("utf8");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Returns the first 12 hex characters of the SHA-256 hash of the API key.
|
|
48
|
+
* Used as a human-readable namespace in logs and error messages.
|
|
49
|
+
*/
|
|
50
|
+
export function hashKey(apiKey) {
|
|
51
|
+
return crypto.createHash("sha256").update(apiKey).digest("hex").slice(0, 12);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns the full SHA-256 hex hash of the API key.
|
|
55
|
+
* Used as the lookup key in Supabase (never store the raw API key).
|
|
56
|
+
*/
|
|
57
|
+
export function hashKeyFull(apiKey) {
|
|
58
|
+
return crypto.createHash("sha256").update(apiKey).digest("hex");
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=keychain-crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain-crypto.js","sourceRoot":"","sources":["../src/keychain-crypto.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,mDAAmD;AACnD,6EAA6E;AAC7E,2DAA2D;AAE3D,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAClC,MAAM,SAAS,GAAW,EAAE,CAAC,CAAC,UAAU;AACxC,MAAM,QAAQ,GAAY,EAAE,CAAC,CAAC,gCAAgC;AAE9D,uEAAuE;AACvE,4EAA4E;AAC5E,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAE9C,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,IAAI,GAAG,MAAM;SAChB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,GAAG,eAAe,IAAI,MAAM,EAAE,CAAC;SACtC,MAAM,EAAE,CAAC;IACZ,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CACrB,SAAiB,EACjB,MAAc;IAEd,MAAM,GAAG,GAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,GAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAM,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACjF,OAAO;QACL,eAAe,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,EAAE,EAAe,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QACnC,QAAQ,EAAS,MAAM,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KACrD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CACrB,eAAuB,EACvB,EAAuB,EACvB,QAAuB,EACvB,MAAuB;IAEvB,MAAM,GAAG,GAAQ,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;IACrF,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACpD,QAAQ,CAAC,KAAK,EAAE;KACjB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SecureInputResult {
|
|
2
|
+
value: string;
|
|
3
|
+
source: "env" | "secure_input" | "direct";
|
|
4
|
+
}
|
|
5
|
+
export declare function checkEnvCredential(platform: string): string | null;
|
|
6
|
+
export declare function startSecureInputServer(platform: string, setupUrl?: string): number;
|
|
7
|
+
export declare function popResolvedCredential(platform: string): string | null;
|
|
8
|
+
export declare function hasActiveServer(platform: string): boolean;
|
|
9
|
+
export interface SecureConnectState {
|
|
10
|
+
status: "found_env" | "found_submitted" | "awaiting_input";
|
|
11
|
+
value?: string;
|
|
12
|
+
source?: "env" | "secure_input";
|
|
13
|
+
url?: string;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function resolveCredential(platform: string, setupUrl?: string): SecureConnectState;
|
|
17
|
+
//# sourceMappingURL=keychain-secure-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain-secure-input.d.ts","sourceRoot":"","sources":["../src/keychain-secure-input.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,cAAc,GAAG,QAAQ,CAAC;CAC3C;AAuED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUlE;AAuDD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA0DlF;AAGD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOrE;AAGD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAID,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAI,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC7D,KAAK,CAAC,EAAI,MAAM,CAAC;IACjB,MAAM,CAAC,EAAG,KAAK,GAAG,cAAc,CAAC;IACjC,GAAG,CAAC,EAAM,MAAM,CAAC;IACjB,OAAO,EAAG,MAAM,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA8BzF"}
|