@frase/mcp-server 0.1.9 → 0.2.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/CHANGELOG.md +16 -0
- package/README.md +62 -0
- package/dist/api-client.js +1 -1
- package/dist/cli/config-writer.d.ts +30 -0
- package/dist/cli/config-writer.d.ts.map +1 -0
- package/dist/cli/config-writer.js +119 -0
- package/dist/cli/config-writer.js.map +1 -0
- package/dist/cli/detect-tool.d.ts +19 -0
- package/dist/cli/detect-tool.d.ts.map +1 -0
- package/dist/cli/detect-tool.js +98 -0
- package/dist/cli/detect-tool.js.map +1 -0
- package/dist/cli/init.d.ts +14 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +182 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts/content-pipeline.d.ts +25 -0
- package/dist/prompts/content-pipeline.d.ts.map +1 -0
- package/dist/prompts/content-pipeline.js +112 -0
- package/dist/prompts/content-pipeline.js.map +1 -0
- package/dist/prompts/content-watchdog.d.ts +17 -0
- package/dist/prompts/content-watchdog.d.ts.map +1 -0
- package/dist/prompts/content-watchdog.js +82 -0
- package/dist/prompts/content-watchdog.js.map +1 -0
- package/dist/prompts/create-seo-article.d.ts +3 -0
- package/dist/prompts/create-seo-article.d.ts.map +1 -1
- package/dist/prompts/create-seo-article.js +51 -5
- package/dist/prompts/create-seo-article.js.map +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +6 -0
- package/dist/prompts/index.js.map +1 -1
- package/dist/resources/sites.d.ts.map +1 -1
- package/dist/resources/sites.js +5 -7
- package/dist/resources/sites.js.map +1 -1
- package/dist/tools/ai-visibility.d.ts.map +1 -1
- package/dist/tools/ai-visibility.js +131 -71
- package/dist/tools/ai-visibility.js.map +1 -1
- package/dist/tools/analytics.d.ts.map +1 -1
- package/dist/tools/analytics.js +96 -49
- package/dist/tools/analytics.js.map +1 -1
- package/dist/tools/audits.d.ts +15 -6
- package/dist/tools/audits.d.ts.map +1 -1
- package/dist/tools/audits.js +35 -12
- package/dist/tools/audits.js.map +1 -1
- package/dist/tools/briefs.d.ts +229 -3
- package/dist/tools/briefs.d.ts.map +1 -1
- package/dist/tools/briefs.js +365 -26
- package/dist/tools/briefs.js.map +1 -1
- package/dist/tools/content.d.ts +13 -3
- package/dist/tools/content.d.ts.map +1 -1
- package/dist/tools/content.js +99 -11
- package/dist/tools/content.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +15 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/optimizations.d.ts.map +1 -1
- package/dist/tools/optimizations.js +93 -39
- package/dist/tools/optimizations.js.map +1 -1
- package/dist/tools/playbooks.d.ts +17 -0
- package/dist/tools/playbooks.d.ts.map +1 -0
- package/dist/tools/playbooks.js +363 -0
- package/dist/tools/playbooks.js.map +1 -0
- package/dist/tools/research.js +2 -2
- package/dist/tools/research.js.map +1 -1
- package/dist/tools/rules.d.ts +81 -0
- package/dist/tools/rules.d.ts.map +1 -0
- package/dist/tools/rules.js +280 -0
- package/dist/tools/rules.js.map +1 -0
- package/dist/tools/serp.js +4 -4
- package/dist/tools/serp.js.map +1 -1
- package/dist/tools/sites.d.ts.map +1 -1
- package/dist/tools/sites.js +1 -2
- package/dist/tools/sites.js.map +1 -1
- package/dist/tools/templates.d.ts +17 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +521 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +44 -24
- package/dist/tools/webhooks.js.map +1 -1
- package/dist/types.d.ts +1 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +25 -1
- package/server.json +35 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-03-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Prompt: `content_pipeline`** — Full autonomous content lifecycle workflow (research → brief → write → optimize → publish → monitor)
|
|
12
|
+
- **Prompt: `content_watchdog`** — Performance monitoring and auto-fix workflow for ranking drops
|
|
13
|
+
- **Enhanced `create_seo_article` prompt** — Now includes optimization scoring, revision loop, and CMS publishing steps
|
|
14
|
+
- Multi-tool setup instructions for **Cursor**, **Windsurf**, and **VS Code Copilot**
|
|
15
|
+
- `target_language` parameter on `create_brief` tool (ISO 639-1 code, e.g., 'en', 'de', 'pt')
|
|
16
|
+
- `target_country` parameter on `create_brief` tool (ISO 3166-1 code, e.g., 'us', 'de', 'br')
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- `SERVER_VERSION` constant now correctly reads `0.2.0` (was stuck at `0.1.0` since initial release)
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Version bump to 0.2.0 across package.json, manifest.json, and server constant
|
|
23
|
+
|
|
8
24
|
## [0.1.0] - 2026-02-01
|
|
9
25
|
|
|
10
26
|
### Added
|
package/README.md
CHANGED
|
@@ -60,6 +60,60 @@ Add this to your Claude Desktop config file:
|
|
|
60
60
|
|
|
61
61
|
After saving the config, restart Claude Desktop. You should see "frase" in the MCP servers list.
|
|
62
62
|
|
|
63
|
+
### Option D: Cursor
|
|
64
|
+
|
|
65
|
+
Add to your project's `.cursor/mcp.json`:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"frase": {
|
|
71
|
+
"command": "npx",
|
|
72
|
+
"args": ["-y", "@frase/mcp-server"],
|
|
73
|
+
"env": {
|
|
74
|
+
"FRASE_API_KEY": "sk_live_your_api_key_here"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Option E: Windsurf
|
|
82
|
+
|
|
83
|
+
Add to your Windsurf MCP config (`~/.codeium/windsurf/mcp_config.json`):
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"frase": {
|
|
89
|
+
"command": "npx",
|
|
90
|
+
"args": ["-y", "@frase/mcp-server"],
|
|
91
|
+
"env": {
|
|
92
|
+
"FRASE_API_KEY": "sk_live_your_api_key_here"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Option F: VS Code with GitHub Copilot
|
|
100
|
+
|
|
101
|
+
Add to your VS Code settings (`.vscode/settings.json`):
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"github.copilot.chat.mcpServers": {
|
|
106
|
+
"frase": {
|
|
107
|
+
"command": "npx",
|
|
108
|
+
"args": ["-y", "@frase/mcp-server"],
|
|
109
|
+
"env": {
|
|
110
|
+
"FRASE_API_KEY": "sk_live_your_api_key_here"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
63
117
|
## Available Tools
|
|
64
118
|
|
|
65
119
|
### Sites
|
|
@@ -81,6 +135,8 @@ After saving the config, restart Claude Desktop. You should see "frase" in the M
|
|
|
81
135
|
- `delete_content` - Delete a content item (soft delete)
|
|
82
136
|
- `get_content_status` - Check content generation progress
|
|
83
137
|
- `export_content` - Export content in JSON, HTML, or Markdown format
|
|
138
|
+
- `regenerate_content` - Regenerate or improve content with optional instructions
|
|
139
|
+
- `rescore_content` - Recalculate SEO, GEO, and EEAT scores for content
|
|
84
140
|
|
|
85
141
|
### Research
|
|
86
142
|
- `list_research` - List research sessions
|
|
@@ -138,6 +194,10 @@ After saving the config, restart Claude Desktop. You should see "frase" in the M
|
|
|
138
194
|
- `update_webhook` - Update a webhook
|
|
139
195
|
- `delete_webhook` - Delete a webhook
|
|
140
196
|
|
|
197
|
+
### CMS Publishing
|
|
198
|
+
- `publish_content` - Publish content to Frase CMS or connected platforms
|
|
199
|
+
- `list_cms_connections` - List CMS connection status for a site
|
|
200
|
+
|
|
141
201
|
## Example Conversations
|
|
142
202
|
|
|
143
203
|
### List your sites
|
|
@@ -219,6 +279,8 @@ Pre-built workflows for common SEO tasks:
|
|
|
219
279
|
| `keyword_research` | Research keywords, SERP analysis, and content opportunities |
|
|
220
280
|
| `competitor_analysis` | Analyze competitor content and find gaps |
|
|
221
281
|
| `content_audit` | Run site audit and prioritize improvements |
|
|
282
|
+
| `content_pipeline` | Full autonomous content lifecycle: research, brief, write, optimize, publish |
|
|
283
|
+
| `content_watchdog` | Monitor performance, fix ranking drops, re-optimize underperforming content |
|
|
222
284
|
|
|
223
285
|
## Configuration
|
|
224
286
|
|
package/dist/api-client.js
CHANGED
|
@@ -112,7 +112,7 @@ export class FraseApiClient {
|
|
|
112
112
|
headers: {
|
|
113
113
|
"Content-Type": "application/json",
|
|
114
114
|
"X-API-KEY": this.config.apiKey,
|
|
115
|
-
"User-Agent": "frase-mcp-server/0.1
|
|
115
|
+
"User-Agent": "frase-mcp-server/0.2.1",
|
|
116
116
|
},
|
|
117
117
|
body: body ? JSON.stringify(body) : undefined,
|
|
118
118
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Config File Writer
|
|
3
|
+
*
|
|
4
|
+
* Reads existing config, merges the Frase MCP server entry,
|
|
5
|
+
* and writes back with a backup of the original.
|
|
6
|
+
*/
|
|
7
|
+
import type { DetectedTool } from "./detect-tool.js";
|
|
8
|
+
/** The MCP server config entry we write */
|
|
9
|
+
interface McpServerEntry {
|
|
10
|
+
command: string;
|
|
11
|
+
args: string[];
|
|
12
|
+
env: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the Frase MCP server entry for a config file
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildFraseEntry(apiKey: string, apiUrl?: string): McpServerEntry;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a Frase entry already exists in the config
|
|
20
|
+
*/
|
|
21
|
+
export declare function hasFraseEntry(tool: DetectedTool): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Write the Frase MCP server config for a tool.
|
|
24
|
+
* Creates directories and backups as needed.
|
|
25
|
+
* Returns the path that was written.
|
|
26
|
+
* Throws with a user-friendly message on permission errors.
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeFraseConfig(tool: DetectedTool, apiKey: string, apiUrl?: string): string;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=config-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../../src/cli/config-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,2CAA2C;AAC3C,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,CAU/E;AAkBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAYzD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CA2D5F"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Config File Writer
|
|
3
|
+
*
|
|
4
|
+
* Reads existing config, merges the Frase MCP server entry,
|
|
5
|
+
* and writes back with a backup of the original.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, copyFileSync, chmodSync } from "node:fs";
|
|
8
|
+
import { dirname } from "node:path";
|
|
9
|
+
/**
|
|
10
|
+
* Build the Frase MCP server entry for a config file
|
|
11
|
+
*/
|
|
12
|
+
export function buildFraseEntry(apiKey, apiUrl) {
|
|
13
|
+
const env = { FRASE_API_KEY: apiKey };
|
|
14
|
+
if (apiUrl) {
|
|
15
|
+
env.FRASE_API_URL = apiUrl;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
command: "npx",
|
|
19
|
+
args: ["-y", "@frase/mcp-server"],
|
|
20
|
+
env,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Read a JSON config file, returning empty object if it doesn't exist.
|
|
25
|
+
* Returns { data, malformed } — malformed is true if the file exists but is not valid JSON.
|
|
26
|
+
*/
|
|
27
|
+
function readJsonConfig(path) {
|
|
28
|
+
if (!existsSync(path)) {
|
|
29
|
+
return { data: {}, malformed: false };
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const content = readFileSync(path, "utf-8");
|
|
33
|
+
return { data: JSON.parse(content), malformed: false };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return { data: {}, malformed: true };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Check if a Frase entry already exists in the config
|
|
41
|
+
*/
|
|
42
|
+
export function hasFraseEntry(tool) {
|
|
43
|
+
if (!tool.configPath || !existsSync(tool.configPath)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const { data } = readJsonConfig(tool.configPath);
|
|
47
|
+
if (tool.id === "vscode") {
|
|
48
|
+
const mcp = data.mcp;
|
|
49
|
+
const servers = mcp?.servers;
|
|
50
|
+
return !!servers?.frase;
|
|
51
|
+
}
|
|
52
|
+
const servers = data[tool.mcpKey];
|
|
53
|
+
return !!servers?.frase;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Write the Frase MCP server config for a tool.
|
|
57
|
+
* Creates directories and backups as needed.
|
|
58
|
+
* Returns the path that was written.
|
|
59
|
+
* Throws with a user-friendly message on permission errors.
|
|
60
|
+
*/
|
|
61
|
+
export function writeFraseConfig(tool, apiKey, apiUrl) {
|
|
62
|
+
const entry = buildFraseEntry(apiKey, apiUrl);
|
|
63
|
+
const configPath = tool.configPath;
|
|
64
|
+
// Ensure directory exists
|
|
65
|
+
const dir = dirname(configPath);
|
|
66
|
+
try {
|
|
67
|
+
if (!existsSync(dir)) {
|
|
68
|
+
mkdirSync(dir, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
throw new Error(`Cannot create directory: ${dir}. Check permissions.`);
|
|
73
|
+
}
|
|
74
|
+
// Read existing config
|
|
75
|
+
const { data: config, malformed } = readJsonConfig(configPath);
|
|
76
|
+
if (malformed) {
|
|
77
|
+
console.log(` Warning: ${configPath} contains invalid JSON.`);
|
|
78
|
+
console.log(" A backup will be created before overwriting.");
|
|
79
|
+
}
|
|
80
|
+
// Backup existing file if it exists
|
|
81
|
+
if (existsSync(configPath)) {
|
|
82
|
+
const backupPath = configPath + ".backup";
|
|
83
|
+
copyFileSync(configPath, backupPath);
|
|
84
|
+
try {
|
|
85
|
+
chmodSync(backupPath, 0o600);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Best-effort: Windows may not support chmod
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// VS Code uses a different structure
|
|
92
|
+
if (tool.id === "vscode") {
|
|
93
|
+
// mcp.servers.frase
|
|
94
|
+
const mcp = (config.mcp || {});
|
|
95
|
+
const servers = (mcp.servers || {});
|
|
96
|
+
servers.frase = entry;
|
|
97
|
+
mcp.servers = servers;
|
|
98
|
+
config.mcp = mcp;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Standard mcpServers.frase structure
|
|
102
|
+
const servers = (config[tool.mcpKey] || {});
|
|
103
|
+
servers.frase = entry;
|
|
104
|
+
config[tool.mcpKey] = servers;
|
|
105
|
+
}
|
|
106
|
+
// Write with pretty formatting and restricted permissions
|
|
107
|
+
try {
|
|
108
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
112
|
+
if (msg.includes("EACCES") || msg.includes("permission")) {
|
|
113
|
+
throw new Error(`Cannot write to ${configPath}. Check file permissions.`);
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
return configPath;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=config-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../../src/cli/config-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Tool Detection
|
|
3
|
+
*
|
|
4
|
+
* Detects which AI coding tools are installed by checking
|
|
5
|
+
* for their config directories/files on the filesystem.
|
|
6
|
+
*/
|
|
7
|
+
export interface DetectedTool {
|
|
8
|
+
name: string;
|
|
9
|
+
id: "claude-desktop" | "claude-code" | "cursor" | "windsurf" | "vscode";
|
|
10
|
+
configPath: string;
|
|
11
|
+
/** Key path within the JSON config for MCP servers */
|
|
12
|
+
mcpKey: string;
|
|
13
|
+
detected: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get all supported tools with detection status
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectTools(): DetectedTool[];
|
|
19
|
+
//# sourceMappingURL=detect-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-tool.d.ts","sourceRoot":"","sources":["../../src/cli/detect-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,gBAAgB,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AA6BD;;GAEG;AACH,wBAAgB,WAAW,IAAI,YAAY,EAAE,CA+D5C"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Tool Detection
|
|
3
|
+
*
|
|
4
|
+
* Detects which AI coding tools are installed by checking
|
|
5
|
+
* for their config directories/files on the filesystem.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { homedir, platform } from "node:os";
|
|
10
|
+
import { execSync } from "node:child_process";
|
|
11
|
+
/**
|
|
12
|
+
* Get the Claude Desktop config path for the current OS
|
|
13
|
+
*/
|
|
14
|
+
function getClaudeDesktopConfigPath() {
|
|
15
|
+
const os = platform();
|
|
16
|
+
if (os === "darwin") {
|
|
17
|
+
return join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
18
|
+
}
|
|
19
|
+
if (os === "win32") {
|
|
20
|
+
return join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
21
|
+
}
|
|
22
|
+
// Linux
|
|
23
|
+
return join(homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if Claude Code CLI is available
|
|
27
|
+
*/
|
|
28
|
+
function isClaudeCodeAvailable() {
|
|
29
|
+
try {
|
|
30
|
+
execSync("claude --version", { stdio: "ignore" });
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get all supported tools with detection status
|
|
39
|
+
*/
|
|
40
|
+
export function detectTools() {
|
|
41
|
+
const home = homedir();
|
|
42
|
+
const tools = [
|
|
43
|
+
{
|
|
44
|
+
name: "Claude Desktop",
|
|
45
|
+
id: "claude-desktop",
|
|
46
|
+
configPath: getClaudeDesktopConfigPath(),
|
|
47
|
+
mcpKey: "mcpServers",
|
|
48
|
+
detected: false,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "Claude Code",
|
|
52
|
+
id: "claude-code",
|
|
53
|
+
configPath: "", // Uses CLI, not a config file
|
|
54
|
+
mcpKey: "",
|
|
55
|
+
detected: false,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "Cursor",
|
|
59
|
+
id: "cursor",
|
|
60
|
+
configPath: join(home, ".cursor", "mcp.json"),
|
|
61
|
+
mcpKey: "mcpServers",
|
|
62
|
+
detected: false,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "Windsurf",
|
|
66
|
+
id: "windsurf",
|
|
67
|
+
configPath: join(home, ".codeium", "windsurf", "mcp_config.json"),
|
|
68
|
+
mcpKey: "mcpServers",
|
|
69
|
+
detected: false,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "VS Code + Copilot",
|
|
73
|
+
id: "vscode",
|
|
74
|
+
configPath: join(process.cwd(), ".vscode", "settings.json"),
|
|
75
|
+
mcpKey: "mcp",
|
|
76
|
+
detected: false,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
// Detect Claude Desktop by checking if config dir exists
|
|
80
|
+
const claudeDesktopDir = join(getClaudeDesktopConfigPath(), "..");
|
|
81
|
+
tools[0].detected = existsSync(claudeDesktopDir);
|
|
82
|
+
// Detect Claude Code via CLI
|
|
83
|
+
tools[1].detected = isClaudeCodeAvailable();
|
|
84
|
+
// Detect Cursor
|
|
85
|
+
tools[2].detected = existsSync(join(home, ".cursor"));
|
|
86
|
+
// Detect Windsurf
|
|
87
|
+
tools[3].detected = existsSync(join(home, ".codeium", "windsurf"));
|
|
88
|
+
// Detect VS Code — check for the `code` CLI or .vscode directory in cwd
|
|
89
|
+
try {
|
|
90
|
+
execSync("code --version", { stdio: "ignore" });
|
|
91
|
+
tools[4].detected = true;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
tools[4].detected = existsSync(join(process.cwd(), ".vscode"));
|
|
95
|
+
}
|
|
96
|
+
return tools;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=detect-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-tool.js","sourceRoot":"","sources":["../../src/cli/detect-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Frase MCP Server — Interactive Setup
|
|
4
|
+
*
|
|
5
|
+
* Usage: npx @frase/mcp-server init
|
|
6
|
+
*
|
|
7
|
+
* Detects installed AI tools, prompts for API key,
|
|
8
|
+
* and auto-configures the MCP server.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Main init flow
|
|
12
|
+
*/
|
|
13
|
+
export declare function runInit(): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":";AAEA;;;;;;;GAOG;AAiBH;;GAEG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAuI7C"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Frase MCP Server — Interactive Setup
|
|
4
|
+
*
|
|
5
|
+
* Usage: npx @frase/mcp-server init
|
|
6
|
+
*
|
|
7
|
+
* Detects installed AI tools, prompts for API key,
|
|
8
|
+
* and auto-configures the MCP server.
|
|
9
|
+
*/
|
|
10
|
+
import { createInterface } from "node:readline/promises";
|
|
11
|
+
import { stdin, stdout } from "node:process";
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
|
+
import { detectTools } from "./detect-tool.js";
|
|
14
|
+
import { writeFraseConfig, hasFraseEntry } from "./config-writer.js";
|
|
15
|
+
const API_KEY_URL = "https://next.frase.io/settings/api";
|
|
16
|
+
/**
|
|
17
|
+
* Validate API key format
|
|
18
|
+
*/
|
|
19
|
+
function isValidApiKey(key) {
|
|
20
|
+
return /^sk_(live|test)_.{10,}$/.test(key);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Main init flow
|
|
24
|
+
*/
|
|
25
|
+
export async function runInit() {
|
|
26
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
27
|
+
try {
|
|
28
|
+
console.log("");
|
|
29
|
+
console.log(" Frase MCP Server Setup");
|
|
30
|
+
console.log(" ----------------------");
|
|
31
|
+
console.log("");
|
|
32
|
+
// Step 1: Detect tools
|
|
33
|
+
console.log(" Scanning for AI tools...");
|
|
34
|
+
const tools = detectTools();
|
|
35
|
+
const detected = tools.filter((t) => t.detected);
|
|
36
|
+
if (detected.length === 0) {
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log(" No supported AI tools detected.");
|
|
39
|
+
console.log(" Supported: Claude Desktop, Claude Code, Cursor, Windsurf, VS Code + Copilot");
|
|
40
|
+
console.log("");
|
|
41
|
+
console.log(" You can still configure manually. See:");
|
|
42
|
+
console.log(" https://github.com/frase-io/frase/tree/main/packages/customer-mcp-server#readme");
|
|
43
|
+
console.log("");
|
|
44
|
+
rl.close();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.log("");
|
|
48
|
+
for (const tool of tools) {
|
|
49
|
+
const mark = tool.detected ? "[*]" : "[ ]";
|
|
50
|
+
console.log(` ${mark} ${tool.name}`);
|
|
51
|
+
}
|
|
52
|
+
console.log("");
|
|
53
|
+
// Step 2: Select tool
|
|
54
|
+
let selectedTool;
|
|
55
|
+
if (detected.length === 1) {
|
|
56
|
+
selectedTool = detected[0];
|
|
57
|
+
console.log(` Using: ${selectedTool.name}`);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.log(" Which tool do you want to configure?");
|
|
61
|
+
for (let i = 0; i < detected.length; i++) {
|
|
62
|
+
console.log(` ${i + 1}) ${detected[i].name}`);
|
|
63
|
+
}
|
|
64
|
+
console.log("");
|
|
65
|
+
let choice = -1;
|
|
66
|
+
while (choice < 1 || choice > detected.length) {
|
|
67
|
+
const answer = await rl.question(` Enter number (1-${detected.length}): `);
|
|
68
|
+
choice = parseInt(answer, 10);
|
|
69
|
+
if (isNaN(choice) || choice < 1 || choice > detected.length) {
|
|
70
|
+
console.log(" Invalid choice. Try again.");
|
|
71
|
+
choice = -1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
selectedTool = detected[choice - 1];
|
|
75
|
+
}
|
|
76
|
+
console.log("");
|
|
77
|
+
// Step 3: Get API key
|
|
78
|
+
console.log(` Get your API key from: ${API_KEY_URL}`);
|
|
79
|
+
console.log("");
|
|
80
|
+
let apiKey = "";
|
|
81
|
+
while (!apiKey) {
|
|
82
|
+
const answer = await rl.question(" Frase API key: ");
|
|
83
|
+
const trimmed = answer.trim();
|
|
84
|
+
if (!trimmed) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (!isValidApiKey(trimmed)) {
|
|
88
|
+
console.log(" Invalid format. API keys start with sk_live_ or sk_test_");
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
apiKey = trimmed;
|
|
92
|
+
}
|
|
93
|
+
console.log("");
|
|
94
|
+
// Step 4: Check for existing config
|
|
95
|
+
if (selectedTool.id !== "claude-code" && hasFraseEntry(selectedTool)) {
|
|
96
|
+
const overwrite = await rl.question(" Frase is already configured. Overwrite? (y/N): ");
|
|
97
|
+
if (overwrite.trim().toLowerCase() !== "y") {
|
|
98
|
+
console.log(" Skipped. Existing configuration preserved.");
|
|
99
|
+
console.log("");
|
|
100
|
+
rl.close();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.log("");
|
|
104
|
+
}
|
|
105
|
+
// Step 5: Configure
|
|
106
|
+
console.log(` Configuring ${selectedTool.name}...`);
|
|
107
|
+
if (selectedTool.id === "claude-code") {
|
|
108
|
+
// Use Claude Code CLI directly
|
|
109
|
+
try {
|
|
110
|
+
execSync(`claude mcp add frase -e FRASE_API_KEY=${apiKey} -- npx -y @frase/mcp-server`, { stdio: "inherit" });
|
|
111
|
+
console.log("");
|
|
112
|
+
console.log(" Done! Frase MCP server added to Claude Code.");
|
|
113
|
+
console.log(" Start a new conversation to use Frase tools.");
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Fallback: show manual instructions
|
|
117
|
+
console.log("");
|
|
118
|
+
console.log(" Could not run 'claude mcp add' automatically.");
|
|
119
|
+
console.log(" Run this command manually:");
|
|
120
|
+
console.log("");
|
|
121
|
+
const masked = apiKey.slice(0, 8) + "..." + apiKey.slice(-4);
|
|
122
|
+
console.log(` claude mcp add frase -e FRASE_API_KEY=<your-key> -- npx -y @frase/mcp-server`);
|
|
123
|
+
console.log("");
|
|
124
|
+
console.log(` Your key starts with: ${masked}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
try {
|
|
129
|
+
const configPath = writeFraseConfig(selectedTool, apiKey);
|
|
130
|
+
console.log(` Config written to: ${configPath}`);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
134
|
+
console.log(` Error: ${msg}`);
|
|
135
|
+
rl.close();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
console.log("");
|
|
140
|
+
console.log(" Setup complete!");
|
|
141
|
+
console.log("");
|
|
142
|
+
// Step 6: Show next steps
|
|
143
|
+
printNextSteps(selectedTool);
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
rl.close();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function printNextSteps(tool) {
|
|
150
|
+
console.log(" Next steps:");
|
|
151
|
+
switch (tool.id) {
|
|
152
|
+
case "claude-desktop":
|
|
153
|
+
console.log(" 1. Restart Claude Desktop");
|
|
154
|
+
console.log(" 2. Look for 'frase' in the MCP tools icon");
|
|
155
|
+
console.log(" 3. Try: 'List my Frase sites'");
|
|
156
|
+
break;
|
|
157
|
+
case "claude-code":
|
|
158
|
+
console.log(" 1. Start a new Claude Code conversation");
|
|
159
|
+
console.log(" 2. Try: 'List my Frase sites'");
|
|
160
|
+
break;
|
|
161
|
+
case "cursor":
|
|
162
|
+
console.log(" 1. Restart Cursor");
|
|
163
|
+
console.log(" 2. Open Cursor Settings > MCP to verify");
|
|
164
|
+
console.log(" 3. Try in chat: 'List my Frase sites'");
|
|
165
|
+
break;
|
|
166
|
+
case "windsurf":
|
|
167
|
+
console.log(" 1. Restart Windsurf");
|
|
168
|
+
console.log(" 2. Try in Cascade: 'List my Frase sites'");
|
|
169
|
+
break;
|
|
170
|
+
case "vscode":
|
|
171
|
+
console.log(" 1. Reload VS Code window (Cmd+Shift+P > 'Reload Window')");
|
|
172
|
+
console.log(" 2. Open Copilot chat");
|
|
173
|
+
console.log(" 3. Try: 'List my Frase sites'");
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
console.log("");
|
|
177
|
+
console.log(" Available tools: sites, content, briefs, research, audits,");
|
|
178
|
+
console.log(" analytics, AI visibility, SERP analysis, and more.");
|
|
179
|
+
console.log(" Full docs: https://frase.io/agents");
|
|
180
|
+
console.log("");
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -12,7 +12,7 @@ export function loadConfig() {
|
|
|
12
12
|
const apiKey = process.env.FRASE_API_KEY;
|
|
13
13
|
if (!apiKey) {
|
|
14
14
|
throw new Error("FRASE_API_KEY environment variable is required. " +
|
|
15
|
-
"Get your API key from https://
|
|
15
|
+
"Get your API key from https://next.frase.io/settings/api");
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
18
18
|
apiKey,
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;GAEG;AACH,MAAM,eAAe,GAAG,8BAA8B,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;YAChD,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;GAEG;AACH,MAAM,eAAe,GAAG,8BAA8B,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAEzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;YAChD,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,eAAe;QACpD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM;KAC9C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,GAAG,IAAe;IACzD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
|