@meertrack/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/LICENSE +21 -0
- package/README.md +313 -0
- package/dist/auth.d.ts +75 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +109 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +84 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +178 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +68 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +48 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +46 -0
- package/dist/logger.js.map +1 -0
- package/dist/prompts/competitor_deep_dive.d.ts +5 -0
- package/dist/prompts/competitor_deep_dive.d.ts.map +1 -0
- package/dist/prompts/competitor_deep_dive.js +48 -0
- package/dist/prompts/competitor_deep_dive.js.map +1 -0
- package/dist/prompts/index.d.ts +13 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +20 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/weekly_recap.d.ts +5 -0
- package/dist/prompts/weekly_recap.d.ts.map +1 -0
- package/dist/prompts/weekly_recap.js +28 -0
- package/dist/prompts/weekly_recap.js.map +1 -0
- package/dist/prompts/whats_new.d.ts +5 -0
- package/dist/prompts/whats_new.d.ts.map +1 -0
- package/dist/prompts/whats_new.js +46 -0
- package/dist/prompts/whats_new.js.map +1 -0
- package/dist/server.d.ts +34 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +43 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/get_activity_item.d.ts +6 -0
- package/dist/tools/get_activity_item.d.ts.map +1 -0
- package/dist/tools/get_activity_item.js +33 -0
- package/dist/tools/get_activity_item.js.map +1 -0
- package/dist/tools/get_competitor.d.ts +6 -0
- package/dist/tools/get_competitor.d.ts.map +1 -0
- package/dist/tools/get_competitor.js +37 -0
- package/dist/tools/get_competitor.js.map +1 -0
- package/dist/tools/get_digest.d.ts +6 -0
- package/dist/tools/get_digest.d.ts.map +1 -0
- package/dist/tools/get_digest.js +33 -0
- package/dist/tools/get_digest.js.map +1 -0
- package/dist/tools/index.d.ts +20 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +36 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list_activities.d.ts +6 -0
- package/dist/tools/list_activities.d.ts.map +1 -0
- package/dist/tools/list_activities.js +87 -0
- package/dist/tools/list_activities.js.map +1 -0
- package/dist/tools/list_competitors.d.ts +6 -0
- package/dist/tools/list_competitors.d.ts.map +1 -0
- package/dist/tools/list_competitors.js +58 -0
- package/dist/tools/list_competitors.js.map +1 -0
- package/dist/tools/list_digests.d.ts +6 -0
- package/dist/tools/list_digests.d.ts.map +1 -0
- package/dist/tools/list_digests.js +63 -0
- package/dist/tools/list_digests.js.map +1 -0
- package/dist/tools/list_latest_digests.d.ts +6 -0
- package/dist/tools/list_latest_digests.d.ts.map +1 -0
- package/dist/tools/list_latest_digests.js +30 -0
- package/dist/tools/list_latest_digests.js.map +1 -0
- package/dist/tools/whoami.d.ts +6 -0
- package/dist/tools/whoami.d.ts.map +1 -0
- package/dist/tools/whoami.js +30 -0
- package/dist/tools/whoami.js.map +1 -0
- package/dist/transports/http.d.ts +58 -0
- package/dist/transports/http.d.ts.map +1 -0
- package/dist/transports/http.js +179 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/stdio.d.ts +12 -0
- package/dist/transports/stdio.d.ts.map +1 -0
- package/dist/transports/stdio.js +35 -0
- package/dist/transports/stdio.js.map +1 -0
- package/dist/types.d.ts +6204 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +359 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +68 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { VERSION } from "./version.js";
|
|
2
|
+
export const DEFAULT_BASE_URL = "https://api.meertrack.com/v1";
|
|
3
|
+
/** Resolve the upstream base URL, honoring `MEERTRACK_API_BASE_URL` for staging/local. */
|
|
4
|
+
export function resolveBaseUrl(override) {
|
|
5
|
+
const raw = override ?? process.env["MEERTRACK_API_BASE_URL"] ?? DEFAULT_BASE_URL;
|
|
6
|
+
return raw.replace(/\/+$/, "");
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Typed error thrown for every non-2xx upstream response. `code` reflects the
|
|
10
|
+
* upstream error envelope's `error.code` when present, else a generic fallback
|
|
11
|
+
* (`http_<status>`, `transport_error`, `invalid_response`).
|
|
12
|
+
*/
|
|
13
|
+
export class MeertrackApiError extends Error {
|
|
14
|
+
status;
|
|
15
|
+
code;
|
|
16
|
+
rateLimitReset;
|
|
17
|
+
constructor(params) {
|
|
18
|
+
super(params.message);
|
|
19
|
+
this.name = "MeertrackApiError";
|
|
20
|
+
this.status = params.status;
|
|
21
|
+
this.code = params.code;
|
|
22
|
+
if (params.rateLimitReset !== undefined) {
|
|
23
|
+
this.rateLimitReset = params.rateLimitReset;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Thin typed wrapper over `api.meertrack.com/v1`. Each method is a 1:1 shadow
|
|
29
|
+
* of its endpoint. No retry/backoff in v1 — a 429 throws with the reset
|
|
30
|
+
* epoch and the caller (the MCP tool layer) decides what to tell the agent.
|
|
31
|
+
*/
|
|
32
|
+
export class MeertrackClient {
|
|
33
|
+
baseUrl;
|
|
34
|
+
apiKey;
|
|
35
|
+
fetchImpl;
|
|
36
|
+
userAgent;
|
|
37
|
+
onUpstreamResponse;
|
|
38
|
+
constructor(opts) {
|
|
39
|
+
this.baseUrl = resolveBaseUrl(opts.baseUrl);
|
|
40
|
+
this.apiKey = opts.apiKey;
|
|
41
|
+
this.fetchImpl = opts.fetchImpl ?? fetch;
|
|
42
|
+
this.userAgent = opts.userAgent ?? `meertrack-mcp/${VERSION}`;
|
|
43
|
+
if (opts.onUpstreamResponse) {
|
|
44
|
+
this.onUpstreamResponse = opts.onUpstreamResponse;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
me() {
|
|
48
|
+
return this.request("GET", "/me");
|
|
49
|
+
}
|
|
50
|
+
listCompetitors(params = {}) {
|
|
51
|
+
const query = new URLSearchParams();
|
|
52
|
+
if (params.active !== undefined)
|
|
53
|
+
query.set("active", params.active ? "true" : "false");
|
|
54
|
+
if (params.ids && params.ids.length > 0)
|
|
55
|
+
query.set("id", params.ids.join(","));
|
|
56
|
+
if (params.expand)
|
|
57
|
+
query.set("expand", params.expand);
|
|
58
|
+
return this.request("GET", "/competitors", query);
|
|
59
|
+
}
|
|
60
|
+
getCompetitor(id) {
|
|
61
|
+
return this.request("GET", `/competitors/${encodeURIComponent(id)}`);
|
|
62
|
+
}
|
|
63
|
+
listActivity(params = {}) {
|
|
64
|
+
const query = new URLSearchParams();
|
|
65
|
+
if (params.competitor_ids && params.competitor_ids.length > 0)
|
|
66
|
+
query.set("competitor_id", params.competitor_ids.join(","));
|
|
67
|
+
if (params.sections && params.sections.length > 0)
|
|
68
|
+
query.set("section", params.sections.join(","));
|
|
69
|
+
if (params.change_types && params.change_types.length > 0)
|
|
70
|
+
query.set("change_type", params.change_types.join(","));
|
|
71
|
+
if (params.from)
|
|
72
|
+
query.set("from", params.from);
|
|
73
|
+
if (params.to)
|
|
74
|
+
query.set("to", params.to);
|
|
75
|
+
if (params.limit !== undefined)
|
|
76
|
+
query.set("limit", String(params.limit));
|
|
77
|
+
if (params.cursor)
|
|
78
|
+
query.set("cursor", params.cursor);
|
|
79
|
+
return this.request("GET", "/activity", query);
|
|
80
|
+
}
|
|
81
|
+
getActivityItem(rowUuid) {
|
|
82
|
+
return this.request("GET", `/activity/${encodeURIComponent(rowUuid)}`);
|
|
83
|
+
}
|
|
84
|
+
listDigests(params = {}) {
|
|
85
|
+
const query = new URLSearchParams();
|
|
86
|
+
if (params.competitor_id && params.competitor_id.length > 0)
|
|
87
|
+
query.set("competitor_id", params.competitor_id.join(","));
|
|
88
|
+
if (params.from)
|
|
89
|
+
query.set("from", params.from);
|
|
90
|
+
if (params.to)
|
|
91
|
+
query.set("to", params.to);
|
|
92
|
+
if (params.limit !== undefined)
|
|
93
|
+
query.set("limit", String(params.limit));
|
|
94
|
+
if (params.cursor)
|
|
95
|
+
query.set("cursor", params.cursor);
|
|
96
|
+
return this.request("GET", "/digests", query);
|
|
97
|
+
}
|
|
98
|
+
listLatestDigests() {
|
|
99
|
+
return this.request("GET", "/digests/latest");
|
|
100
|
+
}
|
|
101
|
+
getDigest(id) {
|
|
102
|
+
return this.request("GET", `/digests/${encodeURIComponent(id)}`);
|
|
103
|
+
}
|
|
104
|
+
async request(method, path, query) {
|
|
105
|
+
const qs = query && query.toString().length > 0 ? `?${query.toString()}` : "";
|
|
106
|
+
const url = `${this.baseUrl}${path}${qs}`;
|
|
107
|
+
let response;
|
|
108
|
+
try {
|
|
109
|
+
response = await this.fetchImpl(url, {
|
|
110
|
+
method,
|
|
111
|
+
headers: {
|
|
112
|
+
authorization: `Bearer ${this.apiKey}`,
|
|
113
|
+
accept: "application/json",
|
|
114
|
+
"user-agent": this.userAgent,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch (cause) {
|
|
119
|
+
throw new MeertrackApiError({
|
|
120
|
+
status: 0,
|
|
121
|
+
code: "transport_error",
|
|
122
|
+
message: cause instanceof Error
|
|
123
|
+
? `Network error calling Meertrack: ${cause.message}`
|
|
124
|
+
: "Network error calling Meertrack",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (this.onUpstreamResponse) {
|
|
128
|
+
this.onUpstreamResponse({
|
|
129
|
+
status: response.status,
|
|
130
|
+
requestId: response.headers.get("x-request-id"),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
throw await toApiError(response);
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
return (await response.json());
|
|
138
|
+
}
|
|
139
|
+
catch (cause) {
|
|
140
|
+
throw new MeertrackApiError({
|
|
141
|
+
status: response.status,
|
|
142
|
+
code: "invalid_response",
|
|
143
|
+
message: cause instanceof Error
|
|
144
|
+
? `Malformed JSON from Meertrack: ${cause.message}`
|
|
145
|
+
: "Malformed JSON from Meertrack",
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/** Parse an upstream non-2xx into a `MeertrackApiError`. Exported for tests. */
|
|
151
|
+
export async function toApiError(response) {
|
|
152
|
+
const resetHeader = response.headers.get("x-ratelimit-reset");
|
|
153
|
+
const rateLimitReset = resetHeader && Number.isFinite(Number(resetHeader)) ? Number(resetHeader) : undefined;
|
|
154
|
+
let code = `http_${response.status}`;
|
|
155
|
+
let message = response.statusText || `Upstream HTTP ${response.status}`;
|
|
156
|
+
try {
|
|
157
|
+
const body = (await response.json());
|
|
158
|
+
if (body && typeof body === "object" && body.error) {
|
|
159
|
+
if (typeof body.error.code === "string" && body.error.code.length > 0) {
|
|
160
|
+
code = body.error.code;
|
|
161
|
+
}
|
|
162
|
+
if (typeof body.error.message === "string" && body.error.message.length > 0) {
|
|
163
|
+
message = body.error.message;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Upstream returned non-JSON (e.g. a Fly platform error page); keep the
|
|
169
|
+
// HTTP-derived fallback code/message. Never propagate the parse error.
|
|
170
|
+
}
|
|
171
|
+
return new MeertrackApiError({
|
|
172
|
+
status: response.status,
|
|
173
|
+
code,
|
|
174
|
+
message,
|
|
175
|
+
...(rateLimitReset !== undefined ? { rateLimitReset } : {}),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps upstream `MeertrackApiError`s into MCP tool-call results per spec
|
|
3
|
+
* §server/tools (isError semantics): upstream REST failures are **tool
|
|
4
|
+
* execution errors**, not protocol errors — the LLM needs to read them and
|
|
5
|
+
* self-correct. They go back as `{ content: [{ type: "text", text }], isError: true }`.
|
|
6
|
+
*
|
|
7
|
+
* Malformed MCP requests (unknown tool, invalid params) are handled by the
|
|
8
|
+
* SDK as JSON-RPC protocol errors (-32601 / -32602) — those never hit this
|
|
9
|
+
* module.
|
|
10
|
+
*
|
|
11
|
+
* Never attach `structuredContent` on `isError: true`: when a tool declares
|
|
12
|
+
* an `outputSchema`, the spec requires `structuredContent` to conform, and
|
|
13
|
+
* error envelopes (e.g. `{ rate_limit_reset }`) don't conform to e.g.
|
|
14
|
+
* `ActivityListResponse`.
|
|
15
|
+
*/
|
|
16
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Narrowed `CallToolResult` for the error branch. `isError: true` per spec,
|
|
19
|
+
* text-only `content`, and no `structuredContent` (the outputSchema doesn't
|
|
20
|
+
* cover error shapes).
|
|
21
|
+
*/
|
|
22
|
+
export type ToolErrorResult = CallToolResult & {
|
|
23
|
+
isError: true;
|
|
24
|
+
};
|
|
25
|
+
/** Map any error thrown inside a tool handler to an MCP tool-error result. */
|
|
26
|
+
export declare function toToolError(err: unknown): ToolErrorResult;
|
|
27
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAIzE;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC;AAEjE,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,CAUzD"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps upstream `MeertrackApiError`s into MCP tool-call results per spec
|
|
3
|
+
* §server/tools (isError semantics): upstream REST failures are **tool
|
|
4
|
+
* execution errors**, not protocol errors — the LLM needs to read them and
|
|
5
|
+
* self-correct. They go back as `{ content: [{ type: "text", text }], isError: true }`.
|
|
6
|
+
*
|
|
7
|
+
* Malformed MCP requests (unknown tool, invalid params) are handled by the
|
|
8
|
+
* SDK as JSON-RPC protocol errors (-32601 / -32602) — those never hit this
|
|
9
|
+
* module.
|
|
10
|
+
*
|
|
11
|
+
* Never attach `structuredContent` on `isError: true`: when a tool declares
|
|
12
|
+
* an `outputSchema`, the spec requires `structuredContent` to conform, and
|
|
13
|
+
* error envelopes (e.g. `{ rate_limit_reset }`) don't conform to e.g.
|
|
14
|
+
* `ActivityListResponse`.
|
|
15
|
+
*/
|
|
16
|
+
import { MeertrackApiError } from "./client.js";
|
|
17
|
+
import { redactApiKeys } from "./auth.js";
|
|
18
|
+
/** Map any error thrown inside a tool handler to an MCP tool-error result. */
|
|
19
|
+
export function toToolError(err) {
|
|
20
|
+
if (err instanceof MeertrackApiError) {
|
|
21
|
+
return formatApiError(err);
|
|
22
|
+
}
|
|
23
|
+
// Defensive: a tool handler threw something that wasn't a MeertrackApiError.
|
|
24
|
+
// Don't leak stack traces to the agent — keep the message short and
|
|
25
|
+
// redacted, then return a safe-to-retry-ish generic error.
|
|
26
|
+
const message = err instanceof Error ? err.message : typeof err === "string" ? err : "Unknown error";
|
|
27
|
+
return errorResult(`Unexpected error: ${redactApiKeys(message)}`);
|
|
28
|
+
}
|
|
29
|
+
function formatApiError(err) {
|
|
30
|
+
const upstream = redactApiKeys(err.message);
|
|
31
|
+
if (err.status === 401) {
|
|
32
|
+
return errorResult("Invalid or revoked Meertrack API key. Mint a new one at Settings → API Keys.");
|
|
33
|
+
}
|
|
34
|
+
if (err.status === 403) {
|
|
35
|
+
// `competitor_inactive` / `forbidden_competitor` messages from upstream
|
|
36
|
+
// are already actionable ("Competitor \"x\" is deactivated. Reactivate…"),
|
|
37
|
+
// so surface them verbatim.
|
|
38
|
+
return errorResult(upstream);
|
|
39
|
+
}
|
|
40
|
+
if (err.status === 404) {
|
|
41
|
+
return errorResult("No such row in this workspace.");
|
|
42
|
+
}
|
|
43
|
+
if (err.status === 429) {
|
|
44
|
+
// Per the OpenAPI contract: trust X-RateLimit-Reset, ignore Remaining.
|
|
45
|
+
// Emit the reset in both human-readable ISO and raw epoch so the agent
|
|
46
|
+
// can parse either form.
|
|
47
|
+
const reset = err.rateLimitReset;
|
|
48
|
+
if (typeof reset === "number" && Number.isFinite(reset)) {
|
|
49
|
+
const iso = new Date(reset * 1000).toISOString();
|
|
50
|
+
return errorResult(`${upstream} Retry after ${iso} (reset=${reset}). Trust X-RateLimit-Reset; do not retry sooner.`);
|
|
51
|
+
}
|
|
52
|
+
return errorResult(`${upstream} Rate limit hit but no reset timestamp was provided; back off and retry after a minute.`);
|
|
53
|
+
}
|
|
54
|
+
if (err.status >= 500 || err.status === 0) {
|
|
55
|
+
// 0 = transport error (DNS / TCP / TLS). Same surface as 5xx for the agent.
|
|
56
|
+
return errorResult("Upstream error; safe to retry.");
|
|
57
|
+
}
|
|
58
|
+
// 400 / 422 / other 4xx — not specifically mapped. Pass the upstream
|
|
59
|
+
// message through so the agent sees what it got wrong.
|
|
60
|
+
return errorResult(`${upstream} (code=${err.code})`);
|
|
61
|
+
}
|
|
62
|
+
function errorResult(text) {
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: "text", text }],
|
|
65
|
+
isError: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAS1C,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,iBAAiB,EAAE,CAAC;QACrC,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,6EAA6E;IAC7E,oEAAoE;IACpE,2DAA2D;IAC3D,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC;IACvF,OAAO,WAAW,CAAC,qBAAqB,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,cAAc,CAAC,GAAsB;IAC5C,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAE5C,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,WAAW,CAChB,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,wEAAwE;QACxE,2EAA2E;QAC3E,4BAA4B;QAC5B,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,WAAW,CAAC,gCAAgC,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,uEAAuE;QACvE,uEAAuE;QACvE,yBAAyB;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,cAAc,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACjD,OAAO,WAAW,CAChB,GAAG,QAAQ,gBAAgB,GAAG,WAAW,KAAK,kDAAkD,CACjG,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,CAChB,GAAG,QAAQ,yFAAyF,CACrG,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,4EAA4E;QAC5E,OAAO,WAAW,CAAC,gCAAgC,CAAC,CAAC;IACvD,CAAC;IAED,qEAAqE;IACrE,uDAAuD;IACvD,OAAO,WAAW,CAAC,GAAG,QAAQ,UAAU,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entry point. Routes to stdio or HTTP based on argv/env:
|
|
4
|
+
*
|
|
5
|
+
* meertrack-mcp → stdio (default)
|
|
6
|
+
* meertrack-mcp --http → HTTP (Streamable)
|
|
7
|
+
* PORT=8080 meertrack-mcp → HTTP
|
|
8
|
+
*
|
|
9
|
+
* stdio mode resolves `MEERTRACK_API_KEY` once at startup.
|
|
10
|
+
* HTTP mode resolves bearers per request from the `Authorization` header.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Entry point. Routes to stdio or HTTP based on argv/env:
|
|
4
|
+
*
|
|
5
|
+
* meertrack-mcp → stdio (default)
|
|
6
|
+
* meertrack-mcp --http → HTTP (Streamable)
|
|
7
|
+
* PORT=8080 meertrack-mcp → HTTP
|
|
8
|
+
*
|
|
9
|
+
* stdio mode resolves `MEERTRACK_API_KEY` once at startup.
|
|
10
|
+
* HTTP mode resolves bearers per request from the `Authorization` header.
|
|
11
|
+
*/
|
|
12
|
+
import { resolveEnvApiKey } from "./auth.js";
|
|
13
|
+
import { runStdio } from "./transports/stdio.js";
|
|
14
|
+
import { createHttpApp, PRM_PATH, defaultProtectedResourceMetadataUrl, } from "./transports/http.js";
|
|
15
|
+
const DEFAULT_ALLOWED_ORIGINS = [
|
|
16
|
+
"https://claude.ai",
|
|
17
|
+
"https://claude.com",
|
|
18
|
+
"https://cursor.sh",
|
|
19
|
+
];
|
|
20
|
+
async function main() {
|
|
21
|
+
const useHttp = process.argv.includes("--http") || process.env["PORT"] !== undefined;
|
|
22
|
+
if (useHttp) {
|
|
23
|
+
await startHttp();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
await startStdio();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function startStdio() {
|
|
30
|
+
// Fail fast with a clear message if the env var is missing or malformed.
|
|
31
|
+
let apiKey;
|
|
32
|
+
try {
|
|
33
|
+
apiKey = resolveEnvApiKey();
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
37
|
+
process.stderr.write(`[meertrack-mcp] ${message}\n`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
await runStdio({ apiKey });
|
|
41
|
+
}
|
|
42
|
+
async function startHttp() {
|
|
43
|
+
// Dynamic import so tests that load `./transports/http` never require
|
|
44
|
+
// `@hono/node-server` to be present.
|
|
45
|
+
const { serve } = await import("@hono/node-server");
|
|
46
|
+
const port = Number(process.env["PORT"] ?? "3000");
|
|
47
|
+
const allowedOrigins = parseAllowedOrigins(process.env["MEERTRACK_MCP_ALLOWED_ORIGINS"] ?? DEFAULT_ALLOWED_ORIGINS.join(","));
|
|
48
|
+
// Fly.io sets `FLY_APP_NAME`; on that platform the instance must bind to
|
|
49
|
+
// 0.0.0.0 so the proxy can route traffic in. Local development binds to
|
|
50
|
+
// 127.0.0.1 per MCP spec §transports (DNS rebinding protection).
|
|
51
|
+
const onFly = Boolean(process.env["FLY_APP_NAME"]);
|
|
52
|
+
const hostname = onFly ? "0.0.0.0" : "127.0.0.1";
|
|
53
|
+
const prmUrl = process.env["MEERTRACK_MCP_PRM_URL"] ??
|
|
54
|
+
defaultProtectedResourceMetadataUrl(process.env["MEERTRACK_MCP_PUBLIC_HOST"] ?? `${hostname}:${port}`, onFly ? "https" : "http");
|
|
55
|
+
const baseUrl = process.env["MEERTRACK_API_BASE_URL"];
|
|
56
|
+
const app = createHttpApp({
|
|
57
|
+
allowedOrigins,
|
|
58
|
+
protectedResourceMetadataUrl: prmUrl,
|
|
59
|
+
...(baseUrl !== undefined ? { baseUrl } : {}),
|
|
60
|
+
});
|
|
61
|
+
serve({ fetch: app.fetch, port, hostname }, (info) => {
|
|
62
|
+
process.stderr.write(`[meertrack-mcp] http listening on http://${info.address}:${info.port} (PRM: ${prmUrl}, origins: ${allowedOrigins.length})\n`);
|
|
63
|
+
process.stderr.write(`[meertrack-mcp] routes: POST /mcp, GET ${PRM_PATH}, GET /health\n`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function parseAllowedOrigins(value) {
|
|
67
|
+
return value
|
|
68
|
+
.split(",")
|
|
69
|
+
.map((s) => s.trim())
|
|
70
|
+
.filter((s) => s.length > 0);
|
|
71
|
+
}
|
|
72
|
+
main().catch((err) => {
|
|
73
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
74
|
+
process.stderr.write(`[meertrack-mcp] fatal: ${message}\n`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-line JSON logger to stderr.
|
|
3
|
+
*
|
|
4
|
+
* Both transports use stderr for diagnostics:
|
|
5
|
+
* - stdio: stdout is the protocol channel — anything else corrupts framing.
|
|
6
|
+
* - http : stderr keeps logs out of HTTP responses and lines them up with
|
|
7
|
+
* `fly logs` (Fly captures both streams; stderr is the convention).
|
|
8
|
+
*
|
|
9
|
+
* Every line is redacted with `redactApiKeys` before write — bearers must
|
|
10
|
+
* never reach disk. Keep the schema additive: consumers parse line-by-line
|
|
11
|
+
* and tolerate extra fields, so adding new keys is non-breaking.
|
|
12
|
+
*/
|
|
13
|
+
/** Fields the caller fills in on every log line. */
|
|
14
|
+
export interface LogInput {
|
|
15
|
+
/** Logical event name — `http_request`, `stdio_start`, `tool_error`, … */
|
|
16
|
+
event: string;
|
|
17
|
+
/** Optional caller-supplied timestamp; otherwise we set it. */
|
|
18
|
+
ts?: string;
|
|
19
|
+
/** HTTP status code, when applicable. */
|
|
20
|
+
status?: number;
|
|
21
|
+
/** Wall-clock duration in milliseconds. */
|
|
22
|
+
duration_ms?: number;
|
|
23
|
+
/** JSON-RPC method extracted from the request body, if any. */
|
|
24
|
+
mcp_method?: string;
|
|
25
|
+
/** Tool name when `mcp_method === "tools/call"`. */
|
|
26
|
+
tool?: string;
|
|
27
|
+
/** `MCP-Protocol-Version` header from the request. */
|
|
28
|
+
mcp_protocol_version?: string;
|
|
29
|
+
/** Inbound `User-Agent` header. */
|
|
30
|
+
client_user_agent?: string;
|
|
31
|
+
/** Upstream `X-Request-Id`, captured from the Meertrack client when available. */
|
|
32
|
+
meertrack_request_id?: string;
|
|
33
|
+
/** Free-form message for human readers (still redacted). */
|
|
34
|
+
message?: string;
|
|
35
|
+
/** Anything else worth tagging — kept open-ended on purpose. */
|
|
36
|
+
[extra: string]: unknown;
|
|
37
|
+
}
|
|
38
|
+
export type LogSink = (line: string) => void;
|
|
39
|
+
/** Default sink: stderr, newline-terminated. */
|
|
40
|
+
export declare const defaultSink: LogSink;
|
|
41
|
+
export declare class Logger {
|
|
42
|
+
private readonly sink;
|
|
43
|
+
constructor(sink?: LogSink);
|
|
44
|
+
log(record: LogInput): void;
|
|
45
|
+
}
|
|
46
|
+
/** Process-wide default. Tests can construct their own with a custom sink. */
|
|
47
|
+
export declare const logger: Logger;
|
|
48
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,oDAAoD;AACpD,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mCAAmC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAE7C,gDAAgD;AAChD,eAAO,MAAM,WAAW,EAAE,OAEzB,CAAC;AAEF,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;gBAEnB,IAAI,GAAE,OAAqB;IAIvC,GAAG,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI;CAmB5B;AAED,8EAA8E;AAC9E,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single-line JSON logger to stderr.
|
|
3
|
+
*
|
|
4
|
+
* Both transports use stderr for diagnostics:
|
|
5
|
+
* - stdio: stdout is the protocol channel — anything else corrupts framing.
|
|
6
|
+
* - http : stderr keeps logs out of HTTP responses and lines them up with
|
|
7
|
+
* `fly logs` (Fly captures both streams; stderr is the convention).
|
|
8
|
+
*
|
|
9
|
+
* Every line is redacted with `redactApiKeys` before write — bearers must
|
|
10
|
+
* never reach disk. Keep the schema additive: consumers parse line-by-line
|
|
11
|
+
* and tolerate extra fields, so adding new keys is non-breaking.
|
|
12
|
+
*/
|
|
13
|
+
import { redactApiKeys } from "./auth.js";
|
|
14
|
+
/** Default sink: stderr, newline-terminated. */
|
|
15
|
+
export const defaultSink = (line) => {
|
|
16
|
+
process.stderr.write(line + "\n");
|
|
17
|
+
};
|
|
18
|
+
export class Logger {
|
|
19
|
+
sink;
|
|
20
|
+
constructor(sink = defaultSink) {
|
|
21
|
+
this.sink = sink;
|
|
22
|
+
}
|
|
23
|
+
log(record) {
|
|
24
|
+
const full = {
|
|
25
|
+
...record,
|
|
26
|
+
ts: record.ts ?? new Date().toISOString(),
|
|
27
|
+
};
|
|
28
|
+
let serialized;
|
|
29
|
+
try {
|
|
30
|
+
serialized = JSON.stringify(full);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Fall back to a minimal record so a single un-serializable value can't
|
|
34
|
+
// silence logging entirely.
|
|
35
|
+
serialized = JSON.stringify({
|
|
36
|
+
ts: full.ts,
|
|
37
|
+
event: full.event,
|
|
38
|
+
message: "log_serialization_failed",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
this.sink(redactApiKeys(serialized));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Process-wide default. Tests can construct their own with a custom sink. */
|
|
45
|
+
export const logger = new Logger();
|
|
46
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AA8B1C,gDAAgD;AAChD,MAAM,CAAC,MAAM,WAAW,GAAY,CAAC,IAAI,EAAE,EAAE;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,OAAO,MAAM;IACA,IAAI,CAAU;IAE/B,YAAY,OAAgB,WAAW;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,GAAG,CAAC,MAAgB;QAClB,MAAM,IAAI,GAAa;YACrB,GAAG,MAAM;YACT,EAAE,EAAE,MAAM,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC1C,CAAC;QACF,IAAI,UAAkB,CAAC;QACvB,IAAI,CAAC;YACH,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;YACxE,4BAA4B;YAC5B,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC1B,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,OAAO,EAAE,0BAA0B;aACpC,CAAC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC;IACvC,CAAC;CACF;AAED,8EAA8E;AAC9E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare const COMPETITOR_DEEP_DIVE_NAME = "competitor_deep_dive";
|
|
3
|
+
export declare const COMPETITOR_DEEP_DIVE_DESCRIPTION = "Full profile and recent-activity brief for one competitor. Resolves the competitor by name, pulls the full profile, and summarizes the last 30 days of detected changes.";
|
|
4
|
+
export declare function registerCompetitorDeepDive(server: McpServer): void;
|
|
5
|
+
//# sourceMappingURL=competitor_deep_dive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"competitor_deep_dive.d.ts","sourceRoot":"","sources":["../../src/prompts/competitor_deep_dive.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,eAAO,MAAM,gCAAgC,6KAC+H,CAAC;AAS7K,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyClE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const COMPETITOR_DEEP_DIVE_NAME = "competitor_deep_dive";
|
|
3
|
+
export const COMPETITOR_DEEP_DIVE_DESCRIPTION = "Full profile and recent-activity brief for one competitor. Resolves the competitor by name, pulls the full profile, and summarizes the last 30 days of detected changes.";
|
|
4
|
+
const argsSchema = {
|
|
5
|
+
competitor_name: z
|
|
6
|
+
.string()
|
|
7
|
+
.min(1)
|
|
8
|
+
.describe("Competitor display name or a distinctive substring. Case-insensitive."),
|
|
9
|
+
};
|
|
10
|
+
export function registerCompetitorDeepDive(server) {
|
|
11
|
+
server.registerPrompt(COMPETITOR_DEEP_DIVE_NAME, {
|
|
12
|
+
title: "Competitor deep dive",
|
|
13
|
+
description: COMPETITOR_DEEP_DIVE_DESCRIPTION,
|
|
14
|
+
argsSchema,
|
|
15
|
+
}, (args) => ({
|
|
16
|
+
messages: [
|
|
17
|
+
{
|
|
18
|
+
role: "user",
|
|
19
|
+
content: {
|
|
20
|
+
type: "text",
|
|
21
|
+
text: [
|
|
22
|
+
`Produce a structured deep-dive brief on the competitor "${args.competitor_name}" using the Meertrack MCP server.`,
|
|
23
|
+
"",
|
|
24
|
+
"Step 1 — Resolve the competitor id:",
|
|
25
|
+
"- Call `list_competitors` (no filters, default `expand=full`).",
|
|
26
|
+
`- Find the row whose \`name\` matches "${args.competitor_name}" (case-insensitive; substring match is acceptable). If no row matches, stop and tell the user — do not guess.`,
|
|
27
|
+
"- If several rows match, list them and ask the user to disambiguate.",
|
|
28
|
+
"",
|
|
29
|
+
"Step 2 — Fetch the full profile:",
|
|
30
|
+
"- Call `get_competitor` with the resolved `id`. This returns the profile plus the most recent items from each tracked section (blog posts, pricing, job listings, messaging, logos, metrics, LinkedIn, YouTube, events, press, case studies).",
|
|
31
|
+
"",
|
|
32
|
+
"Step 3 — Fetch recent activity:",
|
|
33
|
+
"- Call `list_activities` with `competitor_ids=[<id>]` and `from=<today minus 30 days, ISO 8601>`. Default `limit=50` is fine; page once if `pagination.has_more` is true.",
|
|
34
|
+
"",
|
|
35
|
+
"Step 4 — Synthesize the brief with these sections:",
|
|
36
|
+
"- `## Profile` — website, category, social handles from `get_competitor`.",
|
|
37
|
+
"- `## What's new (last 30 days)` — grouped by section; emphasize `change_type=added`.",
|
|
38
|
+
"- `## Current positioning` — draw from `messaging`, `metrics-claimed`, and `pricing` items in the profile.",
|
|
39
|
+
"- `## Hiring signals` — from `job-listings` if present.",
|
|
40
|
+
"",
|
|
41
|
+
"Rules: cite concrete items (URLs, posted dates, prices). Do not invent details not present in the tool responses. If a section has no items, say 'No data' rather than padding.",
|
|
42
|
+
].join("\n"),
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=competitor_deep_dive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"competitor_deep_dive.js","sourceRoot":"","sources":["../../src/prompts/competitor_deep_dive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAEhE,MAAM,CAAC,MAAM,gCAAgC,GAC3C,0KAA0K,CAAC;AAE7K,MAAM,UAAU,GAAG;IACjB,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,uEAAuE,CAAC;CAC5E,CAAC;AAEX,MAAM,UAAU,0BAA0B,CAAC,MAAiB;IAC1D,MAAM,CAAC,cAAc,CACnB,yBAAyB,EACzB;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,gCAAgC;QAC7C,UAAU;KACX,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACJ,2DAA2D,IAAI,CAAC,eAAe,mCAAmC;wBAClH,EAAE;wBACF,qCAAqC;wBACrC,gEAAgE;wBAChE,0CAA0C,IAAI,CAAC,eAAe,gHAAgH;wBAC9K,sEAAsE;wBACtE,EAAE;wBACF,kCAAkC;wBAClC,+OAA+O;wBAC/O,EAAE;wBACF,iCAAiC;wBACjC,2KAA2K;wBAC3K,EAAE;wBACF,oDAAoD;wBACpD,2EAA2E;wBAC3E,uFAAuF;wBACvF,4GAA4G;wBAC5G,yDAAyD;wBACzD,EAAE;wBACF,iLAAiL;qBAClL,CAAC,IAAI,CAAC,IAAI,CAAC;iBACb;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { WEEKLY_RECAP_NAME } from "./weekly_recap.js";
|
|
3
|
+
import { COMPETITOR_DEEP_DIVE_NAME } from "./competitor_deep_dive.js";
|
|
4
|
+
import { WHATS_NEW_NAME } from "./whats_new.js";
|
|
5
|
+
/**
|
|
6
|
+
* Register all 3 prompts on `server`. Prompts surface as slash-commands in
|
|
7
|
+
* MCP-aware clients (Claude Desktop, Cursor, …) and chain the 8 tools into
|
|
8
|
+
* complete workflows without requiring the user to specify the orchestration.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerAllPrompts(server: McpServer): void;
|
|
11
|
+
export declare const PROMPT_NAMES: readonly ["weekly_recap", "competitor_deep_dive", "whats_new"];
|
|
12
|
+
export { WEEKLY_RECAP_NAME, COMPETITOR_DEEP_DIVE_NAME, WHATS_NEW_NAME };
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAuB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAEL,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAoB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAI1D;AAED,eAAO,MAAM,YAAY,gEAIf,CAAC;AAEX,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { registerWeeklyRecap, WEEKLY_RECAP_NAME } from "./weekly_recap.js";
|
|
2
|
+
import { registerCompetitorDeepDive, COMPETITOR_DEEP_DIVE_NAME, } from "./competitor_deep_dive.js";
|
|
3
|
+
import { registerWhatsNew, WHATS_NEW_NAME } from "./whats_new.js";
|
|
4
|
+
/**
|
|
5
|
+
* Register all 3 prompts on `server`. Prompts surface as slash-commands in
|
|
6
|
+
* MCP-aware clients (Claude Desktop, Cursor, …) and chain the 8 tools into
|
|
7
|
+
* complete workflows without requiring the user to specify the orchestration.
|
|
8
|
+
*/
|
|
9
|
+
export function registerAllPrompts(server) {
|
|
10
|
+
registerWeeklyRecap(server);
|
|
11
|
+
registerCompetitorDeepDive(server);
|
|
12
|
+
registerWhatsNew(server);
|
|
13
|
+
}
|
|
14
|
+
export const PROMPT_NAMES = [
|
|
15
|
+
WEEKLY_RECAP_NAME,
|
|
16
|
+
COMPETITOR_DEEP_DIVE_NAME,
|
|
17
|
+
WHATS_NEW_NAME,
|
|
18
|
+
];
|
|
19
|
+
export { WEEKLY_RECAP_NAME, COMPETITOR_DEEP_DIVE_NAME, WHATS_NEW_NAME };
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACnC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iBAAiB;IACjB,yBAAyB;IACzB,cAAc;CACN,CAAC;AAEX,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare const WEEKLY_RECAP_NAME = "weekly_recap";
|
|
3
|
+
export declare const WEEKLY_RECAP_DESCRIPTION = "One-shot 'what happened across my tracked competitors this week'. Fetches the latest digests and produces a per-competitor recap plus a cross-competitor highlights list.";
|
|
4
|
+
export declare function registerWeeklyRecap(server: McpServer): void;
|
|
5
|
+
//# sourceMappingURL=weekly_recap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weekly_recap.d.ts","sourceRoot":"","sources":["../../src/prompts/weekly_recap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,eAAO,MAAM,wBAAwB,8KACwI,CAAC;AAE9K,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4B3D"}
|