@agentsean/mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tools.js ADDED
@@ -0,0 +1,351 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { aiRuns, findings, pages, sites } from "@agentsean/db";
3
+ import { listClusters, listKeywords, listRanks } from "@agentsean/keywords";
4
+ import { listClaims, sitePowerBrief, monthlyClicksForSite } from "@agentsean/measure";
5
+ import { AEO_REFUSALS, listInbound404s, listMentions } from "@agentsean/surfaces";
6
+ import { CAPABILITIES, DFS_RATES, freeEstimate, paidEstimate, keywordsDataTasks, } from "@agentsean/providers";
7
+ import { mcpResponse } from "./formatters.js";
8
+ import { formatMcpTable } from "./table.js";
9
+ export const MCP_TOOLS = [
10
+ {
11
+ name: "keyword_opportunities",
12
+ description: "Keyword opportunities from GSC demand, striking distance, and free expansion. Zero paid keys required.",
13
+ inputSchema: {
14
+ type: "object",
15
+ properties: { origin: { type: "string" } },
16
+ },
17
+ },
18
+ {
19
+ name: "keyword_clusters",
20
+ description: "Semantic-then-SERP keyword clusters (cosine ≈ 0.78, then ≥3 shared top-10 URLs when a licensed SERP is configured).",
21
+ inputSchema: {
22
+ type: "object",
23
+ properties: { origin: { type: "string" } },
24
+ },
25
+ },
26
+ {
27
+ name: "striking_distance",
28
+ description: "Queries in average position 8–20 from GSC. Default metric is clicks.",
29
+ inputSchema: {
30
+ type: "object",
31
+ properties: { origin: { type: "string" } },
32
+ },
33
+ },
34
+ {
35
+ name: "rank_snapshots",
36
+ description: "Weekly licensed rank snapshots. Empty unless a DataForSEO key is configured — Sean never scrapes Google.",
37
+ inputSchema: {
38
+ type: "object",
39
+ properties: { origin: { type: "string" } },
40
+ },
41
+ },
42
+ {
43
+ name: "estimate_provider_cost",
44
+ description: "Return the DataForSEO cost estimate for a capability *before* any call. Free stack is $0.",
45
+ inputSchema: {
46
+ type: "object",
47
+ properties: {
48
+ capability: {
49
+ type: "string",
50
+ enum: ["serp", "keywords", "backlinks", "volume"],
51
+ },
52
+ units: { type: "number" },
53
+ paid: { type: "boolean" },
54
+ },
55
+ required: ["capability"],
56
+ },
57
+ },
58
+ {
59
+ name: "list_findings",
60
+ description: "Open SEO findings for a site.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: { origin: { type: "string" } },
64
+ },
65
+ },
66
+ {
67
+ name: "list_claims",
68
+ description: "Every applied change with its evidence tier. Sean will not claim causation it cannot support.",
69
+ inputSchema: {
70
+ type: "object",
71
+ properties: { origin: { type: "string" } },
72
+ },
73
+ },
74
+ {
75
+ name: "estimate_mde",
76
+ description: "Minimum detectable effect at this site's traffic. Small sites are told most changes land in tier E.",
77
+ inputSchema: {
78
+ type: "object",
79
+ properties: { origin: { type: "string" } },
80
+ },
81
+ },
82
+ {
83
+ name: "ai_citation_share",
84
+ description: "AI citation share from the prompt panel and/or Bing Webmaster AI Performance CSV. Schema and llms.txt are not sold as AEO levers.",
85
+ inputSchema: { type: "object", properties: { origin: { type: "string" } } },
86
+ },
87
+ {
88
+ name: "brand_mentions",
89
+ description: "Unlinked brand mentions and inbound-404 recovery. Outreach send is T3.",
90
+ inputSchema: { type: "object", properties: { origin: { type: "string" } } },
91
+ },
92
+ ];
93
+ export async function callTool(ctx, name, args) {
94
+ switch (name) {
95
+ case "keyword_opportunities":
96
+ return keywordOpportunities(ctx, args);
97
+ case "keyword_clusters":
98
+ return keywordClustersTool(ctx, args);
99
+ case "striking_distance":
100
+ return strikingDistanceTool(ctx, args);
101
+ case "rank_snapshots":
102
+ return rankSnapshotsTool(ctx, args);
103
+ case "estimate_provider_cost":
104
+ return estimateCost(args);
105
+ case "list_findings":
106
+ return listFindingsTool(ctx, args);
107
+ case "list_claims":
108
+ return listClaimsTool(ctx, args);
109
+ case "estimate_mde":
110
+ return estimateMdeTool(ctx, args);
111
+ case "ai_citation_share":
112
+ return aiCitationShareTool(ctx, args);
113
+ case "brand_mentions":
114
+ return brandMentionsTool(ctx, args);
115
+ default:
116
+ return mcpResponse({
117
+ text: `Unknown tool ${name}`,
118
+ structuredContent: { error: "unknown_tool", name },
119
+ });
120
+ }
121
+ }
122
+ function siteOf(ctx, args) {
123
+ const origin = typeof args["origin"] === "string" ? args["origin"] : undefined;
124
+ if (origin)
125
+ return ctx.db.select().from(sites).where(eq(sites.origin, origin)).get() ?? null;
126
+ return ctx.db.select().from(sites).all()[0] ?? null;
127
+ }
128
+ function keywordOpportunities(ctx, args) {
129
+ const site = siteOf(ctx, args);
130
+ if (!site)
131
+ return mcpResponse({
132
+ text: "No site. Run sean audit first.",
133
+ structuredContent: { opportunities: [] },
134
+ });
135
+ const rows = listKeywords(ctx.db, site.id);
136
+ const text = formatMcpTable(rows, [
137
+ { header: "query", value: (r) => r.query },
138
+ { header: "source", value: (r) => r.source },
139
+ { header: "clicks", value: (r) => r.clicks },
140
+ { header: "position", value: (r) => r.position },
141
+ { header: "volume", value: (r) => r.volume },
142
+ ]);
143
+ return mcpResponse({
144
+ text: rows.length ? text : "No keyword opportunities stored. Run sean keywords.",
145
+ structuredContent: { origin: site.origin, opportunities: rows },
146
+ });
147
+ }
148
+ function keywordClustersTool(ctx, args) {
149
+ const site = siteOf(ctx, args);
150
+ if (!site)
151
+ return mcpResponse({ text: "No site.", structuredContent: { clusters: [] } });
152
+ const rows = listClusters(ctx.db, site.id);
153
+ const text = formatMcpTable(rows, [
154
+ { header: "label", value: (r) => r.label },
155
+ { header: "members", value: (r) => r.memberCount },
156
+ { header: "serp_confirmed", value: (r) => Boolean(r.serpConfirmed) },
157
+ ]);
158
+ return mcpResponse({
159
+ text: rows.length ? text : "No clusters stored. Run sean keywords.",
160
+ structuredContent: { origin: site.origin, clusters: rows },
161
+ });
162
+ }
163
+ function strikingDistanceTool(ctx, args) {
164
+ const site = siteOf(ctx, args);
165
+ if (!site)
166
+ return mcpResponse({
167
+ text: "No site.",
168
+ structuredContent: { strikingDistance: [] },
169
+ });
170
+ const rows = listKeywords(ctx.db, site.id).filter((r) => r.position !== null && r.position >= 8 && r.position <= 20);
171
+ const text = formatMcpTable(rows, [
172
+ { header: "query", value: (r) => r.query },
173
+ { header: "position", value: (r) => r.position },
174
+ { header: "clicks", value: (r) => r.clicks },
175
+ ]);
176
+ return mcpResponse({
177
+ text: rows.length ? text : "No striking-distance queries.",
178
+ structuredContent: {
179
+ origin: site.origin,
180
+ strikingDistance: rows,
181
+ metric: "clicks",
182
+ },
183
+ });
184
+ }
185
+ function rankSnapshotsTool(ctx, args) {
186
+ const site = siteOf(ctx, args);
187
+ if (!site)
188
+ return mcpResponse({ text: "No site.", structuredContent: { ranks: [] } });
189
+ const rows = listRanks(ctx.db, site.id);
190
+ const text = rows.length
191
+ ? formatMcpTable(rows, [
192
+ { header: "query", value: (r) => r.query },
193
+ { header: "position", value: (r) => r.position },
194
+ { header: "provider", value: (r) => r.provider },
195
+ { header: "estimated_usd", value: (r) => r.estimatedUsd },
196
+ ])
197
+ : "No licensed rank snapshots. Sean never scrapes Google. Add a DataForSEO key to upgrade in place.";
198
+ return mcpResponse({
199
+ text,
200
+ structuredContent: { origin: site.origin, ranks: rows },
201
+ });
202
+ }
203
+ function estimateCost(args) {
204
+ const capability = String(args["capability"] ?? "");
205
+ if (!CAPABILITIES.includes(capability)) {
206
+ return mcpResponse({
207
+ text: `Unknown capability ${capability}`,
208
+ structuredContent: { error: "unknown_capability" },
209
+ });
210
+ }
211
+ const units = typeof args["units"] === "number" ? args["units"] : 1;
212
+ const paid = args["paid"] === true;
213
+ const cap = capability;
214
+ const estimate = !paid
215
+ ? freeEstimate("gsc", cap, "free_stack", units)
216
+ : cap === "serp"
217
+ ? paidEstimate({
218
+ provider: "dataforseo",
219
+ capability: "serp",
220
+ operation: "organic_standard",
221
+ units,
222
+ unitUsd: DFS_RATES.serpPerKeyword,
223
+ notes: "SERP $0.60/1k standard queue",
224
+ })
225
+ : cap === "volume" || cap === "keywords"
226
+ ? paidEstimate({
227
+ provider: "dataforseo",
228
+ capability: cap,
229
+ operation: "keywords_data",
230
+ units: keywordsDataTasks(units),
231
+ unitUsd: DFS_RATES.keywordsDataPerTask,
232
+ })
233
+ : paidEstimate({
234
+ provider: "dataforseo",
235
+ capability: "backlinks",
236
+ operation: "summary",
237
+ units,
238
+ unitUsd: DFS_RATES.backlinksPerRequest,
239
+ });
240
+ return mcpResponse({
241
+ text: `${estimate.provider} ${estimate.capability}/${estimate.operation}: $${estimate.estimatedUsd.toFixed(4)} (${estimate.free ? "free" : "paid"})`,
242
+ structuredContent: { estimate },
243
+ meta: { creditsCharged: estimate.estimatedUsd },
244
+ });
245
+ }
246
+ function listFindingsTool(ctx, args) {
247
+ const site = siteOf(ctx, args);
248
+ if (!site)
249
+ return mcpResponse({ text: "No site.", structuredContent: { findings: [] } });
250
+ const rows = ctx.db.select().from(findings).where(eq(findings.siteId, site.id)).all();
251
+ const text = formatMcpTable(rows, [
252
+ { header: "rule", value: (r) => r.ruleId },
253
+ { header: "severity", value: (r) => r.severity },
254
+ { header: "title", value: (r) => r.title },
255
+ { header: "status", value: (r) => r.status },
256
+ ]);
257
+ return mcpResponse({
258
+ text: rows.length ? text : "No findings.",
259
+ structuredContent: { origin: site.origin, findings: rows },
260
+ });
261
+ }
262
+ function listClaimsTool(ctx, args) {
263
+ const site = siteOf(ctx, args);
264
+ if (!site)
265
+ return mcpResponse({ text: "No site.", structuredContent: { claims: [] } });
266
+ const rows = listClaims(ctx.db, site.id);
267
+ const text = formatMcpTable(rows, [
268
+ { header: "tier", value: (r) => r.evidenceTier },
269
+ { header: "causation", value: (r) => r.causationClaimed },
270
+ { header: "statement", value: (r) => r.statement },
271
+ ]);
272
+ return mcpResponse({
273
+ text: rows.length ? text : "No claims stored. Run sean measure.",
274
+ structuredContent: { origin: site.origin, claims: rows },
275
+ });
276
+ }
277
+ function estimateMdeTool(ctx, args) {
278
+ const site = siteOf(ctx, args);
279
+ if (!site)
280
+ return mcpResponse({ text: "No site.", structuredContent: { power: null } });
281
+ const monthly = monthlyClicksForSite(ctx.db, site.id);
282
+ const pageCount = ctx.db
283
+ .select()
284
+ .from(pages)
285
+ .where(eq(pages.siteId, site.id))
286
+ .all().length;
287
+ const power = sitePowerBrief({ monthlyClicks: monthly, pageCount });
288
+ return mcpResponse({
289
+ text: power.message,
290
+ structuredContent: { origin: site.origin, power },
291
+ });
292
+ }
293
+ function aiCitationShareTool(ctx, args) {
294
+ const site = siteOf(ctx, args);
295
+ if (!site)
296
+ return mcpResponse({
297
+ text: "No site. Run sean audit first.",
298
+ structuredContent: { citationShare: 0 },
299
+ });
300
+ const runs = ctx.db.select().from(aiRuns).where(eq(aiRuns.siteId, site.id)).all();
301
+ const latest = runs.toSorted((a, b) => b.ranAt.localeCompare(a.ranAt))[0];
302
+ if (!latest) {
303
+ return mcpResponse({
304
+ text: "No AI visibility run stored. Run sean visibility. Schema, content length, and llms.txt are not sold as AEO levers. Training crawlers ≠ citation crawlers.",
305
+ structuredContent: {
306
+ origin: site.origin,
307
+ citationShare: 0,
308
+ shareOfVoice: 0,
309
+ refusals: AEO_REFUSALS,
310
+ },
311
+ });
312
+ }
313
+ const pct = Math.round(latest.citationShare * 100);
314
+ return mcpResponse({
315
+ text: `AI citation share ${pct}% · share of voice ${Math.round(latest.shareOfVoice * 100)}% · ~$${latest.estimatedUsd.toFixed(2)}/run on ${latest.engine}. Schema/llms.txt/length are not AEO levers.`,
316
+ structuredContent: {
317
+ origin: site.origin,
318
+ citationShare: latest.citationShare,
319
+ shareOfVoice: latest.shareOfVoice,
320
+ estimatedUsd: latest.estimatedUsd,
321
+ engine: latest.engine,
322
+ ranAt: latest.ranAt,
323
+ refusals: AEO_REFUSALS,
324
+ },
325
+ });
326
+ }
327
+ function brandMentionsTool(ctx, args) {
328
+ const site = siteOf(ctx, args);
329
+ if (!site)
330
+ return mcpResponse({ text: "No site.", structuredContent: { mentions: [] } });
331
+ const rows = listMentions(ctx.db, site.id);
332
+ const broken = listInbound404s(ctx.db, site.id);
333
+ const text = rows.length
334
+ ? formatMcpTable(rows, [
335
+ { header: "url", value: (r) => r.url },
336
+ { header: "kind", value: (r) => r.kind },
337
+ { header: "linked", value: (r) => Boolean(r.linked) },
338
+ { header: "score", value: (r) => r.score },
339
+ ])
340
+ : "No mention opportunities stored. Run sean visibility. Outreach send is T3.";
341
+ return mcpResponse({
342
+ text,
343
+ structuredContent: {
344
+ origin: site.origin,
345
+ mentions: rows,
346
+ inbound404s: broken,
347
+ sendRequiresApproval: true,
348
+ },
349
+ });
350
+ }
351
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@agentsean/mcp",
3
+ "version": "1.0.0",
4
+ "license": "AGPL-3.0-only",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "engines": {
16
+ "node": ">=22.19.0"
17
+ },
18
+ "dependencies": {
19
+ "drizzle-orm": "0.45.2",
20
+ "@agentsean/keywords": "1.0.0",
21
+ "@agentsean/db": "1.0.0",
22
+ "@agentsean/measure": "1.0.0",
23
+ "@agentsean/providers": "1.0.0",
24
+ "@agentsean/surfaces": "1.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "~5.9.3",
28
+ "vitest": "^4.1.11"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/seziro-team/agentsean.git",
36
+ "directory": "packages/mcp"
37
+ },
38
+ "homepage": "https://github.com/seziro-team/agentsean#readme",
39
+ "bugs": {
40
+ "url": "https://github.com/seziro-team/agentsean/issues"
41
+ },
42
+ "author": "Seziro (https://seziro.com)",
43
+ "description": "Agent Sean — mcp module",
44
+ "keywords": [
45
+ "seo",
46
+ "agent",
47
+ "agentsean",
48
+ "seo-automation"
49
+ ],
50
+ "scripts": {
51
+ "build": "tsc -p tsconfig.json",
52
+ "typecheck": "tsc -p tsconfig.json --noEmit",
53
+ "test": "vitest run --config ../../vitest.config.ts"
54
+ }
55
+ }