@orchyn/mcp 1.12.1 → 1.12.3

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.
@@ -11,7 +11,7 @@ import { OrchynError } from "./orchyn.js";
11
11
  import { formatPaywallError, runVideoAnalysis, validatePostUrl } from "./video.js";
12
12
  import { ORCHYN_UI_TEMPLATE } from "./ui-template.js";
13
13
  /** Current MCP server version — bumped on every deploy for traceability. */
14
- export const MCP_SERVER_VERSION = "1.12.1";
14
+ export const MCP_SERVER_VERSION = "1.12.2";
15
15
  /** MCP Apps extension identifier */
16
16
  const UI_EXTENSION = "io.modelcontextprotocol/ui";
17
17
  /** MIME type for MCP Apps HTML resources */
@@ -36,10 +36,13 @@ export const ORCHYN_UI_TEMPLATE = `<!DOCTYPE html>
36
36
  body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--bg);color:var(--fg);padding:16px;line-height:1.5;}
37
37
 
38
38
  /* ─── Loading / Skeleton ─── */
39
- .loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;gap:16px;}
40
- .loading-spinner{width:32px;height:32px;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite;}
39
+ .loading-container{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;gap:12px;}
40
+ .orchyn-logo{animation:logoSpin 3s ease-in-out infinite;}
41
+ @keyframes logoSpin{0%,100%{transform:rotate(0deg) scale(1)}50%{transform:rotate(180deg) scale(1.1)}}
42
+ .loading-brand{font-size:18px;font-weight:700;letter-spacing:-0.02em;color:var(--fg);}
43
+ .loading-spinner{width:28px;height:28px;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite;}
41
44
  @keyframes spin{to{transform:rotate(360deg)}}
42
- .loading-text{font-size:14px;color:var(--muted);animation:pulse 1.5s ease-in-out infinite;}
45
+ .loading-text{font-size:13px;color:var(--muted);animation:pulse 1.5s ease-in-out infinite;}
43
46
  @keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
44
47
 
45
48
  .skeleton{background:var(--tag);border-radius:var(--radius-sm);overflow:hidden;position:relative;}
@@ -165,14 +168,30 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
165
168
  <body>
166
169
  <div id="app">
167
170
  <div class="loading-container">
168
- <div class="loading-spinner"></div>
169
- <div class="loading-text">Loading results…</div>
171
+ <div class="orchyn-logo">
172
+ <svg width="40" height="40" viewBox="0 0 48 48" fill="none">
173
+ <g fill="var(--accent)" transform="translate(24 24)">
174
+ <circle r="4.1"/>
175
+ <g id="r"><path d="M-2.85 -5.2 L0 -20.6 L2.85 -5.2 L1.15 1.1 L-1.15 1.1 Z"/></g>
176
+ <use href="#r" transform="rotate(45)"/>
177
+ <use href="#r" transform="rotate(90)"/>
178
+ <use href="#r" transform="rotate(135)"/>
179
+ <use href="#r" transform="rotate(180)"/>
180
+ <use href="#r" transform="rotate(225)"/>
181
+ <use href="#r" transform="rotate(270)"/>
182
+ <use href="#r" transform="rotate(315)"/>
183
+ </g>
184
+ </svg>
185
+ </div>
186
+ <div class="loading-brand">Orchyn</div>
187
+ <div class="loading-text">Analyzing…</div>
170
188
  </div>
171
189
  </div>
172
190
  <script>
173
191
  (function(){
174
192
  var nextId=1;var pending=new Map();
175
193
  var loadingTimer=null;
194
+ var currentTool="";
176
195
 
177
196
  function send(method,params){
178
197
  var id=nextId++;
@@ -182,6 +201,7 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
182
201
  });
183
202
  }
184
203
 
204
+ var toolResultReceived=false;
185
205
  window.addEventListener("message",function(ev){
186
206
  var d=ev.data;if(!d||typeof d!=="object")return;
187
207
  if(d.id&&pending.has(d.id)){
@@ -190,10 +210,13 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
190
210
  else p.resolve(d.result);return;
191
211
  }
192
212
  if(d.method==="ui/notifications/tool-result"){
213
+ toolResultReceived=true;
193
214
  clearTimeout(loadingTimer);
215
+ clearTimeout(fallbackTimer);
194
216
  render(d.params);
195
217
  }
196
218
  if(d.method==="ui/notifications/tool-input-partial"){
219
+ currentTool=d.params&&d.params.name?d.params.name:"";
197
220
  updateProgress(d.params);
198
221
  }
199
222
  });
@@ -201,9 +224,39 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
201
224
  // Show skeleton after 300ms of waiting (feels instant but shows loading for slow tools)
202
225
  loadingTimer=setTimeout(function(){
203
226
  var app=document.getElementById("app");
204
- if(app)app.innerHTML=renderSkeleton();
227
+ if(app)app.innerHTML=renderSkeleton(currentTool);
205
228
  },300);
206
229
 
230
+ // Fallback: if no tool-result arrives within 3s, check if data is embedded
231
+ // in the page (some hosts pass structuredContent via URL hash or postMessage)
232
+ var fallbackTimer=setTimeout(function(){
233
+ if(toolResultReceived)return;
234
+ // Try to extract data from URL hash (host may pass structuredContent here)
235
+ try{
236
+ var hash=window.location.hash.slice(1);
237
+ if(hash){
238
+ var decoded=JSON.parse(decodeURIComponent(hash));
239
+ if(decoded&&typeof decoded==="object"){render(decoded);return;}
240
+ }
241
+ }catch(e){}
242
+ // Try to extract from URL search params
243
+ try{
244
+ var params=new URLSearchParams(window.location.search);
245
+ var dataParam=params.get("data");
246
+ if(dataParam){
247
+ var decoded=JSON.parse(decodeURIComponent(dataParam));
248
+ if(decoded&&typeof decoded==="object"){render(decoded);return;}
249
+ }
250
+ }catch(e){}
251
+ // Last resort: show a branded card indicating results are available
252
+ var app=document.getElementById("app");
253
+ if(app)app.innerHTML='<div class="card card-wide fade-in"><div class="card-body" style="text-align:center;padding:24px">'
254
+ +'<svg width="28" height="28" viewBox="0 0 48 48" fill="none" style="margin-bottom:8px"><g fill="var(--accent)" transform="translate(24 24)"><circle r="4.1"/><g id="rf"><path d="M-2.85 -5.2 L0 -20.6 L2.85 -5.2 L1.15 1.1 L-1.15 1.1 Z"/></g><use href="#rf" transform="rotate(45)"/><use href="#rf" transform="rotate(90)"/><use href="#rf" transform="rotate(135)"/><use href="#rf" transform="rotate(180)"/><use href="#rf" transform="rotate(225)"/><use href="#rf" transform="rotate(270)"/><use href="#rf" transform="rotate(315)"/></g></svg>'
255
+ +'<div style="font-size:14px;font-weight:600;margin-bottom:4px">✅ Results ready</div>'
256
+ +'<div style="font-size:12px;color:var(--muted)">Orchyn analysis complete — see the full response in the chat.</div>'
257
+ +'</div></div>';
258
+ },3000);
259
+
207
260
  // MCP Apps handshake
208
261
  send("ui/initialize",{
209
262
  protocolVersion:"2026-01-26",
@@ -224,9 +277,46 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
224
277
  }
225
278
 
226
279
  // ─── Skeleton ───
227
- function renderSkeleton(){
228
- return '<div class="skeleton-gallery stagger">'
229
- +Array(3).fill(0).map(function(){
280
+ // Tools that analyze/fetch a single URL: show 1 wide card skeleton
281
+ var SINGLE_URL_TOOLS={analyze_post:1,get_social_media:1,understand_social_post:1,get_post_comments:1,analyze_creator_profile:1};
282
+ // Tools that return galleries: show multiple small card skeletons
283
+ var GALLERY_TOOLS={discover_social_posts:1,get_user_posts:1,search_creators:1,get_similar_creators:1,discover_sounds:1};
284
+ // Tools that return credits/checkout: show 1 credit card skeleton
285
+ var CREDIT_TOOLS={check_orchyn_credits:1,buy_orchyn_credits:1};
286
+
287
+ function renderSkeleton(toolName){
288
+ // Branded header above skeletons
289
+ var brandHeader='<div style="display:flex;align-items:center;gap:8px;margin-bottom:14px;justify-content:center">'
290
+ +'<svg width="20" height="20" viewBox="0 0 48 48" fill="none"><g fill="var(--accent)" transform="translate(24 24)"><circle r="4.1"/><g id="sb"><path d="M-2.85 -5.2 L0 -20.6 L2.85 -5.2 L1.15 1.1 L-1.15 1.1 Z"/></g><use href="#sb" transform="rotate(45)"/><use href="#sb" transform="rotate(90)"/><use href="#sb" transform="rotate(135)"/><use href="#sb" transform="rotate(180)"/><use href="#sb" transform="rotate(225)"/><use href="#sb" transform="rotate(270)"/><use href="#sb" transform="rotate(315)"/></g></svg>'
291
+ +'<span style="font-size:13px;font-weight:600;color:var(--muted)">Orchyn</span></div>';
292
+ // Single URL tools → 1 wide card skeleton
293
+ if(SINGLE_URL_TOOLS[toolName]){
294
+ return brandHeader+'<div class="fade-in" style="max-width:520px">'
295
+ +'<div class="skeleton-card" style="width:100%">'
296
+ +'<div class="skeleton skeleton-thumb" style="height:220px"></div>'
297
+ +'<div style="padding:14px 16px">'
298
+ +'<div class="skeleton skeleton-badge"></div>'
299
+ +'<div class="skeleton skeleton-line" style="width:90%"></div>'
300
+ +'<div class="skeleton skeleton-line medium"></div>'
301
+ +'<div style="display:flex;gap:6px;margin-top:10px">'
302
+ +'<div class="skeleton" style="width:70px;height:28px;border-radius:999px"></div>'
303
+ +'<div class="skeleton" style="width:60px;height:28px;border-radius:999px"></div>'
304
+ +'<div class="skeleton" style="width:65px;height:28px;border-radius:999px"></div>'
305
+ +'</div></div></div></div>';
306
+ }
307
+ // Credit tools → credit card skeleton
308
+ if(CREDIT_TOOLS[toolName]){
309
+ return brandHeader+'<div class="fade-in" style="max-width:380px">'
310
+ +'<div class="credits-card" style="margin:0">'
311
+ +'<div class="skeleton" style="width:120px;height:20px;margin-bottom:14px"></div>'
312
+ +'<div class="skeleton" style="width:80px;height:40px;margin-bottom:8px"></div>'
313
+ +'<div class="skeleton" style="width:140px;height:14px"></div>'
314
+ +'</div></div>';
315
+ }
316
+ // Gallery tools → multiple small card skeletons (default)
317
+ var count=toolName==='discover_sounds'?4:toolName==='search_creators'||toolName==='get_similar_creators'?3:6;
318
+ return brandHeader+'<div class="skeleton-gallery stagger">'
319
+ +Array(count).fill(0).map(function(){
230
320
  return '<div class="skeleton-card">'
231
321
  +'<div class="skeleton skeleton-thumb"></div>'
232
322
  +'<div class="skeleton skeleton-badge"></div>'
@@ -404,9 +494,21 @@ body{font-family:system-ui,-apple-system,'Segoe UI',sans-serif;background:var(--
404
494
  function updateProgress(params){
405
495
  var app=document.getElementById("app");
406
496
  if(!app)return;
497
+ // If we just learned the tool name and the current skeleton is wrong,
498
+ // re-render with the correct skeleton type
499
+ var toolName=params&&params.name?params.name:currentTool;
500
+ if(toolName&&toolName!==currentTool){
501
+ currentTool=toolName;
502
+ // Only re-render skeleton if we're still in loading state (no result yet)
503
+ var el=document.getElementById("app");
504
+ if(el&&(el.querySelector(".loading-spinner")||el.querySelector(".skeleton"))){
505
+ el.innerHTML=renderSkeleton(currentTool);
506
+ }
507
+ }
407
508
  var text=params&&params.arguments?JSON.stringify(params.arguments):"Processing…";
408
509
  app.innerHTML='<div class="loading-container fade-in">'
409
- +'<div class="loading-spinner"></div>'
510
+ +'<div class="orchyn-logo"><svg width="36" height="36" viewBox="0 0 48 48" fill="none"><g fill="var(--accent)" transform="translate(24 24)"><circle r="4.1"/><g id="rp"><path d="M-2.85 -5.2 L0 -20.6 L2.85 -5.2 L1.15 1.1 L-1.15 1.1 Z"/></g><use href="#rp" transform="rotate(45)"/><use href="#rp" transform="rotate(90)"/><use href="#rp" transform="rotate(135)"/><use href="#rp" transform="rotate(180)"/><use href="#rp" transform="rotate(225)"/><use href="#rp" transform="rotate(270)"/><use href="#rp" transform="rotate(315)"/></g></svg></div>'
511
+ +'<div class="loading-brand">Orchyn</div>'
410
512
  +'<div class="loading-text">'+esc(text.length>80?text.slice(0,80)+"…":text)+'</div>'
411
513
  +'<div class="progress-bar" style="width:200px"><div class="progress-fill" style="width:60%"></div></div>'
412
514
  +'</div>';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchyn/mcp",
3
- "version": "1.12.1",
3
+ "version": "1.12.3",
4
4
  "description": "MCP server for orchyn - fetch, discover and understand TikTok/Instagram/YouTube/X posts with AI (media metadata, niche discovery, hook & viral analysis)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",