@houtini/better-search-console 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/LICENSE +189 -0
- package/README.md +334 -0
- package/better-search-console.jpg +0 -0
- package/dist/core/DataRetention.d.ts +49 -0
- package/dist/core/DataRetention.d.ts.map +1 -0
- package/dist/core/DataRetention.js +165 -0
- package/dist/core/DataRetention.js.map +1 -0
- package/dist/core/DataSync.d.ts +24 -0
- package/dist/core/DataSync.d.ts.map +1 -0
- package/dist/core/DataSync.js +247 -0
- package/dist/core/DataSync.js.map +1 -0
- package/dist/core/Database.d.ts +29 -0
- package/dist/core/Database.d.ts.map +1 -0
- package/dist/core/Database.js +205 -0
- package/dist/core/Database.js.map +1 -0
- package/dist/core/GscClient.d.ts +23 -0
- package/dist/core/GscClient.d.ts.map +1 -0
- package/dist/core/GscClient.js +92 -0
- package/dist/core/GscClient.js.map +1 -0
- package/dist/core/SyncManager.d.ts +66 -0
- package/dist/core/SyncManager.d.ts.map +1 -0
- package/dist/core/SyncManager.js +368 -0
- package/dist/core/SyncManager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/overview/src/ui/overview.html +185 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +441 -0
- package/dist/server.js.map +1 -0
- package/dist/src/ui/dashboard.html +437 -0
- package/dist/sync-progress/src/ui/sync-progress.html +147 -0
- package/dist/tools/compare-periods.d.ts +3 -0
- package/dist/tools/compare-periods.d.ts.map +1 -0
- package/dist/tools/compare-periods.js +127 -0
- package/dist/tools/compare-periods.js.map +1 -0
- package/dist/tools/get-dashboard.d.ts +10 -0
- package/dist/tools/get-dashboard.d.ts.map +1 -0
- package/dist/tools/get-dashboard.js +310 -0
- package/dist/tools/get-dashboard.js.map +1 -0
- package/dist/tools/get-insights.d.ts +3 -0
- package/dist/tools/get-insights.d.ts.map +1 -0
- package/dist/tools/get-insights.js +509 -0
- package/dist/tools/get-insights.js.map +1 -0
- package/dist/tools/get-overview.d.ts +36 -0
- package/dist/tools/get-overview.d.ts.map +1 -0
- package/dist/tools/get-overview.js +111 -0
- package/dist/tools/get-overview.js.map +1 -0
- package/dist/tools/helpers.d.ts +67 -0
- package/dist/tools/helpers.d.ts.map +1 -0
- package/dist/tools/helpers.js +239 -0
- package/dist/tools/helpers.js.map +1 -0
- package/dist/tools/list-properties.d.ts +4 -0
- package/dist/tools/list-properties.d.ts.map +1 -0
- package/dist/tools/list-properties.js +35 -0
- package/dist/tools/list-properties.js.map +1 -0
- package/dist/tools/query-data.d.ts +12 -0
- package/dist/tools/query-data.d.ts.map +1 -0
- package/dist/tools/query-data.js +20 -0
- package/dist/tools/query-data.js.map +1 -0
- package/dist/tools/sync-data.d.ts +11 -0
- package/dist/tools/sync-data.d.ts.map +1 -0
- package/dist/tools/sync-data.js +62 -0
- package/dist/tools/sync-data.js.map +1 -0
- package/dist/types/index.d.ts +101 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +57 -0
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyBpE,wBAAgB,YAAY,IAAI;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAyjB9E"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, } from '@modelcontextprotocol/ext-apps/server';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import fs from 'node:fs/promises';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { GscClient } from './core/GscClient.js';
|
|
8
|
+
import { SyncManager } from './core/SyncManager.js';
|
|
9
|
+
import { DataRetention } from './core/DataRetention.js';
|
|
10
|
+
import { listProperties } from './tools/list-properties.js';
|
|
11
|
+
import { queryData } from './tools/query-data.js';
|
|
12
|
+
import { getInsights } from './tools/get-insights.js';
|
|
13
|
+
import { comparePeriods } from './tools/compare-periods.js';
|
|
14
|
+
import { getDashboardData } from './tools/get-dashboard.js';
|
|
15
|
+
import { getOverviewData } from './tools/get-overview.js';
|
|
16
|
+
import { asciiSparkline, formatCompact, formatChange } from './tools/helpers.js';
|
|
17
|
+
const SERVER_NAME = 'better-search-console';
|
|
18
|
+
const SERVER_VERSION = '0.3.0';
|
|
19
|
+
export function createServer() {
|
|
20
|
+
const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
21
|
+
if (!credentialsPath) {
|
|
22
|
+
throw new Error('GOOGLE_APPLICATION_CREDENTIALS environment variable is not set. See README for setup instructions.');
|
|
23
|
+
}
|
|
24
|
+
const gscClient = new GscClient(credentialsPath);
|
|
25
|
+
const syncManager = new SyncManager(gscClient);
|
|
26
|
+
const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
|
|
27
|
+
// ============================================================
|
|
28
|
+
// Resource URIs (declared upfront for tool registrations)
|
|
29
|
+
// ============================================================
|
|
30
|
+
const syncResourceUri = 'ui://sync/progress.html';
|
|
31
|
+
const dashboardResourceUri = 'ui://dashboard/main.html';
|
|
32
|
+
const overviewResourceUri = 'ui://dashboard/overview.html';
|
|
33
|
+
// ============================================================
|
|
34
|
+
// Tool 1: setup — FIRST-RUN EXPERIENCE
|
|
35
|
+
// ============================================================
|
|
36
|
+
// This is deliberately registered first so it appears at the top
|
|
37
|
+
// of the tool list. It orchestrates: list → sync all → overview.
|
|
38
|
+
registerAppTool(server, 'setup', {
|
|
39
|
+
title: 'Setup — First Run',
|
|
40
|
+
description: 'First time? Start here. Connects to Google Search Console, syncs all your properties (fetches up to 3 months of data), and shows a visual overview of every site. Takes a few minutes depending on how many properties you have. After setup, use get_overview to see all sites at a glance, or get_dashboard to drill into one.',
|
|
41
|
+
inputSchema: {},
|
|
42
|
+
_meta: { ui: { resourceUri: overviewResourceUri } },
|
|
43
|
+
}, async () => {
|
|
44
|
+
try {
|
|
45
|
+
// Step 1: List properties to show what we found
|
|
46
|
+
const properties = await listProperties(gscClient);
|
|
47
|
+
if (properties.length === 0) {
|
|
48
|
+
return {
|
|
49
|
+
content: [{
|
|
50
|
+
type: 'text',
|
|
51
|
+
text: 'No Google Search Console properties found. Check that the service account has been granted access to your GSC properties. See: https://search.google.com/search-console/users',
|
|
52
|
+
}],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const propertyNames = properties.map(p => p.siteUrl);
|
|
56
|
+
const alreadySynced = properties.filter(p => p.lastSyncedAt);
|
|
57
|
+
const needsSync = properties.filter(p => !p.lastSyncedAt);
|
|
58
|
+
// Step 2: Start syncing all properties
|
|
59
|
+
const jobId = await syncManager.startSyncAll({});
|
|
60
|
+
// Step 3: Wait for sync to complete (poll every 2s, timeout after 10 min)
|
|
61
|
+
const SETUP_TIMEOUT_MS = 10 * 60 * 1000;
|
|
62
|
+
const setupStart = Date.now();
|
|
63
|
+
let status = syncManager.getStatus(jobId);
|
|
64
|
+
while (status.status === 'queued' || status.status === 'syncing') {
|
|
65
|
+
if (Date.now() - setupStart > SETUP_TIMEOUT_MS) {
|
|
66
|
+
console.error('[BSC] Setup sync timed out after 10 minutes');
|
|
67
|
+
syncManager.cancelJob(jobId);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
71
|
+
status = syncManager.getStatus(jobId);
|
|
72
|
+
}
|
|
73
|
+
// Step 4: Generate the overview
|
|
74
|
+
const overviewData = await getOverviewData(gscClient, { dateRange: '3m', sortBy: 'clicks' });
|
|
75
|
+
// Build a helpful text summary
|
|
76
|
+
const lines = [
|
|
77
|
+
`Setup complete! Found ${properties.length} properties, synced ${status.completedProperties}.`,
|
|
78
|
+
'',
|
|
79
|
+
];
|
|
80
|
+
if (status.error) {
|
|
81
|
+
lines.push(`Note: ${status.error}`, '');
|
|
82
|
+
}
|
|
83
|
+
for (const p of overviewData.properties) {
|
|
84
|
+
const spark = asciiSparkline(p.sparkline.map((s) => s.clicks));
|
|
85
|
+
lines.push(`${p.domain}`, ` Clicks: ${formatCompact(p.current.clicks)} (${formatChange(p.changes.clicksPct)}) | Impressions: ${formatCompact(p.current.impressions)} (${formatChange(p.changes.impressionsPct)}) | CTR: ${(p.current.ctr * 100).toFixed(1)}% | Pos: ${p.current.avgPosition != null ? p.current.avgPosition.toFixed(1) : 'n/a'}`, ` Trend: ${spark}`, '');
|
|
86
|
+
}
|
|
87
|
+
lines.push('---', 'What would you like to do next?', '', '- **See a dashboard** for any property above (e.g. get_dashboard for your top site)', '- **Find opportunities** — queries ranking on page 2 that could reach page 1', '- **Compare periods** — see what changed between two date ranges', '- **Run a custom SQL query** against any property\'s data', '- **Get insights** — pre-built reports like top queries, growing/declining pages, device breakdown');
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
90
|
+
structuredContent: overviewData,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
96
|
+
isError: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// ============================================================
|
|
101
|
+
// Tool 2: get_overview — ALL SITES AT A GLANCE
|
|
102
|
+
// ============================================================
|
|
103
|
+
registerAppTool(server, 'get_overview', {
|
|
104
|
+
title: 'All Properties Overview',
|
|
105
|
+
description: 'See all your sites at a glance. Shows an interactive grid of every synced GSC property with clicks, impressions, CTR, position, percentage changes, and sparkline trends. Click any property card to open its full dashboard. If no data appears, run setup first to sync your properties.',
|
|
106
|
+
inputSchema: {
|
|
107
|
+
dateRange: z.string().optional().describe('Date range: "7d", "28d", "3m", "6m", "12m", "16m". Default: "28d".'),
|
|
108
|
+
sortBy: z.enum(['alpha', 'clicks', 'impressions', 'ctr', 'position']).optional().describe('Sort order for property cards. Default: "alpha".'),
|
|
109
|
+
search: z.string().optional().describe('Filter properties by domain name substring.'),
|
|
110
|
+
},
|
|
111
|
+
_meta: { ui: { resourceUri: overviewResourceUri } },
|
|
112
|
+
}, async (args) => {
|
|
113
|
+
try {
|
|
114
|
+
const data = await getOverviewData(gscClient, args);
|
|
115
|
+
if (data.properties.length === 0) {
|
|
116
|
+
return {
|
|
117
|
+
content: [{
|
|
118
|
+
type: 'text',
|
|
119
|
+
text: 'No synced properties found. Run setup to connect and sync your Google Search Console properties.',
|
|
120
|
+
}],
|
|
121
|
+
structuredContent: data,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const lines = [
|
|
125
|
+
`GSC Overview: ${data.properties.length} properties (${data.dateRange})`,
|
|
126
|
+
'',
|
|
127
|
+
];
|
|
128
|
+
for (const p of data.properties) {
|
|
129
|
+
const spark = asciiSparkline(p.sparkline.map((s) => s.clicks));
|
|
130
|
+
lines.push(`${p.domain}`, ` Clicks: ${formatCompact(p.current.clicks)} (${formatChange(p.changes.clicksPct)}) | Impressions: ${formatCompact(p.current.impressions)} (${formatChange(p.changes.impressionsPct)}) | CTR: ${(p.current.ctr * 100).toFixed(1)}% | Pos: ${p.current.avgPosition != null ? p.current.avgPosition.toFixed(1) : 'n/a'}`, ` Trend: ${spark}`, ` siteUrl: ${p.siteUrl}`, '');
|
|
131
|
+
}
|
|
132
|
+
lines.push('Use get_dashboard with a siteUrl above to drill into any property.');
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
135
|
+
structuredContent: data,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
return {
|
|
140
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
141
|
+
isError: true,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
// ============================================================
|
|
146
|
+
// Tool 3: get_dashboard — DEEP DIVE INTO ONE SITE
|
|
147
|
+
// ============================================================
|
|
148
|
+
registerAppTool(server, 'get_dashboard', {
|
|
149
|
+
title: 'Search Console Dashboard',
|
|
150
|
+
description: 'Drill into a single property. Shows an interactive dashboard with hero metrics, trend chart, top queries, top pages, country breakdown, ranking distribution, new/lost queries, and branded split. Use the siteUrl from get_overview results. Requires synced data — run setup first if needed.',
|
|
151
|
+
inputSchema: {
|
|
152
|
+
siteUrl: z.string().describe('GSC property URL, e.g. "sc-domain:example.com". Get this from the overview or list_properties.'),
|
|
153
|
+
dateRange: z.string().optional().describe('Date range: "7d", "28d", "3m", "6m", "12m", "16m", or named presets: "lw", "tm", "lm", "tq", "lq", "ytd". Default: "3m".'),
|
|
154
|
+
comparisonMode: z.enum(['previous_period', 'year_over_year', 'previous_month', 'disabled']).optional().describe('Comparison mode. Default: "previous_period".'),
|
|
155
|
+
matchWeekdays: z.boolean().optional().describe('Align comparison period to match weekday patterns. Default: false.'),
|
|
156
|
+
brandTerms: z.array(z.string()).optional().describe('Brand terms for branded/non-branded split (e.g. ["mysite", "my site"]).'),
|
|
157
|
+
},
|
|
158
|
+
_meta: { ui: { resourceUri: dashboardResourceUri } },
|
|
159
|
+
}, async (args) => {
|
|
160
|
+
try {
|
|
161
|
+
const data = getDashboardData(args);
|
|
162
|
+
return {
|
|
163
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
164
|
+
structuredContent: data,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
return {
|
|
169
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
170
|
+
isError: true,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
// ============================================================
|
|
175
|
+
// Tool 4: get_insights — PRE-BUILT REPORTS
|
|
176
|
+
// ============================================================
|
|
177
|
+
server.tool('get_insights', 'Run pre-built analytical queries against synced GSC data. Choose from 16 insight types: summary, top_queries, top_pages, growing_queries, declining_queries, growing_pages, declining_pages, opportunities (queries ranking 5-20 with high impressions — your quick wins), device_breakdown, country_breakdown, page_queries, query_pages, daily_trend, new_queries, lost_queries, branded_split. Requires synced data — run setup first if needed.', {
|
|
178
|
+
siteUrl: z.string().describe('GSC property URL.'),
|
|
179
|
+
insight: z.enum([
|
|
180
|
+
'summary', 'top_queries', 'top_pages',
|
|
181
|
+
'growing_queries', 'declining_queries',
|
|
182
|
+
'growing_pages', 'declining_pages',
|
|
183
|
+
'opportunities', 'device_breakdown', 'country_breakdown',
|
|
184
|
+
'page_queries', 'query_pages', 'daily_trend',
|
|
185
|
+
'new_queries', 'lost_queries', 'branded_split',
|
|
186
|
+
]).describe('Insight type to run.'),
|
|
187
|
+
dateRange: z.string().optional().describe('Date range: "7d", "28d", "3m", "6m", "12m", "16m". Default: "28d".'),
|
|
188
|
+
pageFilter: z.string().optional().describe('Filter by URL path (uses LIKE). e.g. "/blog/"'),
|
|
189
|
+
queryFilter: z.string().optional().describe('Filter by query text (uses LIKE).'),
|
|
190
|
+
device: z.string().optional().describe('Filter by device: DESKTOP, MOBILE, TABLET.'),
|
|
191
|
+
country: z.string().optional().describe('Filter by ISO country code.'),
|
|
192
|
+
brandTerms: z.array(z.string()).optional().describe('Brand terms for branded_split insight.'),
|
|
193
|
+
limit: z.number().optional().describe('Max rows returned. Default: 50.'),
|
|
194
|
+
minClicks: z.number().optional().describe('Minimum clicks threshold.'),
|
|
195
|
+
minImpressions: z.number().optional().describe('Minimum impressions threshold.'),
|
|
196
|
+
}, async (args) => {
|
|
197
|
+
try {
|
|
198
|
+
const result = getInsights(args);
|
|
199
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
// ============================================================
|
|
206
|
+
// Tool 5: compare_periods — DATE RANGE COMPARISON
|
|
207
|
+
// ============================================================
|
|
208
|
+
server.tool('compare_periods', 'Compare two arbitrary date ranges side-by-side across any dimension (query, page, device, country). Shows absolute and percentage changes. Useful for before/after analysis, seasonal comparisons, or measuring the impact of changes. Requires synced data — run setup first if needed.', {
|
|
209
|
+
siteUrl: z.string().describe('GSC property URL.'),
|
|
210
|
+
period1Start: z.string().describe('Period 1 start date (YYYY-MM-DD).'),
|
|
211
|
+
period1End: z.string().describe('Period 1 end date (YYYY-MM-DD).'),
|
|
212
|
+
period2Start: z.string().describe('Period 2 start date (YYYY-MM-DD).'),
|
|
213
|
+
period2End: z.string().describe('Period 2 end date (YYYY-MM-DD).'),
|
|
214
|
+
dimension: z.enum(['query', 'page', 'device', 'country']).optional().describe('Dimension to group by. Default: "query".'),
|
|
215
|
+
limit: z.number().optional().describe('Max rows. Default: 50.'),
|
|
216
|
+
pageFilter: z.string().optional().describe('Filter by URL path (uses LIKE).'),
|
|
217
|
+
}, async (args) => {
|
|
218
|
+
try {
|
|
219
|
+
const result = comparePeriods(args);
|
|
220
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// ============================================================
|
|
227
|
+
// Tool 6: query_gsc_data — CUSTOM SQL QUERIES
|
|
228
|
+
// ============================================================
|
|
229
|
+
server.tool('query_gsc_data', 'Run a read-only SQL query against a synced GSC property database. Supports any SELECT query. INSERT/UPDATE/DELETE/DROP/ALTER/CREATE are blocked. The table is "search_analytics" with columns: date, query, page, device, country, clicks, impressions, ctr, position. Requires synced data — run setup first if needed.', {
|
|
230
|
+
siteUrl: z.string().describe('GSC property URL.'),
|
|
231
|
+
sql: z.string().describe('SQL SELECT query to run against the search_analytics table.'),
|
|
232
|
+
params: z.array(z.any()).optional().describe('Optional parameterised query values.'),
|
|
233
|
+
}, async (args) => {
|
|
234
|
+
try {
|
|
235
|
+
const result = queryData(args);
|
|
236
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
// ============================================================
|
|
243
|
+
// Tool 7: list_properties — CHECK AVAILABLE PROPERTIES
|
|
244
|
+
// ============================================================
|
|
245
|
+
server.tool('list_properties', 'List all Google Search Console properties accessible via the service account, with permission level and local sync status. Usually not needed — setup handles this automatically.', {}, async () => {
|
|
246
|
+
try {
|
|
247
|
+
const properties = await listProperties(gscClient);
|
|
248
|
+
return { content: [{ type: 'text', text: JSON.stringify(properties, null, 2) }] };
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
// ============================================================
|
|
255
|
+
// Tool 8: sync_gsc_data — SYNC A SINGLE PROPERTY
|
|
256
|
+
// ============================================================
|
|
257
|
+
registerAppTool(server, 'sync_gsc_data', {
|
|
258
|
+
title: 'Sync Property Data',
|
|
259
|
+
description: 'Fetch Google Search Console search analytics data into a local SQLite database. Supports full pagination to capture ALL rows (no 1,000-row limit). Default date range is 3 months. Pass explicit startDate for longer ranges (up to 16 months). Returns immediately with a job ID — use check_sync_status to monitor progress.',
|
|
260
|
+
inputSchema: {
|
|
261
|
+
siteUrl: z.string().describe('GSC property URL, e.g. "sc-domain:example.com" or "https://www.example.com/"'),
|
|
262
|
+
startDate: z.string().optional().describe('Start date (YYYY-MM-DD). Defaults to 3 months ago.'),
|
|
263
|
+
endDate: z.string().optional().describe('End date (YYYY-MM-DD). Defaults to today.'),
|
|
264
|
+
dimensions: z.array(z.string()).optional().describe('Dimensions to fetch. Defaults to ["query","page","date","device","country"].'),
|
|
265
|
+
searchType: z.enum(['web', 'discover', 'googleNews', 'image', 'video']).optional().describe('Search type filter. Default: web.'),
|
|
266
|
+
},
|
|
267
|
+
_meta: { ui: { resourceUri: syncResourceUri } },
|
|
268
|
+
}, async (args) => {
|
|
269
|
+
try {
|
|
270
|
+
const jobId = syncManager.startSync(args);
|
|
271
|
+
const status = syncManager.getStatus(jobId);
|
|
272
|
+
return {
|
|
273
|
+
content: [{ type: 'text', text: JSON.stringify(status, null, 2) }],
|
|
274
|
+
structuredContent: status,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
return {
|
|
279
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
280
|
+
isError: true,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
// ============================================================
|
|
285
|
+
// Tool 9: sync_all_properties — SYNC EVERYTHING
|
|
286
|
+
// ============================================================
|
|
287
|
+
registerAppTool(server, 'sync_all_properties', {
|
|
288
|
+
title: 'Sync All Properties',
|
|
289
|
+
description: 'Sync search analytics data for ALL accessible GSC properties in one call. Syncs up to 2 properties in parallel for faster completion. Returns immediately with a job ID — use check_sync_status to monitor progress.',
|
|
290
|
+
inputSchema: {
|
|
291
|
+
startDate: z.string().optional().describe('Start date (YYYY-MM-DD). Defaults to 3 months ago (or incremental from last sync).'),
|
|
292
|
+
endDate: z.string().optional().describe('End date (YYYY-MM-DD). Defaults to today.'),
|
|
293
|
+
dimensions: z.array(z.string()).optional().describe('Dimensions to fetch. Defaults to ["query","page","date","device","country"].'),
|
|
294
|
+
searchType: z.enum(['web', 'discover', 'googleNews', 'image', 'video']).optional().describe('Search type filter. Default: web.'),
|
|
295
|
+
},
|
|
296
|
+
_meta: { ui: { resourceUri: syncResourceUri } },
|
|
297
|
+
}, async (args) => {
|
|
298
|
+
try {
|
|
299
|
+
const jobId = await syncManager.startSyncAll(args);
|
|
300
|
+
const status = syncManager.getStatus(jobId);
|
|
301
|
+
return {
|
|
302
|
+
content: [{ type: 'text', text: JSON.stringify(status, null, 2) }],
|
|
303
|
+
structuredContent: status,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
return {
|
|
308
|
+
content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }],
|
|
309
|
+
isError: true,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
// ============================================================
|
|
314
|
+
// Tool 10: check_sync_status — MONITOR SYNC PROGRESS
|
|
315
|
+
// ============================================================
|
|
316
|
+
server.tool('check_sync_status', 'Check the status of a background sync job. If no jobId provided, returns all active and recent jobs. Use after sync_gsc_data or sync_all_properties to monitor progress.', {
|
|
317
|
+
jobId: z.string().optional().describe('Job ID from sync_gsc_data or sync_all_properties. Omit to see all jobs.'),
|
|
318
|
+
}, async (args) => {
|
|
319
|
+
try {
|
|
320
|
+
const status = syncManager.getStatus(args.jobId);
|
|
321
|
+
return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] };
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
// ============================================================
|
|
328
|
+
// Tool 11: cancel_sync — STOP A SYNC
|
|
329
|
+
// ============================================================
|
|
330
|
+
server.tool('cancel_sync', 'Cancel a running sync job. The job will stop gracefully after completing the current API call.', {
|
|
331
|
+
jobId: z.string().describe('Job ID to cancel.'),
|
|
332
|
+
}, async (args) => {
|
|
333
|
+
try {
|
|
334
|
+
const cancelled = syncManager.cancelJob(args.jobId);
|
|
335
|
+
if (cancelled) {
|
|
336
|
+
const status = syncManager.getStatus(args.jobId);
|
|
337
|
+
return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] };
|
|
338
|
+
}
|
|
339
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: `Job ${args.jobId} not found or already finished.` }) }], isError: true };
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
// ============================================================
|
|
346
|
+
// Tool 12: prune_database — APPLY RETENTION POLICY
|
|
347
|
+
// ============================================================
|
|
348
|
+
server.tool('prune_database', 'Apply data retention policy to a synced property database. Removes low-value rows (zero clicks, low impressions) from older data while preserving all recent data and actionable historical data. Runs VACUUM afterwards to reclaim disk space. This runs automatically after each sync, but you can also trigger it manually. Use preview_prune first to see what would be deleted.', {
|
|
349
|
+
siteUrl: z.string().describe('GSC property URL to prune.'),
|
|
350
|
+
recentDays: z.number().optional().describe('Days of recent data to keep in full (default: 90).'),
|
|
351
|
+
targetMinImpressions: z.number().optional().describe('For target countries: min impressions to keep zero-click rows (default: 5).'),
|
|
352
|
+
preview: z.boolean().optional().describe('If true, show what would be deleted without actually deleting. Default: false.'),
|
|
353
|
+
}, async (args) => {
|
|
354
|
+
try {
|
|
355
|
+
const policy = {};
|
|
356
|
+
if (args.recentDays !== undefined)
|
|
357
|
+
policy.recentDays = args.recentDays;
|
|
358
|
+
if (args.targetMinImpressions !== undefined)
|
|
359
|
+
policy.targetMinImpressions = args.targetMinImpressions;
|
|
360
|
+
if (args.preview) {
|
|
361
|
+
const preview = DataRetention.preview(args.siteUrl, policy);
|
|
362
|
+
const lines = [
|
|
363
|
+
`Prune preview for ${args.siteUrl}:`,
|
|
364
|
+
` Total rows: ${preview.totalRows.toLocaleString()}`,
|
|
365
|
+
` Would delete: ${preview.wouldDelete.toLocaleString()} (${preview.reductionPct}%)`,
|
|
366
|
+
` Would keep: ${preview.wouldKeep.toLocaleString()}`,
|
|
367
|
+
'',
|
|
368
|
+
'Breakdown:',
|
|
369
|
+
` Target country low-value rows: ${preview.breakdown.targetLowValue.toLocaleString()}`,
|
|
370
|
+
` Non-target country zero-click rows: ${preview.breakdown.nonTargetZeroClick.toLocaleString()}`,
|
|
371
|
+
` Recent rows (protected): ${preview.breakdown.recentProtected.toLocaleString()}`,
|
|
372
|
+
];
|
|
373
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
374
|
+
}
|
|
375
|
+
const result = DataRetention.prune(args.siteUrl, policy);
|
|
376
|
+
const lines = [
|
|
377
|
+
`Prune completed for ${args.siteUrl}:`,
|
|
378
|
+
` Rows before: ${result.rowsBefore.toLocaleString()}`,
|
|
379
|
+
` Rows deleted: ${result.rowsDeleted.toLocaleString()}`,
|
|
380
|
+
` Rows after: ${result.rowsAfter.toLocaleString()}`,
|
|
381
|
+
` DB size: ${(result.dbSizeBefore / 1024 / 1024).toFixed(0)} MB -> ${(result.dbSizeAfter / 1024 / 1024).toFixed(0)} MB`,
|
|
382
|
+
` Space saved: ${((result.dbSizeBefore - result.dbSizeAfter) / 1024 / 1024).toFixed(0)} MB`,
|
|
383
|
+
` Duration: ${(result.durationMs / 1000).toFixed(1)}s`,
|
|
384
|
+
result.vacuumed ? ' VACUUM: completed' : ' VACUUM: skipped (no changes)',
|
|
385
|
+
];
|
|
386
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: error.message }) }], isError: true };
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
// ============================================================
|
|
393
|
+
// Resources — HTML UIs served to ext-apps iframes
|
|
394
|
+
// ============================================================
|
|
395
|
+
// Dashboard UI Resource
|
|
396
|
+
registerAppResource(server, 'Dashboard View', dashboardResourceUri, {}, async () => {
|
|
397
|
+
const htmlPath = path.join(path.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/, '$1'), 'src', 'ui', 'dashboard.html');
|
|
398
|
+
const html = await fs.readFile(htmlPath, 'utf-8');
|
|
399
|
+
return {
|
|
400
|
+
contents: [{
|
|
401
|
+
uri: dashboardResourceUri,
|
|
402
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
403
|
+
text: html,
|
|
404
|
+
}],
|
|
405
|
+
};
|
|
406
|
+
});
|
|
407
|
+
// Overview UI Resource
|
|
408
|
+
registerAppResource(server, 'Overview Grid', overviewResourceUri, {}, async () => {
|
|
409
|
+
const htmlPath = path.join(path.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/, '$1'), 'overview', 'src', 'ui', 'overview.html');
|
|
410
|
+
const html = await fs.readFile(htmlPath, 'utf-8');
|
|
411
|
+
return {
|
|
412
|
+
contents: [{
|
|
413
|
+
uri: overviewResourceUri,
|
|
414
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
415
|
+
text: html,
|
|
416
|
+
}],
|
|
417
|
+
};
|
|
418
|
+
});
|
|
419
|
+
// Sync Progress UI Resource
|
|
420
|
+
registerAppResource(server, 'Sync Progress', syncResourceUri, {}, async () => {
|
|
421
|
+
const htmlPath = path.join(path.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/, '$1'), 'sync-progress', 'src', 'ui', 'sync-progress.html');
|
|
422
|
+
const html = await fs.readFile(htmlPath, 'utf-8');
|
|
423
|
+
return {
|
|
424
|
+
contents: [{
|
|
425
|
+
uri: syncResourceUri,
|
|
426
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
427
|
+
text: html,
|
|
428
|
+
}],
|
|
429
|
+
};
|
|
430
|
+
});
|
|
431
|
+
// ============================================================
|
|
432
|
+
// Server startup
|
|
433
|
+
// ============================================================
|
|
434
|
+
const run = async () => {
|
|
435
|
+
const transport = new StdioServerTransport();
|
|
436
|
+
await server.connect(transport);
|
|
437
|
+
console.error(`${SERVER_NAME} v${SERVER_VERSION} running on stdio`);
|
|
438
|
+
};
|
|
439
|
+
return { server, run };
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|