content-repurposer-mcp 1.0.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 +89 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +150 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# content-repurposer-mcp
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that connects AI assistants to [ContentRepurposer](https://contentrepurposer.app) — turning any blog post, transcript, or article into platform-optimized content for Twitter/X, LinkedIn, Substack, email, and video.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
This MCP server exposes two tools:
|
|
8
|
+
|
|
9
|
+
| Tool | Description |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
| `repurpose_content` | Takes content and generates platform-specific versions |
|
|
12
|
+
| `list_formats` | Lists available output formats with descriptions |
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
### 1. Get an API key
|
|
17
|
+
|
|
18
|
+
Sign up at [contentrepurposer.app](https://contentrepurposer.app) and generate an API key at **Settings → API Keys**.
|
|
19
|
+
|
|
20
|
+
### 2. Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install -g content-repurposer-mcp
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 3. Configure your AI client
|
|
27
|
+
|
|
28
|
+
#### Claude Desktop
|
|
29
|
+
|
|
30
|
+
Add to your `claude_desktop_config.json`:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"mcpServers": {
|
|
35
|
+
"content-repurposer": {
|
|
36
|
+
"command": "content-repurposer-mcp",
|
|
37
|
+
"env": {
|
|
38
|
+
"CONTENT_REPURPOSER_API_KEY": "cr_sk_your_key_here"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Claude Code
|
|
46
|
+
|
|
47
|
+
Add to your `.claude/settings.json`:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"content-repurposer": {
|
|
53
|
+
"command": "content-repurposer-mcp",
|
|
54
|
+
"env": {
|
|
55
|
+
"CONTENT_REPURPOSER_API_KEY": "cr_sk_your_key_here"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
Once configured, ask your AI assistant:
|
|
65
|
+
|
|
66
|
+
> "Repurpose this blog post into Twitter threads and LinkedIn posts"
|
|
67
|
+
|
|
68
|
+
> "Take this YouTube transcript and create content for all platforms"
|
|
69
|
+
|
|
70
|
+
> "What formats can ContentRepurposer generate?"
|
|
71
|
+
|
|
72
|
+
## Environment Variables
|
|
73
|
+
|
|
74
|
+
| Variable | Required | Description |
|
|
75
|
+
|----------|----------|-------------|
|
|
76
|
+
| `CONTENT_REPURPOSER_API_KEY` | Yes | Your API key from contentrepurposer.app |
|
|
77
|
+
| `CONTENT_REPURPOSER_API_URL` | No | Custom API URL (defaults to https://contentrepurposer.app) |
|
|
78
|
+
|
|
79
|
+
## Output Formats
|
|
80
|
+
|
|
81
|
+
- **twitter_thread** — 5-12 tweet threads with hooks and CTAs
|
|
82
|
+
- **linkedin_post** — Professional posts optimized for mobile
|
|
83
|
+
- **substack_notes** — 10-note campaigns across 5 categories
|
|
84
|
+
- **email_snippet** — Subject line, preview text, and body
|
|
85
|
+
- **video_script** — 60-second scripts for Shorts/Reels/TikTok
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
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";
|
|
5
|
+
const API_BASE = process.env.CONTENT_REPURPOSER_API_URL ?? "https://contentrepurposer.app";
|
|
6
|
+
const API_KEY = process.env.CONTENT_REPURPOSER_API_KEY;
|
|
7
|
+
const OUTPUT_FORMATS = [
|
|
8
|
+
"twitter_thread",
|
|
9
|
+
"linkedin_post",
|
|
10
|
+
"substack_notes",
|
|
11
|
+
"email_snippet",
|
|
12
|
+
"video_script",
|
|
13
|
+
];
|
|
14
|
+
const SOURCE_TYPES = [
|
|
15
|
+
"blog_post",
|
|
16
|
+
"youtube_transcript",
|
|
17
|
+
"podcast_transcript",
|
|
18
|
+
];
|
|
19
|
+
const FORMAT_DESCRIPTIONS = {
|
|
20
|
+
twitter_thread: "Twitter/X thread (5-12 tweets with hooks and CTAs)",
|
|
21
|
+
linkedin_post: "LinkedIn post (professional, mobile-optimized)",
|
|
22
|
+
substack_notes: "Substack Notes (10-note campaign across 5 categories)",
|
|
23
|
+
email_snippet: "Email newsletter (subject, preview text, and body)",
|
|
24
|
+
video_script: "Video script (60-second Shorts/Reels/TikTok format)",
|
|
25
|
+
};
|
|
26
|
+
// Helper to call the ContentRepurposer API
|
|
27
|
+
async function callRepurposeAPI(body) {
|
|
28
|
+
if (!API_KEY) {
|
|
29
|
+
throw new Error("CONTENT_REPURPOSER_API_KEY is not set. " +
|
|
30
|
+
"Get your API key at https://contentrepurposer.app/settings/api-keys");
|
|
31
|
+
}
|
|
32
|
+
const response = await fetch(`${API_BASE}/api/v1/repurpose`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
Authorization: `Bearer ${API_KEY}`,
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify(body),
|
|
39
|
+
});
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
const error = await response.json().catch(() => ({ error: { message: response.statusText } }));
|
|
42
|
+
const message = error?.error?.message ?? response.statusText;
|
|
43
|
+
throw new Error(`API error (${response.status}): ${message}`);
|
|
44
|
+
}
|
|
45
|
+
return response.json();
|
|
46
|
+
}
|
|
47
|
+
// Format the API response into readable text
|
|
48
|
+
function formatOutputs(data) {
|
|
49
|
+
const outputs = data.outputs;
|
|
50
|
+
if (!outputs || outputs.length === 0) {
|
|
51
|
+
return "No outputs were generated. The job may have failed.";
|
|
52
|
+
}
|
|
53
|
+
const sections = outputs.map((output) => {
|
|
54
|
+
const label = FORMAT_DESCRIPTIONS[output.format] ?? output.format;
|
|
55
|
+
return [
|
|
56
|
+
`## ${label}`,
|
|
57
|
+
"",
|
|
58
|
+
output.content,
|
|
59
|
+
"",
|
|
60
|
+
`(${output.wordCount} words, ${output.charCount} characters)`,
|
|
61
|
+
].join("\n");
|
|
62
|
+
});
|
|
63
|
+
return sections.join("\n\n---\n\n");
|
|
64
|
+
}
|
|
65
|
+
// Create the MCP server
|
|
66
|
+
const server = new McpServer({
|
|
67
|
+
name: "content-repurposer",
|
|
68
|
+
version: "1.0.0",
|
|
69
|
+
});
|
|
70
|
+
// Tool 1: repurpose_content — the main tool
|
|
71
|
+
server.tool("repurpose_content", "Repurpose content into platform-specific formats. Takes a blog post, transcript, or article and generates optimized versions for Twitter/X, LinkedIn, Substack, email, and video. Requires a CONTENT_REPURPOSER_API_KEY.", {
|
|
72
|
+
content: z
|
|
73
|
+
.string()
|
|
74
|
+
.min(50)
|
|
75
|
+
.describe("The source content to repurpose (blog post, transcript, etc.). Minimum 50 characters."),
|
|
76
|
+
source_type: z
|
|
77
|
+
.enum(SOURCE_TYPES)
|
|
78
|
+
.default("blog_post")
|
|
79
|
+
.describe("Type of source content: blog_post, youtube_transcript, or podcast_transcript"),
|
|
80
|
+
source_url: z
|
|
81
|
+
.string()
|
|
82
|
+
.url()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe("Optional URL of the original content for attribution"),
|
|
85
|
+
formats: z
|
|
86
|
+
.array(z.enum(OUTPUT_FORMATS))
|
|
87
|
+
.min(1)
|
|
88
|
+
.default([...OUTPUT_FORMATS])
|
|
89
|
+
.describe("Output formats to generate. Options: twitter_thread, linkedin_post, substack_notes, email_snippet, video_script. Defaults to all 5."),
|
|
90
|
+
}, async ({ content, source_type, source_url, formats }) => {
|
|
91
|
+
try {
|
|
92
|
+
const result = await callRepurposeAPI({
|
|
93
|
+
content,
|
|
94
|
+
sourceType: source_type,
|
|
95
|
+
sourceUrl: source_url,
|
|
96
|
+
formats,
|
|
97
|
+
});
|
|
98
|
+
const formatted = formatOutputs(result);
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: "text",
|
|
103
|
+
text: formatted,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
return {
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: "text",
|
|
113
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Tool 2: list_formats — discover available formats
|
|
121
|
+
server.tool("list_formats", "List all available output formats for content repurposing, with descriptions of what each format produces.", {}, async () => {
|
|
122
|
+
const lines = OUTPUT_FORMATS.map((format) => `- **${format}**: ${FORMAT_DESCRIPTIONS[format]}`);
|
|
123
|
+
return {
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: [
|
|
128
|
+
"# Available Output Formats",
|
|
129
|
+
"",
|
|
130
|
+
"ContentRepurposer can generate the following formats from your content:",
|
|
131
|
+
"",
|
|
132
|
+
...lines,
|
|
133
|
+
"",
|
|
134
|
+
"Use the `repurpose_content` tool with the `formats` parameter to select which formats to generate.",
|
|
135
|
+
"",
|
|
136
|
+
"Learn more at https://contentrepurposer.app/docs/api",
|
|
137
|
+
].join("\n"),
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
// Start the server
|
|
143
|
+
async function main() {
|
|
144
|
+
const transport = new StdioServerTransport();
|
|
145
|
+
await server.connect(transport);
|
|
146
|
+
}
|
|
147
|
+
main().catch((error) => {
|
|
148
|
+
console.error("Failed to start MCP server:", error);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "content-repurposer-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for ContentRepurposer — turn any content into Twitter threads, LinkedIn posts, Substack notes, email newsletters, and video scripts",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"mcp-server",
|
|
8
|
+
"content-repurposer",
|
|
9
|
+
"content-marketing",
|
|
10
|
+
"ai",
|
|
11
|
+
"social-media",
|
|
12
|
+
"repurpose"
|
|
13
|
+
],
|
|
14
|
+
"author": "As The Geek Learns",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"bin": {
|
|
18
|
+
"content-repurposer-mcp": "dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/index.js",
|
|
27
|
+
"dev": "tsx src/index.ts"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
31
|
+
"zod": "^3.25.67"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20",
|
|
35
|
+
"tsx": "^4.21.0",
|
|
36
|
+
"typescript": "^5"
|
|
37
|
+
}
|
|
38
|
+
}
|