@bulkpublishing/mcp-server 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 +170 -0
- package/dist/ai/engine.d.ts +12 -0
- package/dist/ai/engine.d.ts.map +1 -0
- package/dist/ai/engine.js +397 -0
- package/dist/ai/engine.js.map +1 -0
- package/dist/ai/prompts.d.ts +30 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +207 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/auth/context.d.ts +81 -0
- package/dist/auth/context.d.ts.map +1 -0
- package/dist/auth/context.js +68 -0
- package/dist/auth/context.js.map +1 -0
- package/dist/auth/validate.d.ts +13 -0
- package/dist/auth/validate.d.ts.map +1 -0
- package/dist/auth/validate.js +87 -0
- package/dist/auth/validate.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/csv.d.ts +18 -0
- package/dist/tools/csv.d.ts.map +1 -0
- package/dist/tools/csv.js +673 -0
- package/dist/tools/csv.js.map +1 -0
- package/dist/tools/generation.d.ts +14 -0
- package/dist/tools/generation.d.ts.map +1 -0
- package/dist/tools/generation.js +291 -0
- package/dist/tools/generation.js.map +1 -0
- package/dist/tools/indexing.d.ts +11 -0
- package/dist/tools/indexing.d.ts.map +1 -0
- package/dist/tools/indexing.js +219 -0
- package/dist/tools/indexing.js.map +1 -0
- package/dist/tools/projects.d.ts +11 -0
- package/dist/tools/projects.d.ts.map +1 -0
- package/dist/tools/projects.js +181 -0
- package/dist/tools/projects.js.map +1 -0
- package/dist/tools/research.d.ts +12 -0
- package/dist/tools/research.d.ts.map +1 -0
- package/dist/tools/research.js +88 -0
- package/dist/tools/research.js.map +1 -0
- package/dist/tools/seo.d.ts +12 -0
- package/dist/tools/seo.d.ts.map +1 -0
- package/dist/tools/seo.js +164 -0
- package/dist/tools/seo.js.map +1 -0
- package/dist/tools/wordpress.d.ts +15 -0
- package/dist/tools/wordpress.d.ts.map +1 -0
- package/dist/tools/wordpress.js +447 -0
- package/dist/tools/wordpress.js.map +1 -0
- package/dist/types.d.ts +206 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Bulk Publishing AI — MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server that exposes BPAI's content generation, WordPress publishing, SEO, and indexing capabilities as tools callable from any MCP-compatible client.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### 1. Install Dependencies
|
|
8
|
+
```bash
|
|
9
|
+
cd mcp-server
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 2. Build
|
|
14
|
+
```bash
|
|
15
|
+
npm run build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### 3. Run (Development)
|
|
19
|
+
```bash
|
|
20
|
+
npm run dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### 4. Run (Production)
|
|
24
|
+
```bash
|
|
25
|
+
npm start
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Connecting to MCP Clients
|
|
29
|
+
|
|
30
|
+
### Claude Desktop / Antigravity
|
|
31
|
+
|
|
32
|
+
Add to your MCP config file:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"mcpServers": {
|
|
37
|
+
"bulk-publishing-ai": {
|
|
38
|
+
"command": "node",
|
|
39
|
+
"args": ["/path/to/mcp-server/dist/index.js"],
|
|
40
|
+
"env": {
|
|
41
|
+
"OPENAI_API_KEY": "sk-...",
|
|
42
|
+
"GEMINI_API_KEY": "AI...",
|
|
43
|
+
"PERPLEXITY_API_KEY": "pplx-..."
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Cursor
|
|
51
|
+
|
|
52
|
+
Add to `.cursor/mcp.json`:
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"bulk-publishing-ai": {
|
|
57
|
+
"command": "node",
|
|
58
|
+
"args": ["./mcp-server/dist/index.js"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Available Tools
|
|
65
|
+
|
|
66
|
+
### Content Generation
|
|
67
|
+
| Tool | Description |
|
|
68
|
+
|------|-------------|
|
|
69
|
+
| `generate_article` | Generate a single SEO-optimized article from a keyword |
|
|
70
|
+
| `generate_batch` | Generate multiple articles from a keyword list |
|
|
71
|
+
| `list_models` | List all 50+ available AI models |
|
|
72
|
+
|
|
73
|
+
### Research
|
|
74
|
+
| Tool | Description |
|
|
75
|
+
|------|-------------|
|
|
76
|
+
| `research_topic` | Live web research with citations via Perplexity Sonar |
|
|
77
|
+
|
|
78
|
+
### SEO
|
|
79
|
+
| Tool | Description |
|
|
80
|
+
|------|-------------|
|
|
81
|
+
| `generate_seo_metadata` | Generate title, slug, and meta description |
|
|
82
|
+
| `humanize_content` | Anti-AI detection rewrite pass |
|
|
83
|
+
|
|
84
|
+
### WordPress Publishing
|
|
85
|
+
| Tool | Description |
|
|
86
|
+
|------|-------------|
|
|
87
|
+
| `test_wp_connection` | Verify WordPress credentials and fetch site info |
|
|
88
|
+
| `publish_to_wordpress` | Publish articles to WordPress via REST API |
|
|
89
|
+
| `publish_batch` | Publish multiple articles with rate limiting |
|
|
90
|
+
| `list_wp_categories` | List WordPress categories for publishing |
|
|
91
|
+
|
|
92
|
+
### Indexing
|
|
93
|
+
| Tool | Description |
|
|
94
|
+
|------|-------------|
|
|
95
|
+
| `broadcast_urls` | Submit URLs to IndexNow and ping services |
|
|
96
|
+
| `indexnow_submit` | Direct IndexNow API submission |
|
|
97
|
+
| `fetch_sitemap` | Parse sitemap.xml and return URL list |
|
|
98
|
+
|
|
99
|
+
### CSV Import / Export
|
|
100
|
+
| Tool | Description |
|
|
101
|
+
|------|-------------|
|
|
102
|
+
| `import_csv` | Read CSV, auto-detect columns, preview rows |
|
|
103
|
+
| `export_csv` | Export articles to CSV file |
|
|
104
|
+
| `export_markdown` | Export articles as .md files with YAML frontmatter |
|
|
105
|
+
| `export_json` | Export articles as structured JSON |
|
|
106
|
+
| `export_bulk` | Multi-format export with advanced filtering |
|
|
107
|
+
|
|
108
|
+
### Projects
|
|
109
|
+
| Tool | Description |
|
|
110
|
+
|------|-------------|
|
|
111
|
+
| `list_projects` | List all your projects |
|
|
112
|
+
| `get_project` | Get project details and settings |
|
|
113
|
+
|
|
114
|
+
## API Keys
|
|
115
|
+
|
|
116
|
+
Keys can be provided two ways:
|
|
117
|
+
1. **Environment variables** (recommended for persistent config)
|
|
118
|
+
2. **Inline per-tool call** (for ad-hoc usage)
|
|
119
|
+
|
|
120
|
+
| Provider | Env Variable | Tool Parameter |
|
|
121
|
+
|----------|-------------|----------------|
|
|
122
|
+
| OpenAI | `OPENAI_API_KEY` | `api_key_openai` |
|
|
123
|
+
| Claude | `CLAUDE_API_KEY` | `api_key_claude` |
|
|
124
|
+
| Gemini | `GEMINI_API_KEY` | `api_key_gemini` |
|
|
125
|
+
| DeepSeek | `DEEPSEEK_API_KEY` | `api_key_deepseek` |
|
|
126
|
+
| Grok | `GROK_API_KEY` | `api_key_grok` |
|
|
127
|
+
| Perplexity | `PERPLEXITY_API_KEY` | `api_key_perplexity` |
|
|
128
|
+
| Kimi | `KIMI_API_KEY` | `api_key_kimi` |
|
|
129
|
+
| IndexNow | `INDEXNOW_KEY` | `indexnow_key` |
|
|
130
|
+
|
|
131
|
+
## Architecture
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
mcp-server/
|
|
135
|
+
├── src/
|
|
136
|
+
│ ├── index.ts # Server entry point (stdio transport)
|
|
137
|
+
│ ├── types.ts # Shared type definitions
|
|
138
|
+
│ ├── auth/
|
|
139
|
+
│ │ └── context.ts # User authentication context
|
|
140
|
+
│ ├── ai/
|
|
141
|
+
│ │ ├── engine.ts # Multi-provider AI generation engine
|
|
142
|
+
│ │ └── prompts.ts # Prompt templates and builders
|
|
143
|
+
│ └── tools/
|
|
144
|
+
│ ├── generation.ts # Article generation tools
|
|
145
|
+
│ ├── research.ts # Web research tool
|
|
146
|
+
│ ├── seo.ts # SEO metadata and humanization
|
|
147
|
+
│ ├── wordpress.ts # WordPress publishing tools
|
|
148
|
+
│ ├── indexing.ts # URL broadcasting and sitemap tools
|
|
149
|
+
│ ├── projects.ts # Project management tools
|
|
150
|
+
│ └── csv.ts # CSV import/export tools
|
|
151
|
+
├── dist/ # Compiled output
|
|
152
|
+
├── package.json
|
|
153
|
+
└── tsconfig.json
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Supported Providers & Models
|
|
157
|
+
|
|
158
|
+
| Provider | Models |
|
|
159
|
+
|----------|--------|
|
|
160
|
+
| OpenAI | GPT-5.2, GPT-5.1, GPT-5 Mini, GPT-4.1, O4 Mini |
|
|
161
|
+
| Claude | Opus 4.5, Sonnet 4.5, 3.7 Sonnet, 3.5 Sonnet/Haiku |
|
|
162
|
+
| Gemini | 3 Pro, 3 Flash, 2.5 Pro/Flash, 2.0 Flash |
|
|
163
|
+
| Grok | 4 Flagship, 4.1 Fast, 3, 3 Mini |
|
|
164
|
+
| DeepSeek | Reasoner (V3.2), Chat |
|
|
165
|
+
| Kimi | K2.5 Thinking, K2.5, K2 |
|
|
166
|
+
| Perplexity | Sonar Pro, Sonar Reasoning Pro, Deep Research, Sonar |
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BPAI MCP Server — AI Generation Engine
|
|
3
|
+
*
|
|
4
|
+
* Adapted from the web app's src/services/ai/ module for server-side usage.
|
|
5
|
+
* Instead of routing through Netlify edge function proxies, this module calls
|
|
6
|
+
* AI provider APIs directly (since MCP runs server-side, no CORS restriction).
|
|
7
|
+
*/
|
|
8
|
+
import type { AIProvider, ApiKeys, GenerationRequest, GenerationResponse, AIModel, ModelTokenLimits } from '../types.js';
|
|
9
|
+
export declare const MODEL_TOKEN_REGISTRY: Record<string, ModelTokenLimits>;
|
|
10
|
+
export declare function generateContent(request: GenerationRequest, keys: ApiKeys): Promise<GenerationResponse>;
|
|
11
|
+
export declare function listModels(provider?: AIProvider): AIModel[];
|
|
12
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/ai/engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACR,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAElB,OAAO,EACP,gBAAgB,EACnB,MAAM,aAAa,CAAC;AAMrB,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA4CjE,CAAC;AAwUF,wBAAsB,eAAe,CACjC,OAAO,EAAE,iBAAiB,EAC1B,IAAI,EAAE,OAAO,GACd,OAAO,CAAC,kBAAkB,CAAC,CAY7B;AAMD,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,OAAO,EAAE,CAiC3D"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BPAI MCP Server — AI Generation Engine
|
|
3
|
+
*
|
|
4
|
+
* Adapted from the web app's src/services/ai/ module for server-side usage.
|
|
5
|
+
* Instead of routing through Netlify edge function proxies, this module calls
|
|
6
|
+
* AI provider APIs directly (since MCP runs server-side, no CORS restriction).
|
|
7
|
+
*/
|
|
8
|
+
// ============================================
|
|
9
|
+
// MODEL REGISTRY (from modelRegistry.ts)
|
|
10
|
+
// ============================================
|
|
11
|
+
export const MODEL_TOKEN_REGISTRY = {
|
|
12
|
+
// GOOGLE GEMINI
|
|
13
|
+
'gemini-3-pro': { inputTokens: 1048576, outputTokens: 1048576, displayName: 'Gemini 3 Pro' },
|
|
14
|
+
'gemini-3-flash': { inputTokens: 1048576, outputTokens: 1048576, displayName: 'Gemini 3 Flash' },
|
|
15
|
+
'gemini-2.5-pro': { inputTokens: 1048576, outputTokens: 1048576, displayName: 'Gemini 2.5 Pro' },
|
|
16
|
+
'gemini-2.5-flash': { inputTokens: 1048576, outputTokens: 65536, displayName: 'Gemini 2.5 Flash' },
|
|
17
|
+
'gemini-2.0-flash': { inputTokens: 1048576, outputTokens: 8192, displayName: 'Gemini 2.0 Flash' },
|
|
18
|
+
// OPENAI
|
|
19
|
+
'gpt-5.2': { inputTokens: 400000, outputTokens: 131072, displayName: 'GPT-5.2' },
|
|
20
|
+
'gpt-5.1': { inputTokens: 400000, outputTokens: 131072, displayName: 'GPT-5.1' },
|
|
21
|
+
'gpt-5-mini': { inputTokens: 400000, outputTokens: 131072, displayName: 'GPT-5 Mini' },
|
|
22
|
+
'gpt-4.1': { inputTokens: 1048576, outputTokens: 32768, displayName: 'GPT-4.1' },
|
|
23
|
+
'gpt-4.1-mini': { inputTokens: 1048576, outputTokens: 32768, displayName: 'GPT-4.1 Mini' },
|
|
24
|
+
'gpt-4.1-nano': { inputTokens: 1048576, outputTokens: 32768, displayName: 'GPT-4.1 Nano' },
|
|
25
|
+
'o4-mini': { inputTokens: 200000, outputTokens: 100000, displayName: 'O4 Mini' },
|
|
26
|
+
// ANTHROPIC (CLAUDE)
|
|
27
|
+
'claude-opus-4.5': { inputTokens: 200000, outputTokens: 65536, displayName: 'Claude Opus 4.5' },
|
|
28
|
+
'claude-sonnet-4.5': { inputTokens: 200000, outputTokens: 65536, displayName: 'Claude Sonnet 4.5' },
|
|
29
|
+
'claude-3.7-sonnet': { inputTokens: 200000, outputTokens: 131072, displayName: 'Claude 3.7 Sonnet' },
|
|
30
|
+
'claude-3-5-sonnet-latest': { inputTokens: 200000, outputTokens: 8192, displayName: 'Claude 3.5 Sonnet' },
|
|
31
|
+
'claude-3-5-haiku-latest': { inputTokens: 200000, outputTokens: 8192, displayName: 'Claude 3.5 Haiku' },
|
|
32
|
+
// XAI (GROK)
|
|
33
|
+
'grok-4-flagship': { inputTokens: 262144, outputTokens: 32768, displayName: 'Grok 4 Flagship' },
|
|
34
|
+
'grok-4.1-fast': { inputTokens: 2097152, outputTokens: 32768, displayName: 'Grok 4.1 Fast' },
|
|
35
|
+
'grok-3': { inputTokens: 131072, outputTokens: 8192, displayName: 'Grok 3' },
|
|
36
|
+
'grok-3-mini': { inputTokens: 131072, outputTokens: 8192, displayName: 'Grok 3 Mini' },
|
|
37
|
+
// DEEPSEEK
|
|
38
|
+
'deepseek-reasoner': { inputTokens: 131072, outputTokens: 65536, displayName: 'DeepSeek Reasoner (V3.2)' },
|
|
39
|
+
'deepseek-chat': { inputTokens: 131072, outputTokens: 65536, displayName: 'DeepSeek Chat' },
|
|
40
|
+
// KIMI (MOONSHOT)
|
|
41
|
+
'kimi-k2.5-thinking': { inputTokens: 262144, outputTokens: 32768, displayName: 'Kimi K2.5 Thinking' },
|
|
42
|
+
'kimi-k2.5': { inputTokens: 262144, outputTokens: 32768, displayName: 'Kimi K2.5' },
|
|
43
|
+
'kimi-k2': { inputTokens: 131072, outputTokens: 32768, displayName: 'Kimi K2' },
|
|
44
|
+
// PERPLEXITY
|
|
45
|
+
'sonar-pro': { inputTokens: 127000, outputTokens: 4096, displayName: 'Sonar Pro' },
|
|
46
|
+
'sonar-reasoning-pro': { inputTokens: 127000, outputTokens: 4096, displayName: 'Sonar Reasoning Pro' },
|
|
47
|
+
'sonar-deep-research': { inputTokens: 127000, outputTokens: 4096, displayName: 'Sonar Deep Research' },
|
|
48
|
+
'sonar': { inputTokens: 127000, outputTokens: 4096, displayName: 'Sonar' },
|
|
49
|
+
};
|
|
50
|
+
// ============================================
|
|
51
|
+
// REASONING MODEL DETECTION
|
|
52
|
+
// ============================================
|
|
53
|
+
const NO_TEMPERATURE_MODELS = [
|
|
54
|
+
'o1', 'o3', 'o4', 'o4-mini', 'o4-mini-high',
|
|
55
|
+
'gpt-5.2-thinking', 'gpt-5-mini',
|
|
56
|
+
'kimi-k2.5',
|
|
57
|
+
'deepseek-reasoner',
|
|
58
|
+
];
|
|
59
|
+
function modelSupportsTemperature(model) {
|
|
60
|
+
const lower = model.toLowerCase();
|
|
61
|
+
if (NO_TEMPERATURE_MODELS.some(id => lower.startsWith(id) || lower.includes(id))) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (lower.includes('reasoning') || lower.includes('thinking')) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
// ============================================
|
|
70
|
+
// PROVIDER API ENDPOINTS (direct, no proxy)
|
|
71
|
+
// ============================================
|
|
72
|
+
const PROVIDER_ENDPOINTS = {
|
|
73
|
+
openai: 'https://api.openai.com/v1/chat/completions',
|
|
74
|
+
claude: 'https://api.anthropic.com/v1/messages',
|
|
75
|
+
deepseek: 'https://api.deepseek.com/chat/completions',
|
|
76
|
+
grok: 'https://api.x.ai/v1/chat/completions',
|
|
77
|
+
gemini: 'https://generativelanguage.googleapis.com/v1beta',
|
|
78
|
+
perplexity: 'https://api.perplexity.ai/chat/completions',
|
|
79
|
+
kimi: 'https://api.moonshot.cn/v1/chat/completions',
|
|
80
|
+
};
|
|
81
|
+
// ============================================
|
|
82
|
+
// GENERATION FUNCTIONS (per-provider)
|
|
83
|
+
// ============================================
|
|
84
|
+
async function generateOpenAI(request, keys) {
|
|
85
|
+
if (!keys.openai)
|
|
86
|
+
return { text: '', error: 'OpenAI API Key is missing.' };
|
|
87
|
+
const model = request.settings.model || 'gpt-5.2';
|
|
88
|
+
const supportsTemp = modelSupportsTemperature(model);
|
|
89
|
+
const payload = {
|
|
90
|
+
model,
|
|
91
|
+
messages: [
|
|
92
|
+
{ role: 'system', content: request.systemPrompt },
|
|
93
|
+
{ role: 'user', content: request.userPrompt },
|
|
94
|
+
],
|
|
95
|
+
max_completion_tokens: request.settings.maxTokens,
|
|
96
|
+
};
|
|
97
|
+
if (supportsTemp) {
|
|
98
|
+
payload.temperature = request.settings.temperature;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
let response = await fetch(PROVIDER_ENDPOINTS.openai, {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers: {
|
|
104
|
+
'Content-Type': 'application/json',
|
|
105
|
+
'Authorization': `Bearer ${keys.openai}`,
|
|
106
|
+
},
|
|
107
|
+
body: JSON.stringify(payload),
|
|
108
|
+
});
|
|
109
|
+
// Self-healing: retry without temperature if rejected
|
|
110
|
+
if (response.status === 400) {
|
|
111
|
+
const errorText = await response.text();
|
|
112
|
+
if (errorText.includes('temperature')) {
|
|
113
|
+
delete payload.temperature;
|
|
114
|
+
response = await fetch(PROVIDER_ENDPOINTS.openai, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
'Content-Type': 'application/json',
|
|
118
|
+
'Authorization': `Bearer ${keys.openai}`,
|
|
119
|
+
},
|
|
120
|
+
body: JSON.stringify(payload),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return { text: '', error: `OpenAI Error (400): ${errorText.substring(0, 300)}` };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const errorText = await response.text();
|
|
129
|
+
return { text: '', error: `OpenAI Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
130
|
+
}
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
return { text: data.choices?.[0]?.message?.content || '' };
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
return { text: '', error: `OpenAI Network Error: ${error.message}` };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function generateClaude(request, keys) {
|
|
139
|
+
if (!keys.claude)
|
|
140
|
+
return { text: '', error: 'Claude API Key is missing.' };
|
|
141
|
+
const model = request.settings.model || 'claude-opus-4.5';
|
|
142
|
+
try {
|
|
143
|
+
const response = await fetch(PROVIDER_ENDPOINTS.claude, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: {
|
|
146
|
+
'Content-Type': 'application/json',
|
|
147
|
+
'x-api-key': keys.claude,
|
|
148
|
+
'anthropic-version': '2023-06-01',
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify({
|
|
151
|
+
model,
|
|
152
|
+
system: request.systemPrompt,
|
|
153
|
+
messages: [{ role: 'user', content: request.userPrompt }],
|
|
154
|
+
max_tokens: request.settings.maxTokens,
|
|
155
|
+
temperature: request.settings.temperature,
|
|
156
|
+
}),
|
|
157
|
+
});
|
|
158
|
+
if (!response.ok) {
|
|
159
|
+
const errorText = await response.text();
|
|
160
|
+
return { text: '', error: `Claude Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
161
|
+
}
|
|
162
|
+
const data = await response.json();
|
|
163
|
+
const text = data.content?.[0]?.text || '';
|
|
164
|
+
return { text };
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
return { text: '', error: `Claude Network Error: ${error.message}` };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function generateGemini(request, keys) {
|
|
171
|
+
if (!keys.gemini)
|
|
172
|
+
return { text: '', error: 'Gemini API Key missing.' };
|
|
173
|
+
const model = request.settings.model || 'gemini-3-pro';
|
|
174
|
+
try {
|
|
175
|
+
const url = `${PROVIDER_ENDPOINTS.gemini}/models/${model}:generateContent?key=${keys.gemini}`;
|
|
176
|
+
const response = await fetch(url, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
headers: { 'Content-Type': 'application/json' },
|
|
179
|
+
body: JSON.stringify({
|
|
180
|
+
contents: [{
|
|
181
|
+
role: 'user',
|
|
182
|
+
parts: [{ text: `${request.systemPrompt}\n\n${request.userPrompt}` }],
|
|
183
|
+
}],
|
|
184
|
+
generationConfig: {
|
|
185
|
+
temperature: request.settings.temperature,
|
|
186
|
+
maxOutputTokens: request.settings.maxTokens,
|
|
187
|
+
},
|
|
188
|
+
}),
|
|
189
|
+
});
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
const errorText = await response.text();
|
|
192
|
+
return { text: '', error: `Gemini Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
193
|
+
}
|
|
194
|
+
const data = await response.json();
|
|
195
|
+
const text = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
|
|
196
|
+
return { text };
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
return { text: '', error: `Gemini Network Error: ${error.message}` };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function generateDeepSeek(request, keys) {
|
|
203
|
+
if (!keys.deepseek)
|
|
204
|
+
return { text: '', error: 'DeepSeek API Key is missing.' };
|
|
205
|
+
const model = request.settings.model || 'deepseek-chat';
|
|
206
|
+
const isReasoning = model.includes('reasoner');
|
|
207
|
+
const payload = {
|
|
208
|
+
model,
|
|
209
|
+
messages: [
|
|
210
|
+
{ role: 'system', content: request.systemPrompt },
|
|
211
|
+
{ role: 'user', content: request.userPrompt },
|
|
212
|
+
],
|
|
213
|
+
max_tokens: Math.min(request.settings.maxTokens, isReasoning ? 65536 : 8192),
|
|
214
|
+
};
|
|
215
|
+
if (!isReasoning) {
|
|
216
|
+
payload.temperature = request.settings.temperature;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const response = await fetch(PROVIDER_ENDPOINTS.deepseek, {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: {
|
|
222
|
+
'Content-Type': 'application/json',
|
|
223
|
+
'Authorization': `Bearer ${keys.deepseek}`,
|
|
224
|
+
},
|
|
225
|
+
body: JSON.stringify(payload),
|
|
226
|
+
});
|
|
227
|
+
if (!response.ok) {
|
|
228
|
+
const errorText = await response.text();
|
|
229
|
+
return { text: '', error: `DeepSeek Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
230
|
+
}
|
|
231
|
+
const data = await response.json();
|
|
232
|
+
return { text: data.choices?.[0]?.message?.content || '' };
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
return { text: '', error: `DeepSeek Network Error: ${error.message}` };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async function generateGrok(request, keys) {
|
|
239
|
+
if (!keys.grok)
|
|
240
|
+
return { text: '', error: 'Grok API Key missing.' };
|
|
241
|
+
try {
|
|
242
|
+
const response = await fetch(PROVIDER_ENDPOINTS.grok, {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
headers: {
|
|
245
|
+
'Content-Type': 'application/json',
|
|
246
|
+
'Authorization': `Bearer ${keys.grok}`,
|
|
247
|
+
},
|
|
248
|
+
body: JSON.stringify({
|
|
249
|
+
model: request.settings.model || 'grok-4.1-fast',
|
|
250
|
+
messages: [
|
|
251
|
+
{ role: 'system', content: request.systemPrompt },
|
|
252
|
+
{ role: 'user', content: request.userPrompt },
|
|
253
|
+
],
|
|
254
|
+
temperature: request.settings.temperature || 0.7,
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
const errorText = await response.text();
|
|
259
|
+
return { text: '', error: `Grok Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
260
|
+
}
|
|
261
|
+
const data = await response.json();
|
|
262
|
+
return { text: data.choices?.[0]?.message?.content || '' };
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
return { text: '', error: `Grok Network Error: ${error.message}` };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async function generatePerplexity(request, keys) {
|
|
269
|
+
if (!keys.perplexity)
|
|
270
|
+
return { text: '', error: 'Perplexity API Key missing.' };
|
|
271
|
+
try {
|
|
272
|
+
const response = await fetch(PROVIDER_ENDPOINTS.perplexity, {
|
|
273
|
+
method: 'POST',
|
|
274
|
+
headers: {
|
|
275
|
+
'Content-Type': 'application/json',
|
|
276
|
+
'Authorization': `Bearer ${keys.perplexity}`,
|
|
277
|
+
},
|
|
278
|
+
body: JSON.stringify({
|
|
279
|
+
model: request.settings.model || 'sonar-pro',
|
|
280
|
+
messages: [
|
|
281
|
+
{ role: 'system', content: request.systemPrompt },
|
|
282
|
+
{ role: 'user', content: request.userPrompt },
|
|
283
|
+
],
|
|
284
|
+
temperature: request.settings.temperature || 0.7,
|
|
285
|
+
}),
|
|
286
|
+
});
|
|
287
|
+
if (!response.ok) {
|
|
288
|
+
const errorText = await response.text();
|
|
289
|
+
return { text: '', error: `Perplexity Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
290
|
+
}
|
|
291
|
+
const data = await response.json();
|
|
292
|
+
const rawCitations = Array.isArray(data.citations) ? data.citations : [];
|
|
293
|
+
const citations = [...new Set(rawCitations)];
|
|
294
|
+
return {
|
|
295
|
+
text: data.choices?.[0]?.message?.content || '',
|
|
296
|
+
citations,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
return { text: '', error: `Perplexity Network Error: ${error.message}` };
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function generateKimi(request, keys) {
|
|
304
|
+
if (!keys.kimi)
|
|
305
|
+
return { text: '', error: 'Kimi API Key missing.' };
|
|
306
|
+
const model = request.settings.model || 'kimi-k2.5';
|
|
307
|
+
const isThinking = model.includes('thinking');
|
|
308
|
+
const payload = {
|
|
309
|
+
model,
|
|
310
|
+
messages: [
|
|
311
|
+
{ role: 'system', content: request.systemPrompt },
|
|
312
|
+
{ role: 'user', content: request.userPrompt },
|
|
313
|
+
],
|
|
314
|
+
max_tokens: request.settings.maxTokens,
|
|
315
|
+
};
|
|
316
|
+
// Kimi K2.5 has a fixed temperature; don't send it
|
|
317
|
+
if (!model.includes('k2.5')) {
|
|
318
|
+
payload.temperature = request.settings.temperature;
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
const response = await fetch(PROVIDER_ENDPOINTS.kimi, {
|
|
322
|
+
method: 'POST',
|
|
323
|
+
headers: {
|
|
324
|
+
'Content-Type': 'application/json',
|
|
325
|
+
'Authorization': `Bearer ${keys.kimi}`,
|
|
326
|
+
},
|
|
327
|
+
body: JSON.stringify(payload),
|
|
328
|
+
});
|
|
329
|
+
if (!response.ok) {
|
|
330
|
+
const errorText = await response.text();
|
|
331
|
+
return { text: '', error: `Kimi Error (${response.status}): ${errorText.substring(0, 300)}` };
|
|
332
|
+
}
|
|
333
|
+
const data = await response.json();
|
|
334
|
+
return { text: data.choices?.[0]?.message?.content || '' };
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
return { text: '', error: `Kimi Network Error: ${error.message}` };
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// ============================================
|
|
341
|
+
// MAIN ROUTER
|
|
342
|
+
// ============================================
|
|
343
|
+
export async function generateContent(request, keys) {
|
|
344
|
+
switch (request.provider) {
|
|
345
|
+
case 'openai': return generateOpenAI(request, keys);
|
|
346
|
+
case 'claude': return generateClaude(request, keys);
|
|
347
|
+
case 'deepseek': return generateDeepSeek(request, keys);
|
|
348
|
+
case 'grok': return generateGrok(request, keys);
|
|
349
|
+
case 'gemini': return generateGemini(request, keys);
|
|
350
|
+
case 'perplexity': return generatePerplexity(request, keys);
|
|
351
|
+
case 'kimi': return generateKimi(request, keys);
|
|
352
|
+
default:
|
|
353
|
+
return { text: '', error: `Unknown provider: ${request.provider}` };
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
// ============================================
|
|
357
|
+
// MODEL LISTING
|
|
358
|
+
// ============================================
|
|
359
|
+
export function listModels(provider) {
|
|
360
|
+
const models = [];
|
|
361
|
+
for (const [id, info] of Object.entries(MODEL_TOKEN_REGISTRY)) {
|
|
362
|
+
// Determine which provider this model belongs to
|
|
363
|
+
let modelProvider;
|
|
364
|
+
if (id.startsWith('gpt') || id.startsWith('o4') || id.startsWith('o3') || id.startsWith('o1')) {
|
|
365
|
+
modelProvider = 'openai';
|
|
366
|
+
}
|
|
367
|
+
else if (id.startsWith('claude')) {
|
|
368
|
+
modelProvider = 'claude';
|
|
369
|
+
}
|
|
370
|
+
else if (id.startsWith('gemini')) {
|
|
371
|
+
modelProvider = 'gemini';
|
|
372
|
+
}
|
|
373
|
+
else if (id.startsWith('grok')) {
|
|
374
|
+
modelProvider = 'grok';
|
|
375
|
+
}
|
|
376
|
+
else if (id.startsWith('deepseek')) {
|
|
377
|
+
modelProvider = 'deepseek';
|
|
378
|
+
}
|
|
379
|
+
else if (id.startsWith('kimi')) {
|
|
380
|
+
modelProvider = 'kimi';
|
|
381
|
+
}
|
|
382
|
+
else if (id.startsWith('sonar')) {
|
|
383
|
+
modelProvider = 'perplexity';
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
if (provider && modelProvider !== provider)
|
|
389
|
+
continue;
|
|
390
|
+
models.push({
|
|
391
|
+
id,
|
|
392
|
+
displayName: `${info.displayName} (${(info.inputTokens / 1000).toFixed(0)}K in, ${(info.outputTokens / 1000).toFixed(0)}K out)`,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
return models;
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/ai/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BPAI MCP Server — Prompt Templates
|
|
3
|
+
*
|
|
4
|
+
* Adapted from src/services/ai/prompts.ts for server-side MCP usage.
|
|
5
|
+
* Contains the master generation prompt, humanizer, SEO metadata generator,
|
|
6
|
+
* and internal linking builder.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ROBUST_PROMPT_TEMPLATE = "\n(Act as an expert SEO content writer. Create a comprehensive, high-ranking blog post for the keyword: \"{{keyword}}\".\n\n\u26A0\uFE0F CRITICAL OUTPUT RULE: Return ONLY raw Markdown text. NEVER return JSON. NEVER wrap your response in { } braces or a code block.\n\nKEYWORD INSTRUCTIONS:\n1. Target Keyword: {{keyword}} (Use natural variations, do NOT overstuff).\n2. Secondary Keywords: Identify and naturally integrate 3-5 LSI/secondary keywords relevant to the topic to improve semantic reach.\n3. Slug: Use the exact target keyword as the slug, lowercased and hyphenated.\n4. **KEYWORD PLACEMENT (STRICT):**\n - The exact target keyword MUST appear in the first 25% of the article (intro or first section).\n - The exact target keyword MUST appear in at least one H2 header near the beginning of the article.\n\n{{template_instruction}}\n\nDATA & CONTEXT INTEGRITY:\nYou will be provided with \"Context\" or \"Research Data\" in the user prompt. You MUST prioritize this data for facts, statistics, and specific details. Do NOT simulate a web search. Use the provided real-world data to back your claims.\n\n{{title_instruction}}\n{{h1_instruction}}\n\nOUTPUT FORMAT (MANDATORY):\nYOU MUST RETURN RAW MARKDOWN TEXT ONLY. DO NOT RETURN JSON.\n- Start directly with the title using # (H1).\n- Use ## for main sections (H2).\n- Use ### for subsections (H3).\n- Use tables, lists, and bold text for readability.\n- NO JSON format. NO code blocks. NO { \"title\": } structures. Just raw markdown text.\n- At the very END of the article, add the meta description in this format:\n META_DESCRIPTION: [Your 155-char max meta description here]\n\nCONTENT SEPARATION (CRITICAL):\n- The article body must contain ONLY the article content itself.\n- DO NOT include any \"Meta title\", \"Slug\", \"Title Tag\", or metadata sections inside the article.\n- Meta titles, slugs, and meta descriptions are handled SEPARATELY by the system.\n- Your output = H1 title + article body + META_DESCRIPTION line at the end. Nothing else.\n\nREQUIREMENTS:\n1. Title & Meta: Title under 60 characters. Meta description 150-160 characters.\n2. Content Structure (INVERTED PYRAMID): Give the answer immediately. Surface answers first, details later. Remove fluff.\n3. Readability: Simple, accessible language. Paragraphs 2-3 sentences max. Frequent visual breaks.\n4. TL;DR: 3-4 bullet points (~75 words) that fully answer the user's query.\n5. Intro: ~50-100 words, keyword mentioned, direct answer visible.\n\n6. INTRO OPENER (Use Opener Seed: {{opener_seed}}):\n Strategy A \u2014 COLD STAT OPENER: Lead with a surprising number.\n Strategy B \u2014 CONTRARIAN CLAIM: Bold, slightly provocative statement.\n Strategy C \u2014 MINI-STORY: A single vivid sentence.\n Strategy D \u2014 DIRECT ANSWER FIRST: Answer the query in sentence one.\n Strategy E \u2014 QUESTION HOOK: One sharp question.\n Strategy F \u2014 TENSION/PROBLEM: Name the specific pain.\n Strategy G \u2014 QUOTE OR ANECDOTE: A real quote or 1-line anecdote.\n Strategy H \u2014 BEFORE/AFTER CONTRAST: Transformation in one sentence.\n\n7. Components: DEPTH & EXPANSION. Explain concepts in depth. Include at least one data table.\n {{internal_linking_instructions}}\n\n8. CRITICAL RULES:\n - THE CURRENT YEAR IS 2026.\n - NEVER use em-dashes.\n - Use clear headings (H1, H2, H3).\n - Include tables, lists, bold text for readability.\n - Mention specific brands, models, features, and pricing tiers.\n - Reference external sources with natural anchor text (NOT [1] bracket numbers).\n - NEVER fabricate URLs.\n\n9. FORBIDDEN AI TERMINOLOGY:\n Never use: delve, comprehensive, leverage, harness, seamlessly, robust, landscape, multifaceted, pivotal, realm, intricate, tapestry, synergy, ecosystem, embark, embrace, illuminate, paradigm, culmination, quest, pinnacle, beacon, foster, catalyze, meticulous, nuanced, transformative, holistic, resonate, underscore, underpins, streamline, incorporate, facilitate, encompass, exemplify, epitomize, and all related AI-sounding words.\n\n10. BANNED STRUCTURAL PATTERNS:\n - Three consecutive short \"You\" sentences.\n - Starting sentences with \"By\" + gerund.\n - \"it's not about X, it's about Y\" patterns.\n - Generic closers (\"And that's why X matters.\").\n - Motivational speech tone.\n";
|
|
9
|
+
export declare const SEO_GENERATOR_PROMPT = "You are an expert SEO strategist. Generate optimized metadata for a blog article.\n\nCRITICAL: Return ONLY valid JSON. No explanations, no markdown, no code blocks.\n\nFor the given topic/keyword, return this EXACT JSON structure:\n{\n \"title\": \"Article H1 heading\",\n \"titleTag\": \"SEO title for search results (50-60 chars max)\",\n \"slug\": \"url-friendly-slug\",\n \"mainKeyword\": \"primary target keyword phrase\",\n \"secondaryKeywords\": \"related, lsi, keywords\",\n \"metaDescription\": \"Action-oriented meta description (150-160 chars)\"\n}\n\nRules:\n- THE YEAR IS 2026\n- No forbidden AI words\n- Meta description must lead with a verb\n- Slug is keyword lowercased and hyphenated";
|
|
10
|
+
export declare const HUMANIZE_PROMPT = "\nYou are a senior human editor performing a FINAL anti-AI detection pass on a blog article.\nYour job is to rewrite any sentence or section that reads like AI-generated text, while preserving every fact, link, and piece of data.\n\nINPUT CONTENT:\n{{content}}\n\n=== KEY RULES ===\n1. Replace all banned AI words (delve, comprehensive, leverage, harness, etc.)\n2. Replace all banned phrases (\"in today's\", \"it's important to note\", etc.)\n3. Remove ALL em-dashes and replace with periods, commas, or semicolons\n4. Mix sentence lengths (short punchy + medium)\n5. No triplet patterns (3+ sentences starting with same word)\n6. No \"By + gerund\" sentence starters\n7. Use contractions (don't, it's, they're)\n8. Vary paragraph openings\n9. Preserve ALL links, data, formatting, and content depth\n10. Output must be at least as long as input\n\n=== OUTPUT ===\nReturn the FULL humanized article in Markdown. Nothing else.\n";
|
|
11
|
+
export declare function buildInternalLinkingPrompt(urls: string[], maxLinks: number): string;
|
|
12
|
+
export declare const RESEARCH_PROMPT = "You are a research assistant. Search the web for accurate, current information about the given topic.\n\nFocus on:\n1. Recent data, statistics, and trends (2025-2026)\n2. Expert opinions and quotes\n3. Specific product names, pricing, and features\n4. Competitor comparisons\n5. Common questions people ask about this topic\n\nReturn your findings as a structured research brief with citations. Include source URLs where available.";
|
|
13
|
+
export declare function buildGenerationPrompt(options: {
|
|
14
|
+
keyword: string;
|
|
15
|
+
wordCount?: number;
|
|
16
|
+
tone?: string;
|
|
17
|
+
templateInstruction?: string;
|
|
18
|
+
titleInstruction?: string;
|
|
19
|
+
h1Instruction?: string;
|
|
20
|
+
internalLinkUrls?: string[];
|
|
21
|
+
maxInternalLinks?: number;
|
|
22
|
+
knowledgeBaseContext?: string;
|
|
23
|
+
researchContext?: string;
|
|
24
|
+
ctaSnippets?: string[];
|
|
25
|
+
openerSeedIndex?: number;
|
|
26
|
+
}): {
|
|
27
|
+
systemPrompt: string;
|
|
28
|
+
userPrompt: string;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/ai/prompts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,sBAAsB,wvIA2ElC,CAAC;AAMF,eAAO,MAAM,oBAAoB,wsBAkBW,CAAC;AAM7C,eAAO,MAAM,eAAe,s6BAqB3B,CAAC;AAMF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4BnF;AAMD,eAAO,MAAM,eAAe,obAS6E,CAAC;AAQ1G,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAmC/C"}
|