@bragfast/mcp-server 0.1.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/dist/cli.d.ts +2 -0
- package/dist/cli.js +39 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +237 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +6 -0
- package/dist/lib/api-client.js +66 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth.d.ts +1 -0
- package/dist/lib/auth.js +13 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/credentials.d.ts +10 -0
- package/dist/lib/credentials.js +52 -0
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/types.d.ts +83 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/tools/check-account.d.ts +3 -0
- package/dist/tools/check-account.js +4 -0
- package/dist/tools/check-account.js.map +1 -0
- package/dist/tools/generate-images.d.ts +31 -0
- package/dist/tools/generate-images.js +4 -0
- package/dist/tools/generate-images.js.map +1 -0
- package/dist/tools/generate-video.d.ts +9 -0
- package/dist/tools/generate-video.js +9 -0
- package/dist/tools/generate-video.js.map +1 -0
- package/dist/tools/list-brands.d.ts +3 -0
- package/dist/tools/list-brands.js +4 -0
- package/dist/tools/list-brands.js.map +1 -0
- package/dist/tools/list-templates.d.ts +5 -0
- package/dist/tools/list-templates.js +4 -0
- package/dist/tools/list-templates.js.map +1 -0
- package/dist/tools/render-status.d.ts +6 -0
- package/dist/tools/render-status.js +4 -0
- package/dist/tools/render-status.js.map +1 -0
- package/manifest.json +47 -0
- package/package.json +36 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeCredentials, deleteCredentials } from "./lib/credentials.js";
|
|
3
|
+
const [command] = process.argv.slice(2);
|
|
4
|
+
async function login() {
|
|
5
|
+
// For v1, just print instructions. Browser-based login is v1.1.
|
|
6
|
+
console.log("To authenticate, create an API key at: https://bragfast.com/dashboard/api-keys");
|
|
7
|
+
console.log("");
|
|
8
|
+
console.log("Then either:");
|
|
9
|
+
console.log(" 1. Set BRAGFAST_API_KEY environment variable");
|
|
10
|
+
console.log(" 2. Run: npx @bragfast/mcp-server login <your-api-key>");
|
|
11
|
+
const apiKey = process.argv[3];
|
|
12
|
+
if (apiKey) {
|
|
13
|
+
await writeCredentials({ api_key: apiKey });
|
|
14
|
+
console.log("\nAPI key saved! You can now use bragfast in Claude.");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function logout() {
|
|
18
|
+
await deleteCredentials();
|
|
19
|
+
console.log("Logged out. Stored credentials removed.");
|
|
20
|
+
}
|
|
21
|
+
async function main() {
|
|
22
|
+
switch (command) {
|
|
23
|
+
case "login":
|
|
24
|
+
await login();
|
|
25
|
+
break;
|
|
26
|
+
case "logout":
|
|
27
|
+
await logout();
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
// If no command, start MCP server (import dynamically to avoid loading everything for login/logout)
|
|
31
|
+
await import("./index.js");
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
main().catch((err) => {
|
|
36
|
+
console.error("Error:", err.message);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAExC,KAAK,UAAU,KAAK;IAClB,gEAAgE;IAChE,OAAO,CAAC,GAAG,CACT,gFAAgF,CACjF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IAEvE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,MAAM;IACnB,MAAM,iBAAiB,EAAE,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AACzD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,MAAM,KAAK,EAAE,CAAC;YACd,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,MAAM,EAAE,CAAC;YACf,MAAM;QACR;YACE,oGAAoG;YACpG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAC3B,MAAM;IACV,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod/v4";
|
|
5
|
+
import { BragfastApiClient } from "./lib/api-client.js";
|
|
6
|
+
import { generateImages } from "./tools/generate-images.js";
|
|
7
|
+
import { generateVideo } from "./tools/generate-video.js";
|
|
8
|
+
import { listBrands } from "./tools/list-brands.js";
|
|
9
|
+
import { listTemplates } from "./tools/list-templates.js";
|
|
10
|
+
import { checkAccount } from "./tools/check-account.js";
|
|
11
|
+
import { getRenderStatus } from "./tools/render-status.js";
|
|
12
|
+
const server = new McpServer({
|
|
13
|
+
name: "bragfast",
|
|
14
|
+
version: "0.1.0",
|
|
15
|
+
});
|
|
16
|
+
const client = new BragfastApiClient();
|
|
17
|
+
// 1. bragfast_generate_release_images
|
|
18
|
+
server.registerTool("bragfast_generate_release_images", {
|
|
19
|
+
title: "Generate Release Images",
|
|
20
|
+
description: "Generate branded release announcement images. Returns a cook_id immediately — use bragfast_get_render_status to poll for completion.",
|
|
21
|
+
inputSchema: z.object({
|
|
22
|
+
brand_id: z.string().optional().describe("Brand ID to use for styling"),
|
|
23
|
+
colors: z
|
|
24
|
+
.object({
|
|
25
|
+
background: z.string(),
|
|
26
|
+
text: z.string(),
|
|
27
|
+
primary: z.string(),
|
|
28
|
+
})
|
|
29
|
+
.optional()
|
|
30
|
+
.describe("Custom colors (hex). Required if no brand_id."),
|
|
31
|
+
name: z.string().optional().describe("Brand name override"),
|
|
32
|
+
logo_url: z.string().optional().describe("Logo URL override"),
|
|
33
|
+
font_family: z.string().optional().describe("Font family override"),
|
|
34
|
+
template: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Template ID (e.g. standard-browser, split-mobile, hero, or tmpl_*)"),
|
|
38
|
+
formats: z
|
|
39
|
+
.array(z.object({
|
|
40
|
+
name: z
|
|
41
|
+
.enum(["landscape", "square", "portrait", "og"])
|
|
42
|
+
.describe("Output format"),
|
|
43
|
+
slides: z.array(z.object({
|
|
44
|
+
objects: z
|
|
45
|
+
.array(z.object({
|
|
46
|
+
id: z.string().describe("Object ID from template config"),
|
|
47
|
+
text: z.string().optional(),
|
|
48
|
+
image_url: z.string().optional(),
|
|
49
|
+
font_family: z.string().optional(),
|
|
50
|
+
color: z.string().optional(),
|
|
51
|
+
image_frame: z
|
|
52
|
+
.enum(["browser", "mobile", "none"])
|
|
53
|
+
.optional(),
|
|
54
|
+
image_frame_color: z.string().optional(),
|
|
55
|
+
}))
|
|
56
|
+
.optional(),
|
|
57
|
+
})),
|
|
58
|
+
}))
|
|
59
|
+
.describe("Formats and slide content"),
|
|
60
|
+
metadata: z.string().optional().describe("Arbitrary metadata string"),
|
|
61
|
+
webhook_url: z
|
|
62
|
+
.string()
|
|
63
|
+
.optional()
|
|
64
|
+
.describe("Webhook URL for completion notification"),
|
|
65
|
+
}),
|
|
66
|
+
}, async (input) => {
|
|
67
|
+
try {
|
|
68
|
+
const result = await generateImages(client, input);
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
77
|
+
],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// 2. bragfast_generate_release_video
|
|
83
|
+
server.registerTool("bragfast_generate_release_video", {
|
|
84
|
+
title: "Generate Release Video",
|
|
85
|
+
description: "Generate a branded release announcement video. Returns a cook_id immediately — use bragfast_get_render_status to poll for completion. Does not support 'og' format.",
|
|
86
|
+
inputSchema: z.object({
|
|
87
|
+
brand_id: z.string().optional(),
|
|
88
|
+
colors: z
|
|
89
|
+
.object({ background: z.string(), text: z.string(), primary: z.string() })
|
|
90
|
+
.optional(),
|
|
91
|
+
name: z.string().optional(),
|
|
92
|
+
logo_url: z.string().optional(),
|
|
93
|
+
font_family: z.string().optional(),
|
|
94
|
+
template: z.string().optional(),
|
|
95
|
+
formats: z.array(z.object({
|
|
96
|
+
name: z.enum(["landscape", "square", "portrait"]),
|
|
97
|
+
slides: z.array(z.object({
|
|
98
|
+
objects: z
|
|
99
|
+
.array(z.object({
|
|
100
|
+
id: z.string(),
|
|
101
|
+
text: z.string().optional(),
|
|
102
|
+
image_url: z.string().optional(),
|
|
103
|
+
font_family: z.string().optional(),
|
|
104
|
+
color: z.string().optional(),
|
|
105
|
+
image_frame: z
|
|
106
|
+
.enum(["browser", "mobile", "none"])
|
|
107
|
+
.optional(),
|
|
108
|
+
image_frame_color: z.string().optional(),
|
|
109
|
+
}))
|
|
110
|
+
.optional(),
|
|
111
|
+
})),
|
|
112
|
+
})),
|
|
113
|
+
video: z
|
|
114
|
+
.union([
|
|
115
|
+
z.literal(true),
|
|
116
|
+
z.object({ duration: z.number().optional() }),
|
|
117
|
+
])
|
|
118
|
+
.optional()
|
|
119
|
+
.describe("Video options. Defaults to true."),
|
|
120
|
+
metadata: z.string().optional(),
|
|
121
|
+
webhook_url: z.string().optional(),
|
|
122
|
+
}),
|
|
123
|
+
}, async (input) => {
|
|
124
|
+
try {
|
|
125
|
+
const result = await generateVideo(client, input);
|
|
126
|
+
return {
|
|
127
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
return {
|
|
132
|
+
content: [
|
|
133
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
134
|
+
],
|
|
135
|
+
isError: true,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
// 3. bragfast_list_brands
|
|
140
|
+
server.registerTool("bragfast_list_brands", {
|
|
141
|
+
title: "List Brands",
|
|
142
|
+
description: "List all brands associated with your Bragfast account.",
|
|
143
|
+
inputSchema: z.object({}),
|
|
144
|
+
}, async () => {
|
|
145
|
+
try {
|
|
146
|
+
const brands = await listBrands(client);
|
|
147
|
+
return {
|
|
148
|
+
content: [{ type: "text", text: JSON.stringify(brands, null, 2) }],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
return {
|
|
153
|
+
content: [
|
|
154
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
155
|
+
],
|
|
156
|
+
isError: true,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
// 4. bragfast_list_templates
|
|
161
|
+
server.registerTool("bragfast_list_templates", {
|
|
162
|
+
title: "List Templates",
|
|
163
|
+
description: "List all available templates with their full config including object IDs. Use object IDs when composing slides for generate_release_images/video.",
|
|
164
|
+
inputSchema: z.object({}),
|
|
165
|
+
}, async () => {
|
|
166
|
+
try {
|
|
167
|
+
const result = await listTemplates(client);
|
|
168
|
+
return {
|
|
169
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
return {
|
|
174
|
+
content: [
|
|
175
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
176
|
+
],
|
|
177
|
+
isError: true,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
// 5. bragfast_check_account
|
|
182
|
+
server.registerTool("bragfast_check_account", {
|
|
183
|
+
title: "Check Account",
|
|
184
|
+
description: "Check your Bragfast account credits and plan.",
|
|
185
|
+
inputSchema: z.object({}),
|
|
186
|
+
}, async () => {
|
|
187
|
+
try {
|
|
188
|
+
const info = await checkAccount(client);
|
|
189
|
+
return {
|
|
190
|
+
content: [{ type: "text", text: JSON.stringify(info, null, 2) }],
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
return {
|
|
195
|
+
content: [
|
|
196
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
197
|
+
],
|
|
198
|
+
isError: true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
// 6. bragfast_get_render_status
|
|
203
|
+
server.registerTool("bragfast_get_render_status", {
|
|
204
|
+
title: "Get Render Status",
|
|
205
|
+
description: "Check the status of a render job. Returns status, and image/video URLs when complete.",
|
|
206
|
+
inputSchema: z.object({
|
|
207
|
+
cook_id: z
|
|
208
|
+
.string()
|
|
209
|
+
.describe("The cook_id returned from generate_release_images or generate_release_video"),
|
|
210
|
+
}),
|
|
211
|
+
}, async (input) => {
|
|
212
|
+
try {
|
|
213
|
+
const result = await getRenderStatus(client, input);
|
|
214
|
+
return {
|
|
215
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
return {
|
|
220
|
+
content: [
|
|
221
|
+
{ type: "text", text: `Error: ${err.message}` },
|
|
222
|
+
],
|
|
223
|
+
isError: true,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
// Start server
|
|
228
|
+
async function main() {
|
|
229
|
+
const transport = new StdioServerTransport();
|
|
230
|
+
await server.connect(transport);
|
|
231
|
+
console.error("Bragfast MCP Server running on stdio");
|
|
232
|
+
}
|
|
233
|
+
main().catch((err) => {
|
|
234
|
+
console.error("Fatal error:", err);
|
|
235
|
+
process.exit(1);
|
|
236
|
+
});
|
|
237
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { resolveApiKey } from "./auth.js";
|
|
2
|
+
import { deleteCredentials } from "./credentials.js";
|
|
3
|
+
const DEFAULT_BASE_URL = "https://bragfast.com/api/v1";
|
|
4
|
+
async function handleResponse(res) {
|
|
5
|
+
if (res.ok) {
|
|
6
|
+
return res.json();
|
|
7
|
+
}
|
|
8
|
+
if (res.status === 401) {
|
|
9
|
+
await deleteCredentials();
|
|
10
|
+
throw new Error("API key is invalid or revoked. Run: npx @bragfast/mcp-server login");
|
|
11
|
+
}
|
|
12
|
+
if (res.status === 429) {
|
|
13
|
+
const retryAfter = res.headers.get("Retry-After") ?? "unknown";
|
|
14
|
+
throw new Error(`Rate limited. Try again in ${retryAfter} seconds`);
|
|
15
|
+
}
|
|
16
|
+
let message;
|
|
17
|
+
try {
|
|
18
|
+
const body = (await res.json());
|
|
19
|
+
message = body.error ?? `HTTP ${res.status}`;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
message = `HTTP ${res.status}`;
|
|
23
|
+
}
|
|
24
|
+
throw new Error(message);
|
|
25
|
+
}
|
|
26
|
+
export class BragfastApiClient {
|
|
27
|
+
baseUrl;
|
|
28
|
+
constructor(baseUrl) {
|
|
29
|
+
this.baseUrl = baseUrl ?? process.env.BRAGFAST_API_URL ?? DEFAULT_BASE_URL;
|
|
30
|
+
}
|
|
31
|
+
async get(path) {
|
|
32
|
+
const apiKey = await resolveApiKey();
|
|
33
|
+
let res;
|
|
34
|
+
try {
|
|
35
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
36
|
+
method: "GET",
|
|
37
|
+
headers: {
|
|
38
|
+
Authorization: `Bearer ${apiKey}`,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
throw new Error("Cannot reach Bragfast API. Check your internet connection.");
|
|
44
|
+
}
|
|
45
|
+
return handleResponse(res);
|
|
46
|
+
}
|
|
47
|
+
async post(path, body) {
|
|
48
|
+
const apiKey = await resolveApiKey();
|
|
49
|
+
let res;
|
|
50
|
+
try {
|
|
51
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: {
|
|
54
|
+
Authorization: `Bearer ${apiKey}`,
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify(body),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new Error("Cannot reach Bragfast API. Check your internet connection.");
|
|
62
|
+
}
|
|
63
|
+
return handleResponse(res);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAEvD,KAAK,UAAU,cAAc,CAAI,GAAa;IAC5C,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;IAClC,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,iBAAiB,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,UAAU,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAuB,CAAC;QACtD,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,OAAO,iBAAiB;IACpB,OAAO,CAAS;IAExB,YAAY,OAAgB;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,gBAAgB,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY;QACvB,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;gBAC1C,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,EAAE;iBAClC;aACF,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,cAAc,CAAI,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAa;QACvC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;gBAC1C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,MAAM,EAAE;oBACjC,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAC3B,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,cAAc,CAAI,GAAG,CAAC,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function resolveApiKey(): Promise<string>;
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readCredentials } from "./credentials.js";
|
|
2
|
+
export async function resolveApiKey() {
|
|
3
|
+
const envKey = process.env.BRAGFAST_API_KEY;
|
|
4
|
+
if (envKey) {
|
|
5
|
+
return envKey;
|
|
6
|
+
}
|
|
7
|
+
const stored = await readCredentials();
|
|
8
|
+
if (stored?.api_key) {
|
|
9
|
+
return stored.api_key;
|
|
10
|
+
}
|
|
11
|
+
throw new Error("Not authenticated. Run: npx @bragfast/mcp-server login\nOr set BRAGFAST_API_KEY env var.\nCreate a key at: https://bragfast.com/dashboard/api-keys");
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IACvC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,oJAAoJ,CACrJ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const _testing: {
|
|
2
|
+
setCredsDir(dir: string): void;
|
|
3
|
+
resetCredsDir(): void;
|
|
4
|
+
};
|
|
5
|
+
export interface StoredCredentials {
|
|
6
|
+
api_key: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function readCredentials(): Promise<StoredCredentials | null>;
|
|
9
|
+
export declare function writeCredentials(creds: StoredCredentials): Promise<void>;
|
|
10
|
+
export declare function deleteCredentials(): Promise<void>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir, unlink, chmod } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const DEFAULT_CREDS_DIR = join(homedir(), ".bragfast");
|
|
5
|
+
const CREDS_FILENAME = "credentials.json";
|
|
6
|
+
// Allow tests to override the credentials directory
|
|
7
|
+
let _credsDir = DEFAULT_CREDS_DIR;
|
|
8
|
+
export const _testing = {
|
|
9
|
+
setCredsDir(dir) {
|
|
10
|
+
_credsDir = dir;
|
|
11
|
+
},
|
|
12
|
+
resetCredsDir() {
|
|
13
|
+
_credsDir = DEFAULT_CREDS_DIR;
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
function getCredsFile() {
|
|
17
|
+
return join(_credsDir, CREDS_FILENAME);
|
|
18
|
+
}
|
|
19
|
+
export async function readCredentials() {
|
|
20
|
+
try {
|
|
21
|
+
const raw = await readFile(getCredsFile(), "utf-8");
|
|
22
|
+
const parsed = JSON.parse(raw);
|
|
23
|
+
if (parsed !== null &&
|
|
24
|
+
typeof parsed === "object" &&
|
|
25
|
+
"api_key" in parsed &&
|
|
26
|
+
typeof parsed.api_key === "string") {
|
|
27
|
+
return parsed;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export async function writeCredentials(creds) {
|
|
36
|
+
await mkdir(_credsDir, { recursive: true });
|
|
37
|
+
await chmod(_credsDir, 0o700);
|
|
38
|
+
const file = getCredsFile();
|
|
39
|
+
await writeFile(file, JSON.stringify(creds, null, 2), { encoding: "utf-8", mode: 0o600 });
|
|
40
|
+
}
|
|
41
|
+
export async function deleteCredentials() {
|
|
42
|
+
try {
|
|
43
|
+
await unlink(getCredsFile());
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const code = err.code;
|
|
47
|
+
if (code !== "ENOENT") {
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AACvD,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAE1C,oDAAoD;AACpD,IAAI,SAAS,GAAG,iBAAiB,CAAC;AAElC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,CAAC,GAAW;QACrB,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;IACD,aAAa;QACX,SAAS,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF,CAAC;AAEF,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACzC,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IACE,MAAM,KAAK,IAAI;YACf,OAAO,MAAM,KAAK,QAAQ;YAC1B,SAAS,IAAI,MAAM;YACnB,OAAQ,MAAkC,CAAC,OAAO,KAAK,QAAQ,EAC/D,CAAC;YACD,OAAO,MAA2B,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAwB;IAC7D,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAC5B,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export interface BrandColors {
|
|
2
|
+
background: string;
|
|
3
|
+
text: string;
|
|
4
|
+
primary: string;
|
|
5
|
+
}
|
|
6
|
+
export interface BrandRecord {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
logo_url?: string;
|
|
10
|
+
website?: string;
|
|
11
|
+
font_family?: string;
|
|
12
|
+
colors: BrandColors;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ObjectModification {
|
|
17
|
+
id: string;
|
|
18
|
+
text?: string;
|
|
19
|
+
font_family?: string;
|
|
20
|
+
color?: string;
|
|
21
|
+
image_url?: string;
|
|
22
|
+
image_frame?: "browser" | "mobile" | "none";
|
|
23
|
+
image_frame_color?: string;
|
|
24
|
+
anchor_x?: "left" | "center" | "right";
|
|
25
|
+
anchor_y?: "top" | "center" | "bottom";
|
|
26
|
+
entrance?: "fade-in" | "slide-up" | "bounce" | "none";
|
|
27
|
+
}
|
|
28
|
+
export interface FormatEntry {
|
|
29
|
+
name: "landscape" | "square" | "portrait" | "og";
|
|
30
|
+
slides: Array<{
|
|
31
|
+
objects?: ObjectModification[];
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface ReleaseRequest {
|
|
35
|
+
brand_id?: string;
|
|
36
|
+
colors?: BrandColors;
|
|
37
|
+
name?: string;
|
|
38
|
+
logo_url?: string;
|
|
39
|
+
font_family?: string;
|
|
40
|
+
template?: string;
|
|
41
|
+
formats: FormatEntry[];
|
|
42
|
+
video?: true | {
|
|
43
|
+
duration?: number;
|
|
44
|
+
};
|
|
45
|
+
metadata?: string;
|
|
46
|
+
webhook_url?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ReleaseResult {
|
|
49
|
+
cook_id: string;
|
|
50
|
+
output: "image" | "video";
|
|
51
|
+
status: "pending" | "pending_review" | "completed" | "failed" | "dismissed";
|
|
52
|
+
images: Record<string, {
|
|
53
|
+
slides: string[];
|
|
54
|
+
dimensions: string;
|
|
55
|
+
}> | null;
|
|
56
|
+
videos?: Record<string, {
|
|
57
|
+
url: string;
|
|
58
|
+
duration: number;
|
|
59
|
+
dimensions: string;
|
|
60
|
+
}> | null;
|
|
61
|
+
credits_used: number;
|
|
62
|
+
credits_remaining: number;
|
|
63
|
+
created_at: string;
|
|
64
|
+
completed_at?: string;
|
|
65
|
+
metadata?: string;
|
|
66
|
+
webhook_url?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface TemplateRecord {
|
|
69
|
+
id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
is_default: boolean;
|
|
72
|
+
config: unknown;
|
|
73
|
+
preview_url: string | null;
|
|
74
|
+
created_at: string;
|
|
75
|
+
updated_at: string;
|
|
76
|
+
}
|
|
77
|
+
export interface AccountInfo {
|
|
78
|
+
credits_remaining: number;
|
|
79
|
+
plan: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ApiError {
|
|
82
|
+
error: string;
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,+CAA+C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-account.js","sourceRoot":"","sources":["../../src/tools/check-account.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAyB;IAC1D,OAAO,MAAM,CAAC,GAAG,CAAc,UAAU,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BragfastApiClient } from "../lib/api-client.js";
|
|
2
|
+
import type { ReleaseResult } from "../lib/types.js";
|
|
3
|
+
export interface GenerateImagesInput {
|
|
4
|
+
brand_id?: string;
|
|
5
|
+
colors?: {
|
|
6
|
+
background: string;
|
|
7
|
+
text: string;
|
|
8
|
+
primary: string;
|
|
9
|
+
};
|
|
10
|
+
name?: string;
|
|
11
|
+
logo_url?: string;
|
|
12
|
+
font_family?: string;
|
|
13
|
+
template?: string;
|
|
14
|
+
formats: Array<{
|
|
15
|
+
name: "landscape" | "square" | "portrait" | "og";
|
|
16
|
+
slides: Array<{
|
|
17
|
+
objects?: Array<{
|
|
18
|
+
id: string;
|
|
19
|
+
text?: string;
|
|
20
|
+
image_url?: string;
|
|
21
|
+
font_family?: string;
|
|
22
|
+
color?: string;
|
|
23
|
+
image_frame?: "browser" | "mobile" | "none";
|
|
24
|
+
image_frame_color?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
}>;
|
|
28
|
+
metadata?: string;
|
|
29
|
+
webhook_url?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function generateImages(client: BragfastApiClient, input: GenerateImagesInput): Promise<ReleaseResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-images.js","sourceRoot":"","sources":["../../src/tools/generate-images.ts"],"names":[],"mappings":"AA4BA,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAyB,EACzB,KAA0B;IAE1B,OAAO,MAAM,CAAC,IAAI,CAAgB,OAAO,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BragfastApiClient } from "../lib/api-client.js";
|
|
2
|
+
import type { ReleaseResult } from "../lib/types.js";
|
|
3
|
+
import type { GenerateImagesInput } from "./generate-images.js";
|
|
4
|
+
export interface GenerateVideoInput extends GenerateImagesInput {
|
|
5
|
+
video?: {
|
|
6
|
+
duration?: number;
|
|
7
|
+
} | true;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateVideo(client: BragfastApiClient, input: GenerateVideoInput): Promise<ReleaseResult>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export async function generateVideo(client, input) {
|
|
2
|
+
const hasOg = input.formats.some((f) => f.name === "og");
|
|
3
|
+
if (hasOg) {
|
|
4
|
+
throw new Error('Video does not support "og" format. Use landscape, square, or portrait.');
|
|
5
|
+
}
|
|
6
|
+
const body = { ...input, video: input.video ?? true };
|
|
7
|
+
return client.post("/cook", body);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=generate-video.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-video.js","sourceRoot":"","sources":["../../src/tools/generate-video.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAyB,EACzB,KAAyB;IAEzB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IACzD,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;IACtD,OAAO,MAAM,CAAC,IAAI,CAAgB,OAAO,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-brands.js","sourceRoot":"","sources":["../../src/tools/list-brands.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAyB;IACxD,OAAO,MAAM,CAAC,GAAG,CAAgB,SAAS,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-templates.js","sourceRoot":"","sources":["../../src/tools/list-templates.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAyB;IAEzB,OAAO,MAAM,CAAC,GAAG,CAAkC,YAAY,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BragfastApiClient } from "../lib/api-client.js";
|
|
2
|
+
import type { ReleaseResult } from "../lib/types.js";
|
|
3
|
+
export interface RenderStatusInput {
|
|
4
|
+
cook_id: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function getRenderStatus(client: BragfastApiClient, input: RenderStatusInput): Promise<ReleaseResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-status.js","sourceRoot":"","sources":["../../src/tools/render-status.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAyB,EACzB,KAAwB;IAExB,OAAO,MAAM,CAAC,GAAG,CAAgB,SAAS,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7D,CAAC"}
|
package/manifest.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bragfast",
|
|
3
|
+
"display_name": "Bragfast",
|
|
4
|
+
"description": "Generate branded release announcement images and videos",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"author": "Bragfast",
|
|
7
|
+
"homepage": "https://bragfast.com",
|
|
8
|
+
"is_official": true,
|
|
9
|
+
"tools": [
|
|
10
|
+
{
|
|
11
|
+
"name": "bragfast_generate_release_images",
|
|
12
|
+
"description": "Generate branded release images"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "bragfast_generate_release_video",
|
|
16
|
+
"description": "Generate branded release video"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "bragfast_list_brands",
|
|
20
|
+
"description": "List available brands"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "bragfast_list_templates",
|
|
24
|
+
"description": "List available templates"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "bragfast_check_account",
|
|
28
|
+
"description": "Check account credits and plan"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "bragfast_get_render_status",
|
|
32
|
+
"description": "Check render job status"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"server": {
|
|
36
|
+
"type": "stdio",
|
|
37
|
+
"command": "npx",
|
|
38
|
+
"args": ["-y", "@bragfast/mcp-server"]
|
|
39
|
+
},
|
|
40
|
+
"env": [
|
|
41
|
+
{
|
|
42
|
+
"name": "BRAGFAST_API_KEY",
|
|
43
|
+
"description": "Your Bragfast API key. Get one at https://bragfast.com/dashboard/api-keys",
|
|
44
|
+
"required": false
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bragfast/mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for Bragfast — generate release images and videos from Claude",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"bragfast-mcp": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"keywords": ["mcp", "bragfast", "release", "images", "video"],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/rob-vb/bragfast-mcp"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"files": ["dist", "manifest.json"],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
29
|
+
"zod": "^4.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.0.0",
|
|
33
|
+
"typescript": "^5.7.0",
|
|
34
|
+
"vitest": "^3.0.0"
|
|
35
|
+
}
|
|
36
|
+
}
|