@feedmob/ai-video-hub 1.0.1
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 +102 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# FeedMob AI Video Hub MCP Server
|
|
2
|
+
|
|
3
|
+
stdio MCP server for managing AI video entries via FeedMob Rails API.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Environment Variables
|
|
12
|
+
|
|
13
|
+
| Variable | Required | Description |
|
|
14
|
+
|----------|----------|-------------|
|
|
15
|
+
| `FEEDMOB_ACCESS_TOKEN` | Yes | OAuth access token for Rails API |
|
|
16
|
+
| `RAILS_BASE_URL` | No | Rails API base URL (default: `https://insights-mcp.feedmob.com`) |
|
|
17
|
+
|
|
18
|
+
## MCP Client Configuration
|
|
19
|
+
|
|
20
|
+
### Claude Desktop / Claude Code
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"mcpServers": {
|
|
25
|
+
"feedmob-ai-video-hub": {
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["-y", "@feedmob/ai-video-hub"],
|
|
28
|
+
"env": {
|
|
29
|
+
"FEEDMOB_ACCESS_TOKEN": "your_token_here",
|
|
30
|
+
"RAILS_BASE_URL": "http://localhost:3000"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Tools
|
|
38
|
+
|
|
39
|
+
### list_ai_videos
|
|
40
|
+
|
|
41
|
+
List AI video entries with optional filters.
|
|
42
|
+
|
|
43
|
+
**Parameters:**
|
|
44
|
+
- `client_name` (string, optional): Filter by exact client name
|
|
45
|
+
- `creator_id` (number, optional): Filter by creator user id
|
|
46
|
+
- `status` (string, optional): `draft`, `reviewing`, `ready`, `archived`
|
|
47
|
+
- `title_query` (string, optional): Case-insensitive title search
|
|
48
|
+
- `limit` (number, optional): Max results (1-100, default: 25)
|
|
49
|
+
|
|
50
|
+
### get_ai_video
|
|
51
|
+
|
|
52
|
+
Fetch a single AI video entry.
|
|
53
|
+
|
|
54
|
+
**Parameters:**
|
|
55
|
+
- `id` (number, required): AI video id
|
|
56
|
+
|
|
57
|
+
### create_ai_video
|
|
58
|
+
|
|
59
|
+
Create a new AI video entry. Optionally upload a video file from local filesystem.
|
|
60
|
+
|
|
61
|
+
**Parameters:**
|
|
62
|
+
- `title` (string, required): Video title
|
|
63
|
+
- `client_name` (string, required): Client name
|
|
64
|
+
- `status` (string, required): `draft`, `reviewing`, `ready`, `archived`
|
|
65
|
+
- `duration_seconds` (number, optional): Duration in seconds
|
|
66
|
+
- `published_on` (string, optional): ISO date
|
|
67
|
+
- `source_research_markdown` (string, optional): Markdown source notes
|
|
68
|
+
- `design_rationale_markdown` (string, optional): Markdown design rationale
|
|
69
|
+
- `production_notes_markdown` (string, optional): Markdown production notes
|
|
70
|
+
- `references` (array, optional): Structured references
|
|
71
|
+
- `video_path` (string, optional): Local path to video file to upload
|
|
72
|
+
|
|
73
|
+
### update_ai_videos
|
|
74
|
+
|
|
75
|
+
Update one or more AI video entries in bulk. Optionally upload a new video file.
|
|
76
|
+
|
|
77
|
+
**Parameters:**
|
|
78
|
+
- `ids` (number[], required): AI video ids to update
|
|
79
|
+
- `status` (string, optional): New workflow status
|
|
80
|
+
- `client_name` (string, optional): New client name
|
|
81
|
+
- `published_on` (string, optional): ISO date
|
|
82
|
+
- `source_research_markdown` (string, optional): Markdown source notes
|
|
83
|
+
- `design_rationale_markdown` (string, optional): Markdown design rationale
|
|
84
|
+
- `production_notes_markdown` (string, optional): Markdown production notes
|
|
85
|
+
- `video_path` (string, optional): Local path to video file to upload
|
|
86
|
+
|
|
87
|
+
### delete_ai_videos
|
|
88
|
+
|
|
89
|
+
Delete one or more AI video entries.
|
|
90
|
+
|
|
91
|
+
**Parameters:**
|
|
92
|
+
- `ids` (number[], required): AI video ids to delete
|
|
93
|
+
|
|
94
|
+
## File Upload Flow
|
|
95
|
+
|
|
96
|
+
When creating or updating videos with a local file:
|
|
97
|
+
|
|
98
|
+
1. MCP server reads the local file from `video_path`
|
|
99
|
+
2. Uploads file to Rails API (`POST /ai-video-hub/api/videos/upload`)
|
|
100
|
+
3. Rails stores file in S3 and returns blob key
|
|
101
|
+
4. MCP server calls create/update API with the blob key
|
|
102
|
+
5. Rails attaches the uploaded file to the video record
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { FastMCP } from "fastmcp";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
const RAILS_BASE = process.env.RAILS_BASE_URL || "https://insights-mcp.feedmob.com";
|
|
7
|
+
const ACCESS_TOKEN = process.env.FEEDMOB_ACCESS_TOKEN;
|
|
8
|
+
if (!ACCESS_TOKEN) {
|
|
9
|
+
console.error("Error: FEEDMOB_ACCESS_TOKEN environment variable is required");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
// Helper function to call Rails API
|
|
13
|
+
async function callRailsApi(path, options = {}) {
|
|
14
|
+
const url = `${RAILS_BASE}${path}`;
|
|
15
|
+
const headers = {
|
|
16
|
+
Authorization: `Bearer ${ACCESS_TOKEN}`,
|
|
17
|
+
Accept: "application/json",
|
|
18
|
+
...options.headers,
|
|
19
|
+
};
|
|
20
|
+
if (!(options.body instanceof FormData)) {
|
|
21
|
+
headers["Content-Type"] = "application/json";
|
|
22
|
+
}
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
...options,
|
|
25
|
+
headers,
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const errorText = await response.text();
|
|
29
|
+
throw new Error(`Rails API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
30
|
+
}
|
|
31
|
+
return response.json();
|
|
32
|
+
}
|
|
33
|
+
// Upload file to Rails API
|
|
34
|
+
async function uploadFile(filePath) {
|
|
35
|
+
const resolvedPath = path.resolve(filePath);
|
|
36
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
37
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
38
|
+
}
|
|
39
|
+
const fileBuffer = fs.readFileSync(resolvedPath);
|
|
40
|
+
const fileName = path.basename(resolvedPath);
|
|
41
|
+
// Determine content type
|
|
42
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
43
|
+
const contentTypes = {
|
|
44
|
+
".mp4": "video/mp4",
|
|
45
|
+
".mov": "video/quicktime",
|
|
46
|
+
".avi": "video/x-msvideo",
|
|
47
|
+
".mkv": "video/x-matroska",
|
|
48
|
+
".webm": "video/webm",
|
|
49
|
+
".gif": "image/gif",
|
|
50
|
+
".jpg": "image/jpeg",
|
|
51
|
+
".jpeg": "image/jpeg",
|
|
52
|
+
".png": "image/png",
|
|
53
|
+
};
|
|
54
|
+
const contentType = contentTypes[ext] || "application/octet-stream";
|
|
55
|
+
const formData = new FormData();
|
|
56
|
+
const blob = new Blob([fileBuffer], { type: contentType });
|
|
57
|
+
formData.append("file", blob, fileName);
|
|
58
|
+
const url = `${RAILS_BASE}/ai-video-hub/api/videos/upload`;
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: {
|
|
62
|
+
Authorization: `Bearer ${ACCESS_TOKEN}`,
|
|
63
|
+
},
|
|
64
|
+
body: formData,
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorText = await response.text();
|
|
68
|
+
throw new Error(`Upload failed: ${response.status} - ${errorText}`);
|
|
69
|
+
}
|
|
70
|
+
return response.json();
|
|
71
|
+
}
|
|
72
|
+
// Create MCP Server
|
|
73
|
+
const server = new FastMCP({
|
|
74
|
+
name: "feedmob-ai-video-hub",
|
|
75
|
+
version: "1.0.1",
|
|
76
|
+
});
|
|
77
|
+
// Tool: list_ai_videos
|
|
78
|
+
server.addTool({
|
|
79
|
+
name: "list_ai_videos",
|
|
80
|
+
description: "List AI video entries with optional filters for client, creator, status, and title.",
|
|
81
|
+
parameters: z.object({
|
|
82
|
+
client_name: z.string().optional().describe("Filter by exact client name"),
|
|
83
|
+
creator_id: z.number().optional().describe("Filter by creator user id"),
|
|
84
|
+
status: z
|
|
85
|
+
.enum(["draft", "reviewing", "ready", "archived"])
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("Filter by workflow status"),
|
|
88
|
+
title_query: z
|
|
89
|
+
.string()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Case-insensitive title search"),
|
|
92
|
+
limit: z
|
|
93
|
+
.number()
|
|
94
|
+
.min(1)
|
|
95
|
+
.max(100)
|
|
96
|
+
.optional()
|
|
97
|
+
.describe("Max number of videos to return"),
|
|
98
|
+
}),
|
|
99
|
+
execute: async (args) => {
|
|
100
|
+
const params = new URLSearchParams();
|
|
101
|
+
if (args.client_name)
|
|
102
|
+
params.set("client_name", args.client_name);
|
|
103
|
+
if (args.creator_id)
|
|
104
|
+
params.set("creator_id", String(args.creator_id));
|
|
105
|
+
if (args.status)
|
|
106
|
+
params.set("status", args.status);
|
|
107
|
+
if (args.title_query)
|
|
108
|
+
params.set("title_query", args.title_query);
|
|
109
|
+
if (args.limit)
|
|
110
|
+
params.set("limit", String(args.limit));
|
|
111
|
+
const data = await callRailsApi(`/ai-video-hub/api/videos?${params.toString()}`);
|
|
112
|
+
return JSON.stringify(data, null, 2);
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
// Tool: get_ai_video
|
|
116
|
+
server.addTool({
|
|
117
|
+
name: "get_ai_video",
|
|
118
|
+
description: "Fetch a single AI video entry with markdown notes and structured references.",
|
|
119
|
+
parameters: z.object({
|
|
120
|
+
id: z.number().describe("AI video id"),
|
|
121
|
+
}),
|
|
122
|
+
execute: async (args) => {
|
|
123
|
+
const data = await callRailsApi(`/ai-video-hub/api/videos/${args.id}`);
|
|
124
|
+
return JSON.stringify(data, null, 2);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
// Tool: create_ai_video
|
|
128
|
+
server.addTool({
|
|
129
|
+
name: "create_ai_video",
|
|
130
|
+
description: "Create a new AI video entry with metadata, markdown notes, and structured references. Optionally upload a video file from local filesystem.",
|
|
131
|
+
parameters: z.object({
|
|
132
|
+
title: z.string().describe("Video title"),
|
|
133
|
+
client_name: z.string().describe("Client name"),
|
|
134
|
+
status: z
|
|
135
|
+
.enum(["draft", "reviewing", "ready", "archived"])
|
|
136
|
+
.describe("Workflow status"),
|
|
137
|
+
duration_seconds: z.number().optional().describe("Duration in seconds"),
|
|
138
|
+
published_on: z.string().optional().describe("ISO date"),
|
|
139
|
+
source_research_markdown: z
|
|
140
|
+
.string()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe("Markdown source notes"),
|
|
143
|
+
design_rationale_markdown: z
|
|
144
|
+
.string()
|
|
145
|
+
.optional()
|
|
146
|
+
.describe("Markdown design rationale"),
|
|
147
|
+
production_notes_markdown: z
|
|
148
|
+
.string()
|
|
149
|
+
.optional()
|
|
150
|
+
.describe("Markdown production notes"),
|
|
151
|
+
references: z
|
|
152
|
+
.array(z.object({
|
|
153
|
+
title: z.string().optional(),
|
|
154
|
+
url: z.string().optional(),
|
|
155
|
+
source_kind: z.string().optional(),
|
|
156
|
+
notes: z.string().optional(),
|
|
157
|
+
position: z.number().optional(),
|
|
158
|
+
}))
|
|
159
|
+
.optional()
|
|
160
|
+
.describe("Structured references"),
|
|
161
|
+
video_path: z
|
|
162
|
+
.string()
|
|
163
|
+
.optional()
|
|
164
|
+
.describe("Local path to video file to upload"),
|
|
165
|
+
}),
|
|
166
|
+
execute: async (args) => {
|
|
167
|
+
let videoBlobKey;
|
|
168
|
+
// Upload file if path provided
|
|
169
|
+
if (args.video_path) {
|
|
170
|
+
console.error(`Uploading file: ${args.video_path}`);
|
|
171
|
+
const uploadResult = await uploadFile(args.video_path);
|
|
172
|
+
videoBlobKey = uploadResult.key;
|
|
173
|
+
console.error(`Uploaded: ${uploadResult.filename} (key: ${uploadResult.key})`);
|
|
174
|
+
}
|
|
175
|
+
const { video_path, ...videoData } = args;
|
|
176
|
+
const data = await callRailsApi("/ai-video-hub/api/videos", {
|
|
177
|
+
method: "POST",
|
|
178
|
+
body: JSON.stringify({
|
|
179
|
+
ai_video: {
|
|
180
|
+
title: videoData.title,
|
|
181
|
+
client_name: videoData.client_name,
|
|
182
|
+
status: videoData.status,
|
|
183
|
+
duration_seconds: videoData.duration_seconds,
|
|
184
|
+
published_on: videoData.published_on,
|
|
185
|
+
source_research_markdown: videoData.source_research_markdown,
|
|
186
|
+
design_rationale_markdown: videoData.design_rationale_markdown,
|
|
187
|
+
production_notes_markdown: videoData.production_notes_markdown,
|
|
188
|
+
ai_video_references_attributes: videoData.references,
|
|
189
|
+
},
|
|
190
|
+
video_blob_key: videoBlobKey,
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
return JSON.stringify(data, null, 2);
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
// Tool: update_ai_videos
|
|
197
|
+
server.addTool({
|
|
198
|
+
name: "update_ai_videos",
|
|
199
|
+
description: "Update one or more AI video entries in bulk. Optionally upload a new video file.",
|
|
200
|
+
parameters: z.object({
|
|
201
|
+
ids: z.array(z.number()).describe("AI video ids to update"),
|
|
202
|
+
status: z
|
|
203
|
+
.enum(["draft", "reviewing", "ready", "archived"])
|
|
204
|
+
.optional()
|
|
205
|
+
.describe("New workflow status"),
|
|
206
|
+
client_name: z.string().optional().describe("New client name"),
|
|
207
|
+
published_on: z.string().optional().describe("ISO date"),
|
|
208
|
+
source_research_markdown: z
|
|
209
|
+
.string()
|
|
210
|
+
.optional()
|
|
211
|
+
.describe("Markdown source notes"),
|
|
212
|
+
design_rationale_markdown: z
|
|
213
|
+
.string()
|
|
214
|
+
.optional()
|
|
215
|
+
.describe("Markdown design rationale"),
|
|
216
|
+
production_notes_markdown: z
|
|
217
|
+
.string()
|
|
218
|
+
.optional()
|
|
219
|
+
.describe("Markdown production notes"),
|
|
220
|
+
video_path: z
|
|
221
|
+
.string()
|
|
222
|
+
.optional()
|
|
223
|
+
.describe("Local path to video file to upload"),
|
|
224
|
+
}),
|
|
225
|
+
execute: async (args) => {
|
|
226
|
+
const { ids, video_path, ...updates } = args;
|
|
227
|
+
if (ids.length === 0) {
|
|
228
|
+
return JSON.stringify({ error: "Provide at least one id." });
|
|
229
|
+
}
|
|
230
|
+
const hasUpdates = Object.values(updates).some((v) => v !== undefined) ||
|
|
231
|
+
video_path !== undefined;
|
|
232
|
+
if (!hasUpdates) {
|
|
233
|
+
return JSON.stringify({
|
|
234
|
+
error: "Provide at least one attribute to update.",
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
let videoBlobKey;
|
|
238
|
+
// Upload file if path provided
|
|
239
|
+
if (video_path) {
|
|
240
|
+
console.error(`Uploading file: ${video_path}`);
|
|
241
|
+
const uploadResult = await uploadFile(video_path);
|
|
242
|
+
videoBlobKey = uploadResult.key;
|
|
243
|
+
console.error(`Uploaded: ${uploadResult.filename} (key: ${uploadResult.key})`);
|
|
244
|
+
}
|
|
245
|
+
const data = await callRailsApi("/ai-video-hub/api/videos/bulk_update", {
|
|
246
|
+
method: "PATCH",
|
|
247
|
+
body: JSON.stringify({
|
|
248
|
+
ids,
|
|
249
|
+
updates: {
|
|
250
|
+
status: updates.status,
|
|
251
|
+
client_name: updates.client_name,
|
|
252
|
+
published_on: updates.published_on,
|
|
253
|
+
source_research_markdown: updates.source_research_markdown,
|
|
254
|
+
design_rationale_markdown: updates.design_rationale_markdown,
|
|
255
|
+
production_notes_markdown: updates.production_notes_markdown,
|
|
256
|
+
},
|
|
257
|
+
video_blob_key: videoBlobKey,
|
|
258
|
+
}),
|
|
259
|
+
});
|
|
260
|
+
return JSON.stringify(data, null, 2);
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
// Tool: delete_ai_videos
|
|
264
|
+
server.addTool({
|
|
265
|
+
name: "delete_ai_videos",
|
|
266
|
+
description: "Delete one or more AI video entries.",
|
|
267
|
+
parameters: z.object({
|
|
268
|
+
ids: z.array(z.number()).describe("AI video ids to delete"),
|
|
269
|
+
}),
|
|
270
|
+
execute: async (args) => {
|
|
271
|
+
if (args.ids.length === 0) {
|
|
272
|
+
return JSON.stringify({ error: "Provide at least one id." });
|
|
273
|
+
}
|
|
274
|
+
const data = await callRailsApi("/ai-video-hub/api/videos/bulk_destroy", {
|
|
275
|
+
method: "DELETE",
|
|
276
|
+
body: JSON.stringify({ ids: args.ids }),
|
|
277
|
+
});
|
|
278
|
+
return JSON.stringify(data, null, 2);
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
// Start the server
|
|
282
|
+
server.start({
|
|
283
|
+
transportType: "stdio",
|
|
284
|
+
});
|
|
285
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@feedmob/ai-video-hub",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "FeedMob AI Video Hub MCP Server",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"feedmob-ai-video-hub": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"fastmcp": "1.21.0",
|
|
22
|
+
"@modelcontextprotocol/sdk": "1.6.0",
|
|
23
|
+
"zod": "^3.22.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.0.0",
|
|
27
|
+
"tsx": "^4.0.0",
|
|
28
|
+
"typescript": "^5.0.0"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"mcp",
|
|
35
|
+
"feedmob",
|
|
36
|
+
"ai-video",
|
|
37
|
+
"video-management"
|
|
38
|
+
],
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/feed-mob/fm-mcp-servers.git"
|
|
43
|
+
}
|
|
44
|
+
}
|