@orchyn/mcp 1.2.1 → 1.3.0
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 +3 -4
- package/dist/index.js +8 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,9 +39,8 @@ npx @orchyn/mcp login # one-time sign-in (Google)
|
|
|
39
39
|
| Tool | Credits | Description |
|
|
40
40
|
|------|---------|-------------|
|
|
41
41
|
| `analyze_post` | first free* | **Preferred.** Analyze any post (video, image, carousel/slideshow) from a TikTok/Instagram/YouTube/X-Twitter URL — imports the media and runs AI analysis over the actual content (video frames, carousel images, caption). Returns a `jobId` to poll via `GET /ai/analyze-post`. *First analysis free per workspace via the dashboard free grant.* |
|
|
42
|
-
| `analyze_video` | first free* | **Deprecated alias of `analyze_post`** — kept for backwards compatibility. Use `analyze_post` for new integrations. |
|
|
43
42
|
| `get_social_media` | 1 | Fetch a post's media from a URL: `contentType` (video/image/carousel/slideshow), title, caption, author, stats, direct media URLs **+ inline thumbnail image in chat**. |
|
|
44
|
-
| `
|
|
43
|
+
| `discover_social_posts` | 2 | **Preferred.** Find recent posts (video/image/carousel/slideshow) for a niche (YouTube via `yt-dlp` search; TikTok/Instagram via Apify). Each post includes title/caption, views/likes/comments, author, `externalUrl` + **inline thumbnails (4 at a time)** — see *Images in chat* below. Supports `limit`/`offset` pagination (“next”). |
|
|
45
44
|
| `understand_social_post` | 10 | Import a post URL **and** analyze it with multimodal AI over the actual video/images: factual `whatHappens` description, hook strength, viral triggers, format breakdown, variation ideas, suggested hook/hashtags. Includes inline thumbnails. |
|
|
46
45
|
|
|
47
46
|
All tools require a connected orchyn account and are billed against your orchyn credit balance (`POST /billing/mcp-credits/checkout` tops up).
|
|
@@ -53,8 +52,8 @@ All tools require a connected orchyn account and are billed against your orchyn
|
|
|
53
52
|
Every tool that returns posts also renders **inline thumbnails** directly in the chat:
|
|
54
53
|
|
|
55
54
|
- `get_social_media` / `understand_social_post` / `analyze_post` — up to 4 frames inline (poster + carousel slides). The full `mediaItems[].preview_url` + `thumbnailUrl` stay in `structuredContent` for the model to reason over.
|
|
56
|
-
- `
|
|
57
|
-
- **Batch analysis** — ask "analyze all 4" or "understand these 3 in batch" and Claude will call `analyze_post`/`understand_social_post` once per URL in parallel and summarize. For large batches, `
|
|
55
|
+
- `discover_social_posts` — each discovered post shows its thumbnail inline (up to 4 of the 6 results at once) together with its title/caption + views/likes/comments. Say **"next"** or **"show more"** — Claude will re-call `discover_social_posts` with `offset` pagination. Say **"analyze the 2nd one"** — Claude calls `analyze_post` or `understand_social_post` on that URL.
|
|
56
|
+
- **Batch analysis** — ask "analyze all 4" or "understand these 3 in batch" and Claude will call `analyze_post`/`understand_social_post` once per URL in parallel and summarize. For large batches, `discover_social_posts` + a follow-up `analyze_post` per URL is the recommended flow.
|
|
58
57
|
|
|
59
58
|
> The backend's `analyze_post` now watches the **actual video/images** (direct MP4, YouTube `fileUri`, or 6 carousel frames via Gemini multimodal) — not just the caption. The analysis includes a `whatHappens` field describing exactly what is seen.
|
|
60
59
|
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* orchyn-mcp — MCP server exposing
|
|
3
|
+
* orchyn-mcp — MCP server exposing `analyze_post` (analyze any post: video/image/carousel) that runs
|
|
4
4
|
* AI video analysis through the user's orchyn account.
|
|
5
5
|
*
|
|
6
6
|
* Modes:
|
|
@@ -77,42 +77,6 @@ export function createServer(opts) {
|
|
|
77
77
|
return { content: [{ type: "text", text: `Analysis failed: ${msg}` }], isError: true };
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
|
-
server.registerTool("analyze_video", {
|
|
81
|
-
title: "Analyze Video",
|
|
82
|
-
description: "[Deprecated — use analyze_post] Alias of analyze_post — analyzes any post type.",
|
|
83
|
-
inputSchema: z
|
|
84
|
-
.object({
|
|
85
|
-
url: z.string().describe("Public post URL (TikTok/Instagram/YouTube/X or shortlinks)."),
|
|
86
|
-
})
|
|
87
|
-
.strict(),
|
|
88
|
-
}, async (args, extra) => {
|
|
89
|
-
let session;
|
|
90
|
-
if (extra.authInfo?.token && opts.resolveSession) {
|
|
91
|
-
session = opts.resolveSession(extra.authInfo.token);
|
|
92
|
-
}
|
|
93
|
-
const client = opts.makeClient(session);
|
|
94
|
-
const validation = validatePostUrl(args.url);
|
|
95
|
-
if (!validation.ok) {
|
|
96
|
-
return {
|
|
97
|
-
content: [{ type: "text", text: `Invalid url: ${validation.error}` }],
|
|
98
|
-
isError: true,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
try {
|
|
102
|
-
const result = await runVideoAnalysis(client, validation.url);
|
|
103
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
if (err instanceof OrchynError && err.paywall) {
|
|
107
|
-
return {
|
|
108
|
-
content: [{ type: "text", text: `Analysis blocked: ${formatPaywallError(err)}\n\nHTTP ${err.status}: ${err.message}` }],
|
|
109
|
-
isError: true,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
113
|
-
return { content: [{ type: "text", text: `Analysis failed: ${msg}` }], isError: true };
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
80
|
server.registerTool("get_social_media", {
|
|
117
81
|
title: "Get Social Media",
|
|
118
82
|
description: "Fetch a social post's media from a TikTok, Instagram, YouTube or X/Twitter URL: " +
|
|
@@ -132,11 +96,11 @@ export function createServer(opts) {
|
|
|
132
96
|
return toolError("get_social_media failed", err);
|
|
133
97
|
}
|
|
134
98
|
});
|
|
135
|
-
server.registerTool("
|
|
136
|
-
title: "Discover Social
|
|
137
|
-
description: "Discover recent
|
|
138
|
-
"
|
|
139
|
-
"or \"analyze the 2nd one\" / \"analyze all\" for batch analysis. Consumes 2 orchyn credits.",
|
|
99
|
+
server.registerTool("discover_social_posts", {
|
|
100
|
+
title: "Discover Social Posts",
|
|
101
|
+
description: "Discover recent posts (video, image, carousel, slideshow) for a niche. YouTube via search; TikTok & Instagram via Apify. " +
|
|
102
|
+
"Each post includes title/caption, thumbnailUrl, externalUrl, views/likes/comments and inline thumbnails (up to 4) so they show in chat. " +
|
|
103
|
+
"Say \"next\" to paginate (offset), or \"analyze the 2nd one\" / \"analyze all\" for batch analysis. Consumes 2 orchyn credits.",
|
|
140
104
|
inputSchema: z
|
|
141
105
|
.object({
|
|
142
106
|
niche: z.string().describe("Niche/topic, e.g. 'fitness'."),
|
|
@@ -152,10 +116,10 @@ export function createServer(opts) {
|
|
|
152
116
|
}, async (args, extra) => {
|
|
153
117
|
const client = makeClientFor(extra, opts);
|
|
154
118
|
try {
|
|
155
|
-
return toToolResult(await client.callTool("
|
|
119
|
+
return toToolResult(await client.callTool("discover_social_posts", { ...args }));
|
|
156
120
|
}
|
|
157
121
|
catch (err) {
|
|
158
|
-
return toolError("
|
|
122
|
+
return toolError("discover_social_posts failed", err);
|
|
159
123
|
}
|
|
160
124
|
});
|
|
161
125
|
server.registerTool("understand_social_post", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchyn/mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
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",
|