@cesteral/snapchat-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.md +201 -0
- package/README.md +336 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +3 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/snapchat-auth-adapter.d.ts +44 -0
- package/dist/auth/snapchat-auth-adapter.d.ts.map +1 -0
- package/dist/auth/snapchat-auth-adapter.js +127 -0
- package/dist/auth/snapchat-auth-adapter.js.map +1 -0
- package/dist/auth/snapchat-auth-strategy.d.ts +13 -0
- package/dist/auth/snapchat-auth-strategy.d.ts.map +1 -0
- package/dist/auth/snapchat-auth-strategy.js +54 -0
- package/dist/auth/snapchat-auth-strategy.js.map +1 -0
- package/dist/config/index.d.ts +124 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +57 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.js +127 -0
- package/dist/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/campaign-setup-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/campaign-setup-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/campaign-setup-workflow.prompt.js +121 -0
- package/dist/mcp-server/prompts/definitions/campaign-setup-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/creative-upload-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/creative-upload-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/creative-upload-workflow.prompt.js +121 -0
- package/dist/mcp-server/prompts/definitions/creative-upload-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-campaign-setup.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-campaign-setup.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-campaign-setup.prompt.js +299 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-campaign-setup.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-performance.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-performance.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-performance.prompt.js +170 -0
- package/dist/mcp-server/prompts/definitions/cross-platform-performance.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/entity-duplication-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/entity-duplication-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/entity-duplication-workflow.prompt.js +198 -0
- package/dist/mcp-server/prompts/definitions/entity-duplication-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/entity-update-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/entity-update-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/entity-update-workflow.prompt.js +189 -0
- package/dist/mcp-server/prompts/definitions/entity-update-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/reporting-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/reporting-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/reporting-workflow.prompt.js +126 -0
- package/dist/mcp-server/prompts/definitions/reporting-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/targeting-discovery-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/targeting-discovery-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/targeting-discovery-workflow.prompt.js +198 -0
- package/dist/mcp-server/prompts/definitions/targeting-discovery-workflow.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/tool-schema-exploration.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/tool-schema-exploration.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/tool-schema-exploration.prompt.js +91 -0
- package/dist/mcp-server/prompts/definitions/tool-schema-exploration.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/troubleshoot-entity.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/troubleshoot-entity.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/troubleshoot-entity.prompt.js +111 -0
- package/dist/mcp-server/prompts/definitions/troubleshoot-entity.prompt.js.map +1 -0
- package/dist/mcp-server/prompts/index.d.ts +9 -0
- package/dist/mcp-server/prompts/index.d.ts.map +1 -0
- package/dist/mcp-server/prompts/index.js +89 -0
- package/dist/mcp-server/prompts/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-examples.resource.d.ts +4 -0
- package/dist/mcp-server/resources/definitions/entity-examples.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-examples.resource.js +177 -0
- package/dist/mcp-server/resources/definitions/entity-examples.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-hierarchy.resource.d.ts +3 -0
- package/dist/mcp-server/resources/definitions/entity-hierarchy.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-hierarchy.resource.js +194 -0
- package/dist/mcp-server/resources/definitions/entity-hierarchy.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-schemas.resource.d.ts +4 -0
- package/dist/mcp-server/resources/definitions/entity-schemas.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/entity-schemas.resource.js +117 -0
- package/dist/mcp-server/resources/definitions/entity-schemas.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +7 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +54 -0
- package/dist/mcp-server/resources/definitions/index.js.map +1 -0
- package/dist/mcp-server/resources/definitions/reporting-reference.resource.d.ts +3 -0
- package/dist/mcp-server/resources/definitions/reporting-reference.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/reporting-reference.resource.js +148 -0
- package/dist/mcp-server/resources/definitions/reporting-reference.resource.js.map +1 -0
- package/dist/mcp-server/resources/index.d.ts +3 -0
- package/dist/mcp-server/resources/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/index.js +2 -0
- package/dist/mcp-server/resources/index.js.map +1 -0
- package/dist/mcp-server/resources/types.d.ts +8 -0
- package/dist/mcp-server/resources/types.d.ts.map +1 -0
- package/dist/mcp-server/resources/types.js +2 -0
- package/dist/mcp-server/resources/types.js.map +1 -0
- package/dist/mcp-server/server.d.ts +5 -0
- package/dist/mcp-server/server.d.ts.map +1 -0
- package/dist/mcp-server/server.js +134 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/mcp-server/tools/definitions/adjust-bids.tool.d.ts +209 -0
- package/dist/mcp-server/tools/definitions/adjust-bids.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/adjust-bids.tool.js +141 -0
- package/dist/mcp-server/tools/definitions/adjust-bids.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-create-entities.tool.d.ts +163 -0
- package/dist/mcp-server/tools/definitions/bulk-create-entities.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-create-entities.tool.js +119 -0
- package/dist/mcp-server/tools/definitions/bulk-create-entities.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-update-entities.tool.d.ts +241 -0
- package/dist/mcp-server/tools/definitions/bulk-update-entities.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-update-entities.tool.js +149 -0
- package/dist/mcp-server/tools/definitions/bulk-update-entities.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-update-status.tool.d.ts +203 -0
- package/dist/mcp-server/tools/definitions/bulk-update-status.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/bulk-update-status.tool.js +154 -0
- package/dist/mcp-server/tools/definitions/bulk-update-status.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/check-report-status.tool.d.ts +119 -0
- package/dist/mcp-server/tools/definitions/check-report-status.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/check-report-status.tool.js +89 -0
- package/dist/mcp-server/tools/definitions/check-report-status.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/create-entity.tool.d.ts +131 -0
- package/dist/mcp-server/tools/definitions/create-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/create-entity.tool.js +116 -0
- package/dist/mcp-server/tools/definitions/create-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/delete-entity.tool.d.ts +100 -0
- package/dist/mcp-server/tools/definitions/delete-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/delete-entity.tool.js +110 -0
- package/dist/mcp-server/tools/definitions/delete-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/download-report.tool.d.ts +297 -0
- package/dist/mcp-server/tools/definitions/download-report.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/download-report.tool.js +103 -0
- package/dist/mcp-server/tools/definitions/download-report.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/duplicate-entity.tool.d.ts +105 -0
- package/dist/mcp-server/tools/definitions/duplicate-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/duplicate-entity.tool.js +93 -0
- package/dist/mcp-server/tools/definitions/duplicate-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ad-preview.tool.d.ts +68 -0
- package/dist/mcp-server/tools/definitions/get-ad-preview.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ad-preview.tool.js +61 -0
- package/dist/mcp-server/tools/definitions/get-ad-preview.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-audience-estimate.tool.d.ts +104 -0
- package/dist/mcp-server/tools/definitions/get-audience-estimate.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-audience-estimate.tool.js +107 -0
- package/dist/mcp-server/tools/definitions/get-audience-estimate.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.d.ts +76 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.js +71 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-report-breakdowns.tool.d.ts +295 -0
- package/dist/mcp-server/tools/definitions/get-report-breakdowns.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-report-breakdowns.tool.js +172 -0
- package/dist/mcp-server/tools/definitions/get-report-breakdowns.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-report.tool.d.ts +279 -0
- package/dist/mcp-server/tools/definitions/get-report.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-report.tool.js +166 -0
- package/dist/mcp-server/tools/definitions/get-report.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.d.ts +89 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.js +99 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +25 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +75 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-advertisers.tool.d.ts +54 -0
- package/dist/mcp-server/tools/definitions/list-advertisers.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/list-advertisers.tool.js +61 -0
- package/dist/mcp-server/tools/definitions/list-advertisers.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-entities.tool.d.ts +161 -0
- package/dist/mcp-server/tools/definitions/list-entities.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/list-entities.tool.js +94 -0
- package/dist/mcp-server/tools/definitions/list-entities.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-targeting.tool.d.ts +103 -0
- package/dist/mcp-server/tools/definitions/search-targeting.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-targeting.tool.js +108 -0
- package/dist/mcp-server/tools/definitions/search-targeting.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/submit-report.tool.d.ts +134 -0
- package/dist/mcp-server/tools/definitions/submit-report.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/submit-report.tool.js +110 -0
- package/dist/mcp-server/tools/definitions/submit-report.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/update-entity.tool.d.ts +155 -0
- package/dist/mcp-server/tools/definitions/update-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/update-entity.tool.js +115 -0
- package/dist/mcp-server/tools/definitions/update-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/upload-image.tool.d.ts +82 -0
- package/dist/mcp-server/tools/definitions/upload-image.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/upload-image.tool.js +111 -0
- package/dist/mcp-server/tools/definitions/upload-image.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/upload-video.tool.d.ts +82 -0
- package/dist/mcp-server/tools/definitions/upload-video.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/upload-video.tool.js +109 -0
- package/dist/mcp-server/tools/definitions/upload-video.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/validate-entity.tool.d.ts +169 -0
- package/dist/mcp-server/tools/definitions/validate-entity.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/validate-entity.tool.js +204 -0
- package/dist/mcp-server/tools/definitions/validate-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/index.d.ts +2 -0
- package/dist/mcp-server/tools/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/index.js +2 -0
- package/dist/mcp-server/tools/index.js.map +1 -0
- package/dist/mcp-server/tools/utils/entity-mapping.d.ts +18 -0
- package/dist/mcp-server/tools/utils/entity-mapping.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/entity-mapping.js +96 -0
- package/dist/mcp-server/tools/utils/entity-mapping.js.map +1 -0
- package/dist/mcp-server/tools/utils/media-types.d.ts +19 -0
- package/dist/mcp-server/tools/utils/media-types.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/media-types.js +2 -0
- package/dist/mcp-server/tools/utils/media-types.js.map +1 -0
- package/dist/mcp-server/tools/utils/resolve-session.d.ts +4 -0
- package/dist/mcp-server/tools/utils/resolve-session.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/resolve-session.js +6 -0
- package/dist/mcp-server/tools/utils/resolve-session.js.map +1 -0
- package/dist/mcp-server/transports/streamable-http-transport.d.ts +61 -0
- package/dist/mcp-server/transports/streamable-http-transport.d.ts.map +1 -0
- package/dist/mcp-server/transports/streamable-http-transport.js +105 -0
- package/dist/mcp-server/transports/streamable-http-transport.js.map +1 -0
- package/dist/services/session-services.d.ts +20 -0
- package/dist/services/session-services.d.ts.map +1 -0
- package/dist/services/session-services.js +23 -0
- package/dist/services/session-services.js.map +1 -0
- package/dist/services/snapchat/snapchat-http-client.d.ts +16 -0
- package/dist/services/snapchat/snapchat-http-client.d.ts.map +1 -0
- package/dist/services/snapchat/snapchat-http-client.js +153 -0
- package/dist/services/snapchat/snapchat-http-client.js.map +1 -0
- package/dist/services/snapchat/snapchat-reporting-service.d.ts +64 -0
- package/dist/services/snapchat/snapchat-reporting-service.d.ts.map +1 -0
- package/dist/services/snapchat/snapchat-reporting-service.js +172 -0
- package/dist/services/snapchat/snapchat-reporting-service.js.map +1 -0
- package/dist/services/snapchat/snapchat-service.d.ts +82 -0
- package/dist/services/snapchat/snapchat-service.d.ts.map +1 -0
- package/dist/services/snapchat/snapchat-service.js +321 -0
- package/dist/services/snapchat/snapchat-service.js.map +1 -0
- package/dist/services/snapchat/types.d.ts +136 -0
- package/dist/services/snapchat/types.d.ts.map +1 -0
- package/dist/services/snapchat/types.js +59 -0
- package/dist/services/snapchat/types.js.map +1 -0
- package/dist/types-global/mcp.d.ts +2 -0
- package/dist/types-global/mcp.d.ts.map +1 -0
- package/dist/types-global/mcp.js +2 -0
- package/dist/types-global/mcp.js.map +1 -0
- package/dist/utils/errors/index.d.ts +2 -0
- package/dist/utils/errors/index.d.ts.map +1 -0
- package/dist/utils/errors/index.js +2 -0
- package/dist/utils/errors/index.js.map +1 -0
- package/dist/utils/platform.d.ts +3 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +5 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/utils/security/rate-limiter.d.ts +3 -0
- package/dist/utils/security/rate-limiter.d.ts.map +1 -0
- package/dist/utils/security/rate-limiter.js +5 -0
- package/dist/utils/security/rate-limiter.js.map +1 -0
- package/dist/utils/telemetry/index.d.ts +2 -0
- package/dist/utils/telemetry/index.d.ts.map +1 -0
- package/dist/utils/telemetry/index.js +2 -0
- package/dist/utils/telemetry/index.js.map +1 -0
- package/dist/utils/telemetry/tracing.d.ts +3 -0
- package/dist/utils/telemetry/tracing.d.ts.map +1 -0
- package/dist/utils/telemetry/tracing.js +4 -0
- package/dist/utils/telemetry/tracing.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { extractHeader, fetchWithTimeout, fingerprintCredentials, JsonRpcErrorCode, McpError, OAuth2RefreshAdapterBase, } from "@cesteral/shared";
|
|
2
|
+
async function fetchSnapchatUserId(token, baseUrl) {
|
|
3
|
+
const response = await fetchWithTimeout(`${baseUrl}/v1/me`, 10_000, undefined, {
|
|
4
|
+
method: "GET",
|
|
5
|
+
headers: {
|
|
6
|
+
Authorization: `Bearer ${token}`,
|
|
7
|
+
"Content-Type": "application/json",
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
if (!response.ok) {
|
|
11
|
+
const errorBody = await response.text().catch(() => "");
|
|
12
|
+
throw new McpError(JsonRpcErrorCode.Unauthorized, `Snapchat token validation HTTP error: ${response.status} ${response.statusText}. ${errorBody.substring(0, 200)}`);
|
|
13
|
+
}
|
|
14
|
+
const data = (await response.json());
|
|
15
|
+
return data.me?.id ?? "unknown";
|
|
16
|
+
}
|
|
17
|
+
export class SnapchatAccessTokenAdapter {
|
|
18
|
+
accessToken;
|
|
19
|
+
_adAccountId;
|
|
20
|
+
baseUrl;
|
|
21
|
+
_orgId;
|
|
22
|
+
validated = false;
|
|
23
|
+
_userId = "";
|
|
24
|
+
constructor(accessToken, _adAccountId, baseUrl = "https://adsapi.snapchat.com", _orgId = "") {
|
|
25
|
+
this.accessToken = accessToken;
|
|
26
|
+
this._adAccountId = _adAccountId;
|
|
27
|
+
this.baseUrl = baseUrl;
|
|
28
|
+
this._orgId = _orgId;
|
|
29
|
+
}
|
|
30
|
+
get userId() {
|
|
31
|
+
return this._userId;
|
|
32
|
+
}
|
|
33
|
+
get adAccountId() {
|
|
34
|
+
return this._adAccountId;
|
|
35
|
+
}
|
|
36
|
+
get orgId() {
|
|
37
|
+
return this._orgId;
|
|
38
|
+
}
|
|
39
|
+
async getAccessToken() {
|
|
40
|
+
return this.accessToken;
|
|
41
|
+
}
|
|
42
|
+
async validate() {
|
|
43
|
+
if (this.validated)
|
|
44
|
+
return;
|
|
45
|
+
this._userId = await fetchSnapchatUserId(this.accessToken, this.baseUrl);
|
|
46
|
+
this.validated = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class SnapchatRefreshTokenAdapter extends OAuth2RefreshAdapterBase {
|
|
50
|
+
_adAccountId;
|
|
51
|
+
baseUrl;
|
|
52
|
+
_orgId;
|
|
53
|
+
_userId = "";
|
|
54
|
+
constructor(credentials, _adAccountId, baseUrl = "https://adsapi.snapchat.com", _orgId = "") {
|
|
55
|
+
super({
|
|
56
|
+
platformName: "Snapchat",
|
|
57
|
+
credentials,
|
|
58
|
+
requestToken: async (refreshToken) => {
|
|
59
|
+
const response = await fetchWithTimeout("https://accounts.snapchat.com/login/oauth2/access_token", 10_000, undefined, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
62
|
+
body: new URLSearchParams({
|
|
63
|
+
grant_type: "refresh_token",
|
|
64
|
+
client_id: credentials.appId,
|
|
65
|
+
client_secret: credentials.appSecret,
|
|
66
|
+
refresh_token: refreshToken,
|
|
67
|
+
}).toString(),
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const errorBody = await response.text().catch(() => "");
|
|
71
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Snapchat token refresh failed: ${response.status} ${response.statusText}. ${errorBody.substring(0, 200)}`);
|
|
72
|
+
}
|
|
73
|
+
return (await response.json());
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
this._adAccountId = _adAccountId;
|
|
77
|
+
this.baseUrl = baseUrl;
|
|
78
|
+
this._orgId = _orgId;
|
|
79
|
+
}
|
|
80
|
+
get userId() {
|
|
81
|
+
return this._userId;
|
|
82
|
+
}
|
|
83
|
+
get adAccountId() {
|
|
84
|
+
return this._adAccountId;
|
|
85
|
+
}
|
|
86
|
+
get orgId() {
|
|
87
|
+
return this._orgId;
|
|
88
|
+
}
|
|
89
|
+
async validate() {
|
|
90
|
+
const token = await this.getAccessToken();
|
|
91
|
+
this._userId = await fetchSnapchatUserId(token, this.baseUrl);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function parseSnapchatRefreshCredentialsFromHeaders(headers) {
|
|
95
|
+
const appId = extractHeader(headers, "x-snapchat-app-id");
|
|
96
|
+
const appSecret = extractHeader(headers, "x-snapchat-app-secret");
|
|
97
|
+
const refreshToken = extractHeader(headers, "x-snapchat-refresh-token");
|
|
98
|
+
if (!appId || !appSecret || !refreshToken) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return { appId, appSecret, refreshToken };
|
|
102
|
+
}
|
|
103
|
+
export function parseSnapchatTokenFromHeaders(headers) {
|
|
104
|
+
const authHeader = extractHeader(headers, "authorization");
|
|
105
|
+
if (!authHeader) {
|
|
106
|
+
throw new McpError(JsonRpcErrorCode.Unauthorized, "Missing required Authorization header");
|
|
107
|
+
}
|
|
108
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
109
|
+
if (!match || !match[1]) {
|
|
110
|
+
throw new McpError(JsonRpcErrorCode.Unauthorized, "Authorization header must use Bearer scheme");
|
|
111
|
+
}
|
|
112
|
+
return match[1];
|
|
113
|
+
}
|
|
114
|
+
export function getSnapchatAdvertiserIdFromHeaders(headers) {
|
|
115
|
+
const adAccountId = extractHeader(headers, "x-snapchat-advertiser-id");
|
|
116
|
+
if (!adAccountId) {
|
|
117
|
+
throw new McpError(JsonRpcErrorCode.InvalidRequest, "Missing required X-Snapchat-Advertiser-Id header");
|
|
118
|
+
}
|
|
119
|
+
return adAccountId;
|
|
120
|
+
}
|
|
121
|
+
export function getSnapchatOrgIdFromHeaders(headers) {
|
|
122
|
+
return extractHeader(headers, "x-snapchat-org-id") ?? "";
|
|
123
|
+
}
|
|
124
|
+
export function getSnapchatCredentialFingerprint(accessToken, adAccountId) {
|
|
125
|
+
return fingerprintCredentials(accessToken, adAccountId);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=snapchat-auth-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapchat-auth-adapter.js","sourceRoot":"","sources":["../../src/auth/snapchat-auth-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Logger } from "pino";
|
|
2
|
+
import { BearerAuthStrategyBase, type BearerAdapterResult } from "@cesteral/shared";
|
|
3
|
+
export declare class SnapchatBearerAuthStrategy extends BearerAuthStrategyBase {
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
protected readonly authType = "snapchat-bearer";
|
|
6
|
+
protected readonly platformName = "Snapchat";
|
|
7
|
+
constructor(baseUrl: string, logger?: Logger);
|
|
8
|
+
protected resolveRefreshBranch(headers: Record<string, string | string[] | undefined>): Promise<BearerAdapterResult | null>;
|
|
9
|
+
protected resolveAccessBranch(headers: Record<string, string | string[] | undefined>): Promise<BearerAdapterResult>;
|
|
10
|
+
protected getRefreshFingerprint(headers: Record<string, string | string[] | undefined>): string | undefined;
|
|
11
|
+
protected getTokenFingerprint(headers: Record<string, string | string[] | undefined>): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=snapchat-auth-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapchat-auth-strategy.d.ts","sourceRoot":"","sources":["../../src/auth/snapchat-auth-strategy.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAWpF,qBAAa,0BAA2B,SAAQ,sBAAsB;IAKlE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,SAAS,CAAC,QAAQ,CAAC,QAAQ,qBAAqB;IAChD,SAAS,CAAC,QAAQ,CAAC,YAAY,cAAc;gBAG1B,OAAO,EAAE,MAAM,EAChC,MAAM,CAAC,EAAE,MAAM;cAKD,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;cAmBtB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,mBAAmB,CAAC;IAgB/B,SAAS,CAAC,qBAAqB,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,GAAG,SAAS;IAOrB,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM;CAK9F"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { BearerAuthStrategyBase } from "@cesteral/shared";
|
|
2
|
+
import { SnapchatAccessTokenAdapter, SnapchatRefreshTokenAdapter, parseSnapchatTokenFromHeaders, parseSnapchatRefreshCredentialsFromHeaders, getSnapchatAdvertiserIdFromHeaders, getSnapchatOrgIdFromHeaders, getSnapchatCredentialFingerprint, } from "./snapchat-auth-adapter.js";
|
|
3
|
+
export class SnapchatBearerAuthStrategy extends BearerAuthStrategyBase {
|
|
4
|
+
baseUrl;
|
|
5
|
+
authType = "snapchat-bearer";
|
|
6
|
+
platformName = "Snapchat";
|
|
7
|
+
constructor(baseUrl, logger) {
|
|
8
|
+
super(logger);
|
|
9
|
+
this.baseUrl = baseUrl;
|
|
10
|
+
}
|
|
11
|
+
async resolveRefreshBranch(headers) {
|
|
12
|
+
const refreshCreds = parseSnapchatRefreshCredentialsFromHeaders(headers);
|
|
13
|
+
if (!refreshCreds)
|
|
14
|
+
return null;
|
|
15
|
+
const adAccountId = getSnapchatAdvertiserIdFromHeaders(headers);
|
|
16
|
+
const orgId = getSnapchatOrgIdFromHeaders(headers);
|
|
17
|
+
const adapter = new SnapchatRefreshTokenAdapter(refreshCreds, adAccountId, this.baseUrl, orgId);
|
|
18
|
+
await adapter.validate();
|
|
19
|
+
return {
|
|
20
|
+
adapter,
|
|
21
|
+
fingerprint: getSnapchatCredentialFingerprint(refreshCreds.appId, adAccountId),
|
|
22
|
+
userId: adapter.userId,
|
|
23
|
+
authFlow: "refresh-token",
|
|
24
|
+
logContext: { adAccountId, orgId },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async resolveAccessBranch(headers) {
|
|
28
|
+
const token = parseSnapchatTokenFromHeaders(headers);
|
|
29
|
+
const adAccountId = getSnapchatAdvertiserIdFromHeaders(headers);
|
|
30
|
+
const orgId = getSnapchatOrgIdFromHeaders(headers);
|
|
31
|
+
const adapter = new SnapchatAccessTokenAdapter(token, adAccountId, this.baseUrl, orgId);
|
|
32
|
+
await adapter.validate();
|
|
33
|
+
return {
|
|
34
|
+
adapter,
|
|
35
|
+
fingerprint: getSnapchatCredentialFingerprint(token, adAccountId),
|
|
36
|
+
userId: adapter.userId,
|
|
37
|
+
authFlow: "static-token",
|
|
38
|
+
logContext: { adAccountId, orgId },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
getRefreshFingerprint(headers) {
|
|
42
|
+
const refreshCreds = parseSnapchatRefreshCredentialsFromHeaders(headers);
|
|
43
|
+
if (!refreshCreds)
|
|
44
|
+
return undefined;
|
|
45
|
+
const adAccountId = getSnapchatAdvertiserIdFromHeaders(headers);
|
|
46
|
+
return getSnapchatCredentialFingerprint(refreshCreds.appId, adAccountId);
|
|
47
|
+
}
|
|
48
|
+
getTokenFingerprint(headers) {
|
|
49
|
+
const token = parseSnapchatTokenFromHeaders(headers);
|
|
50
|
+
const adAccountId = getSnapchatAdvertiserIdFromHeaders(headers);
|
|
51
|
+
return getSnapchatCredentialFingerprint(token, adAccountId);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=snapchat-auth-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapchat-auth-strategy.js","sourceRoot":"","sources":["../../src/auth/snapchat-auth-strategy.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,6BAA6B,EAC7B,0CAA0C,EAC1C,kCAAkC,EAClC,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,4BAA4B,CAAC;AAEpC,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;IAKjD;IAJA,QAAQ,GAAG,iBAAiB,CAAC;IAC7B,YAAY,GAAG,UAAU,CAAC;IAE7C,YACmB,OAAe,EAChC,MAAe;QAEf,KAAK,CAAC,MAAM,CAAC,CAAC;QAHG,YAAO,GAAP,OAAO,CAAQ;IAIlC,CAAC;IAES,KAAK,CAAC,oBAAoB,CAClC,OAAsD;QAEtD,MAAM,YAAY,GAAG,0CAA0C,CAAC,OAAO,CAAC,CAAC;QACzE,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,WAAW,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,2BAA2B,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAChG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzB,OAAO;YACL,OAAO;YAEP,WAAW,EAAE,gCAAgC,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC;YAC9E,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,eAAe;YACzB,UAAU,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;SACnC,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,mBAAmB,CACjC,OAAsD;QAEtD,MAAM,KAAK,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,0BAA0B,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACxF,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzB,OAAO;YACL,OAAO;YACP,WAAW,EAAE,gCAAgC,CAAC,KAAK,EAAE,WAAW,CAAC;YACjE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;SACnC,CAAC;IACJ,CAAC;IAES,qBAAqB,CAC7B,OAAsD;QAEtD,MAAM,YAAY,GAAG,0CAA0C,CAAC,OAAO,CAAC,CAAC;QACzE,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,WAAW,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;QAChE,OAAO,gCAAgC,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC3E,CAAC;IAES,mBAAmB,CAAC,OAAsD;QAClF,MAAM,KAAK,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,kCAAkC,CAAC,OAAO,CAAC,CAAC;QAChE,OAAO,gCAAgC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;CACF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const ConfigSchema: z.ZodObject<{
|
|
3
|
+
host: z.ZodDefault<z.ZodString>;
|
|
4
|
+
nodeEnv: z.ZodDefault<z.ZodEnum<["development", "production", "test"]>>;
|
|
5
|
+
mcpStatefulSessionTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
mcpAuthSecretKey: z.ZodOptional<z.ZodString>;
|
|
7
|
+
mcpAllowedOrigins: z.ZodOptional<z.ZodString>;
|
|
8
|
+
logLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "notice", "warning", "error"]>>;
|
|
9
|
+
mcpLogLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "notice", "warning", "error"]>>;
|
|
10
|
+
otelEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
11
|
+
otelExporterOtlpTracesEndpoint: z.ZodOptional<z.ZodString>;
|
|
12
|
+
otelExporterOtlpMetricsEndpoint: z.ZodOptional<z.ZodString>;
|
|
13
|
+
gcsBucketName: z.ZodOptional<z.ZodString>;
|
|
14
|
+
} & {
|
|
15
|
+
serviceName: z.ZodDefault<z.ZodString>;
|
|
16
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
17
|
+
otelServiceName: z.ZodDefault<z.ZodString>;
|
|
18
|
+
mcpAuthMode: z.ZodDefault<z.ZodEnum<["snapchat-bearer", "jwt", "none"]>>;
|
|
19
|
+
snapchatApiBaseUrl: z.ZodDefault<z.ZodString>;
|
|
20
|
+
snapchatApiVersion: z.ZodDefault<z.ZodString>;
|
|
21
|
+
snapchatRateLimitPerMinute: z.ZodDefault<z.ZodNumber>;
|
|
22
|
+
snapchatAccessToken: z.ZodOptional<z.ZodString>;
|
|
23
|
+
snapchatAdAccountId: z.ZodOptional<z.ZodString>;
|
|
24
|
+
snapchatOrgId: z.ZodOptional<z.ZodString>;
|
|
25
|
+
snapchatAppId: z.ZodOptional<z.ZodString>;
|
|
26
|
+
snapchatAppSecret: z.ZodOptional<z.ZodString>;
|
|
27
|
+
snapchatRefreshToken: z.ZodOptional<z.ZodString>;
|
|
28
|
+
snapchatReportPollIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
29
|
+
snapchatReportMaxPollAttempts: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
snapchatVideoUploadPollIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
snapchatVideoUploadMaxPollAttempts: z.ZodDefault<z.ZodNumber>;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
serviceName: string;
|
|
34
|
+
port: number;
|
|
35
|
+
otelServiceName: string;
|
|
36
|
+
mcpAuthMode: "snapchat-bearer" | "jwt" | "none";
|
|
37
|
+
snapchatApiBaseUrl: string;
|
|
38
|
+
snapchatApiVersion: string;
|
|
39
|
+
snapchatRateLimitPerMinute: number;
|
|
40
|
+
snapchatReportPollIntervalMs: number;
|
|
41
|
+
snapchatReportMaxPollAttempts: number;
|
|
42
|
+
snapchatVideoUploadPollIntervalMs: number;
|
|
43
|
+
snapchatVideoUploadMaxPollAttempts: number;
|
|
44
|
+
host: string;
|
|
45
|
+
nodeEnv: "development" | "production" | "test";
|
|
46
|
+
mcpStatefulSessionTimeoutMs: number;
|
|
47
|
+
logLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
48
|
+
mcpLogLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
49
|
+
otelEnabled: boolean;
|
|
50
|
+
snapchatAccessToken?: string | undefined;
|
|
51
|
+
snapchatAdAccountId?: string | undefined;
|
|
52
|
+
snapchatOrgId?: string | undefined;
|
|
53
|
+
snapchatAppId?: string | undefined;
|
|
54
|
+
snapchatAppSecret?: string | undefined;
|
|
55
|
+
snapchatRefreshToken?: string | undefined;
|
|
56
|
+
mcpAuthSecretKey?: string | undefined;
|
|
57
|
+
mcpAllowedOrigins?: string | undefined;
|
|
58
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
59
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
60
|
+
gcsBucketName?: string | undefined;
|
|
61
|
+
}, {
|
|
62
|
+
serviceName?: string | undefined;
|
|
63
|
+
port?: number | undefined;
|
|
64
|
+
otelServiceName?: string | undefined;
|
|
65
|
+
mcpAuthMode?: "snapchat-bearer" | "jwt" | "none" | undefined;
|
|
66
|
+
snapchatApiBaseUrl?: string | undefined;
|
|
67
|
+
snapchatApiVersion?: string | undefined;
|
|
68
|
+
snapchatRateLimitPerMinute?: number | undefined;
|
|
69
|
+
snapchatAccessToken?: string | undefined;
|
|
70
|
+
snapchatAdAccountId?: string | undefined;
|
|
71
|
+
snapchatOrgId?: string | undefined;
|
|
72
|
+
snapchatAppId?: string | undefined;
|
|
73
|
+
snapchatAppSecret?: string | undefined;
|
|
74
|
+
snapchatRefreshToken?: string | undefined;
|
|
75
|
+
snapchatReportPollIntervalMs?: number | undefined;
|
|
76
|
+
snapchatReportMaxPollAttempts?: number | undefined;
|
|
77
|
+
snapchatVideoUploadPollIntervalMs?: number | undefined;
|
|
78
|
+
snapchatVideoUploadMaxPollAttempts?: number | undefined;
|
|
79
|
+
host?: string | undefined;
|
|
80
|
+
nodeEnv?: "development" | "production" | "test" | undefined;
|
|
81
|
+
mcpStatefulSessionTimeoutMs?: number | undefined;
|
|
82
|
+
mcpAuthSecretKey?: string | undefined;
|
|
83
|
+
mcpAllowedOrigins?: string | undefined;
|
|
84
|
+
logLevel?: "debug" | "info" | "notice" | "warning" | "error" | undefined;
|
|
85
|
+
mcpLogLevel?: "debug" | "info" | "notice" | "warning" | "error" | undefined;
|
|
86
|
+
otelEnabled?: boolean | undefined;
|
|
87
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
88
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
89
|
+
gcsBucketName?: string | undefined;
|
|
90
|
+
}>;
|
|
91
|
+
export type AppConfig = z.infer<typeof ConfigSchema>;
|
|
92
|
+
export declare function parseConfig(): AppConfig;
|
|
93
|
+
export declare const mcpConfig: {
|
|
94
|
+
serviceName: string;
|
|
95
|
+
port: number;
|
|
96
|
+
otelServiceName: string;
|
|
97
|
+
mcpAuthMode: "snapchat-bearer" | "jwt" | "none";
|
|
98
|
+
snapchatApiBaseUrl: string;
|
|
99
|
+
snapchatApiVersion: string;
|
|
100
|
+
snapchatRateLimitPerMinute: number;
|
|
101
|
+
snapchatReportPollIntervalMs: number;
|
|
102
|
+
snapchatReportMaxPollAttempts: number;
|
|
103
|
+
snapchatVideoUploadPollIntervalMs: number;
|
|
104
|
+
snapchatVideoUploadMaxPollAttempts: number;
|
|
105
|
+
host: string;
|
|
106
|
+
nodeEnv: "development" | "production" | "test";
|
|
107
|
+
mcpStatefulSessionTimeoutMs: number;
|
|
108
|
+
logLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
109
|
+
mcpLogLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
110
|
+
otelEnabled: boolean;
|
|
111
|
+
snapchatAccessToken?: string | undefined;
|
|
112
|
+
snapchatAdAccountId?: string | undefined;
|
|
113
|
+
snapchatOrgId?: string | undefined;
|
|
114
|
+
snapchatAppId?: string | undefined;
|
|
115
|
+
snapchatAppSecret?: string | undefined;
|
|
116
|
+
snapchatRefreshToken?: string | undefined;
|
|
117
|
+
mcpAuthSecretKey?: string | undefined;
|
|
118
|
+
mcpAllowedOrigins?: string | undefined;
|
|
119
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
120
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
121
|
+
gcsBucketName?: string | undefined;
|
|
122
|
+
};
|
|
123
|
+
export {};
|
|
124
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkChB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAErD,wBAAgB,WAAW,IAAI,SAAS,CA8CvC;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadDotEnv, BaseConfigSchema, getBaseEnvConfig, parseConfigWithSchema, getDefaultHost, } from "@cesteral/shared";
|
|
3
|
+
loadDotEnv();
|
|
4
|
+
const ConfigSchema = BaseConfigSchema.extend({
|
|
5
|
+
serviceName: z.string().default("snapchat-mcp"),
|
|
6
|
+
port: z.number().int().min(1).max(65535).default(3009),
|
|
7
|
+
otelServiceName: z.string().default("snapchat-mcp"),
|
|
8
|
+
mcpAuthMode: z.enum(["snapchat-bearer", "jwt", "none"]).default("snapchat-bearer"),
|
|
9
|
+
snapchatApiBaseUrl: z.string().url().default("https://adsapi.snapchat.com"),
|
|
10
|
+
snapchatApiVersion: z.string().default("v1"),
|
|
11
|
+
snapchatRateLimitPerMinute: z.number().default(10),
|
|
12
|
+
snapchatAccessToken: z.string().optional(),
|
|
13
|
+
snapchatAdAccountId: z.string().optional(),
|
|
14
|
+
snapchatOrgId: z.string().optional(),
|
|
15
|
+
snapchatAppId: z.string().optional(),
|
|
16
|
+
snapchatAppSecret: z.string().optional(),
|
|
17
|
+
snapchatRefreshToken: z.string().optional(),
|
|
18
|
+
snapchatReportPollIntervalMs: z.number().default(2_000),
|
|
19
|
+
snapchatReportMaxPollAttempts: z.number().default(30),
|
|
20
|
+
snapchatVideoUploadPollIntervalMs: z.number().default(20_000),
|
|
21
|
+
snapchatVideoUploadMaxPollAttempts: z.number().default(30),
|
|
22
|
+
});
|
|
23
|
+
export function parseConfig() {
|
|
24
|
+
const defaultHost = getDefaultHost();
|
|
25
|
+
const rawConfig = {
|
|
26
|
+
...getBaseEnvConfig(defaultHost),
|
|
27
|
+
serviceName: process.env.SERVICE_NAME,
|
|
28
|
+
...(process.env.SNAPCHAT_MCP_PORT ? { port: Number(process.env.SNAPCHAT_MCP_PORT) } : {}),
|
|
29
|
+
host: process.env.SNAPCHAT_MCP_HOST || defaultHost,
|
|
30
|
+
snapchatApiBaseUrl: process.env.SNAPCHAT_API_BASE_URL,
|
|
31
|
+
snapchatApiVersion: process.env.SNAPCHAT_API_VERSION,
|
|
32
|
+
snapchatRateLimitPerMinute: process.env.SNAPCHAT_RATE_LIMIT_PER_MINUTE
|
|
33
|
+
? Number(process.env.SNAPCHAT_RATE_LIMIT_PER_MINUTE)
|
|
34
|
+
: undefined,
|
|
35
|
+
snapchatAccessToken: process.env.SNAPCHAT_ACCESS_TOKEN,
|
|
36
|
+
snapchatAdAccountId: process.env.SNAPCHAT_AD_ACCOUNT_ID,
|
|
37
|
+
snapchatOrgId: process.env.SNAPCHAT_ORG_ID,
|
|
38
|
+
snapchatAppId: process.env.SNAPCHAT_APP_ID,
|
|
39
|
+
snapchatAppSecret: process.env.SNAPCHAT_APP_SECRET,
|
|
40
|
+
snapchatRefreshToken: process.env.SNAPCHAT_REFRESH_TOKEN,
|
|
41
|
+
snapchatReportPollIntervalMs: process.env.SNAPCHAT_REPORT_POLL_INTERVAL_MS
|
|
42
|
+
? Number(process.env.SNAPCHAT_REPORT_POLL_INTERVAL_MS)
|
|
43
|
+
: undefined,
|
|
44
|
+
snapchatReportMaxPollAttempts: process.env.SNAPCHAT_REPORT_MAX_POLL_ATTEMPTS
|
|
45
|
+
? Number(process.env.SNAPCHAT_REPORT_MAX_POLL_ATTEMPTS)
|
|
46
|
+
: undefined,
|
|
47
|
+
snapchatVideoUploadPollIntervalMs: process.env.SNAPCHAT_VIDEO_UPLOAD_POLL_INTERVAL_MS
|
|
48
|
+
? Number(process.env.SNAPCHAT_VIDEO_UPLOAD_POLL_INTERVAL_MS)
|
|
49
|
+
: undefined,
|
|
50
|
+
snapchatVideoUploadMaxPollAttempts: process.env.SNAPCHAT_VIDEO_UPLOAD_MAX_POLL_ATTEMPTS
|
|
51
|
+
? Number(process.env.SNAPCHAT_VIDEO_UPLOAD_MAX_POLL_ATTEMPTS)
|
|
52
|
+
: undefined,
|
|
53
|
+
};
|
|
54
|
+
return parseConfigWithSchema(ConfigSchema, rawConfig);
|
|
55
|
+
}
|
|
56
|
+
export const mcpConfig = parseConfig();
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mcpConfig } from "./config/index.js";
|
|
3
|
+
import { createMcpServer, runStdioServer } from "./mcp-server/server.js";
|
|
4
|
+
import { startHttpServer } from "./mcp-server/transports/streamable-http-transport.js";
|
|
5
|
+
import { initializeOpenTelemetry, otelLogMixin } from "@cesteral/shared";
|
|
6
|
+
import { SnapchatAccessTokenAdapter } from "./auth/snapchat-auth-adapter.js";
|
|
7
|
+
import { detectTransportMode, createServerLogger, bootstrapMcpServer } from "@cesteral/shared";
|
|
8
|
+
import { createSessionServices, sessionServiceStore } from "./services/session-services.js";
|
|
9
|
+
import { rateLimiter } from "./utils/platform.js";
|
|
10
|
+
const transportMode = detectTransportMode();
|
|
11
|
+
const logger = createServerLogger("snapchat-mcp", transportMode, otelLogMixin());
|
|
12
|
+
async function setupStdioCredentials(sessionId) {
|
|
13
|
+
const accessToken = mcpConfig.snapchatAccessToken;
|
|
14
|
+
const adAccountId = mcpConfig.snapchatAdAccountId;
|
|
15
|
+
if (!accessToken || !adAccountId) {
|
|
16
|
+
logger.warn("No Snapchat credentials found in env vars. " +
|
|
17
|
+
"Set SNAPCHAT_ACCESS_TOKEN and SNAPCHAT_AD_ACCOUNT_ID for stdio mode.");
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const authAdapter = new SnapchatAccessTokenAdapter(accessToken, adAccountId, mcpConfig.snapchatApiBaseUrl, mcpConfig.snapchatOrgId ?? "");
|
|
21
|
+
await authAdapter.validate();
|
|
22
|
+
const services = createSessionServices(authAdapter, {
|
|
23
|
+
baseUrl: mcpConfig.snapchatApiBaseUrl,
|
|
24
|
+
reportPollIntervalMs: mcpConfig.snapchatReportPollIntervalMs,
|
|
25
|
+
reportMaxPollAttempts: mcpConfig.snapchatReportMaxPollAttempts,
|
|
26
|
+
}, logger, rateLimiter);
|
|
27
|
+
sessionServiceStore.set(sessionId, services);
|
|
28
|
+
logger.info("Stdio session services created successfully");
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
bootstrapMcpServer({
|
|
32
|
+
serviceName: "snapchat-mcp",
|
|
33
|
+
config: mcpConfig,
|
|
34
|
+
logger,
|
|
35
|
+
transportMode,
|
|
36
|
+
initOtel: initializeOpenTelemetry,
|
|
37
|
+
setupStdioSession: setupStdioCredentials,
|
|
38
|
+
createMcpServer,
|
|
39
|
+
runStdio: runStdioServer,
|
|
40
|
+
startHttp: startHttpServer,
|
|
41
|
+
onShutdown: () => rateLimiter.destroy(),
|
|
42
|
+
}).catch((err) => {
|
|
43
|
+
logger.fatal({ err }, "Failed to start snapchat-mcp");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,sDAAsD,CAAC;AACvF,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,MAAM,aAAa,GAAG,mBAAmB,EAAE,CAAC;AAC5C,MAAM,MAAM,GAAG,kBAAkB,CAAC,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC;AAMjF,KAAK,UAAU,qBAAqB,CAAC,SAAiB;IACpD,MAAM,WAAW,GAAG,SAAS,CAAC,mBAAmB,CAAC;IAClD,MAAM,WAAW,GAAG,SAAS,CAAC,mBAAmB,CAAC;IAElD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CACT,6CAA6C;YAC3C,sEAAsE,CACzE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,0BAA0B,CAChD,WAAW,EACX,WAAW,EACX,SAAS,CAAC,kBAAkB,EAC5B,SAAS,CAAC,aAAa,IAAI,EAAE,CAC9B,CAAC;IAGF,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;IAE7B,MAAM,QAAQ,GAAG,qBAAqB,CACpC,WAAW,EACX;QACE,OAAO,EAAE,SAAS,CAAC,kBAAkB;QACrC,oBAAoB,EAAE,SAAS,CAAC,4BAA4B;QAC5D,qBAAqB,EAAE,SAAS,CAAC,6BAA6B;KAC/D,EACD,MAAM,EACN,WAAW,CACZ,CAAC;IAEF,mBAAmB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kBAAkB,CAAC;IACjB,WAAW,EAAE,cAAc;IAC3B,MAAM,EAAE,SAAS;IACjB,MAAM;IACN,aAAa;IACb,QAAQ,EAAE,uBAAuB;IACjC,iBAAiB,EAAE,qBAAqB;IACxC,eAAe;IACf,QAAQ,EAAE,cAAc;IACxB,SAAS,EAAE,eAAe;IAC1B,UAAU,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE;CACxC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACf,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,8BAA8B,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Prompt } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare const bulkOperationsWorkflowPrompt: Prompt;
|
|
3
|
+
export declare function getBulkOperationsWorkflowMessage(args?: Record<string, string>): string;
|
|
4
|
+
//# sourceMappingURL=bulk-operations-workflow.prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-operations-workflow.prompt.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAEjE,eAAO,MAAM,4BAA4B,EAAE,MAgB1C,CAAC;AAEF,wBAAgB,gCAAgC,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CA8GtF"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const bulkOperationsWorkflowPrompt = {
|
|
2
|
+
name: "snapchat_bulk_operations_workflow",
|
|
3
|
+
description: "Guide for performing bulk create, update, and status operations on Snapchat Ads entities",
|
|
4
|
+
arguments: [
|
|
5
|
+
{
|
|
6
|
+
name: "adAccountId",
|
|
7
|
+
description: "Snapchat Advertiser ID",
|
|
8
|
+
required: true,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "entityType",
|
|
12
|
+
description: "Entity type to operate on (campaign, adGroup, ad)",
|
|
13
|
+
required: false,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
export function getBulkOperationsWorkflowMessage(args) {
|
|
18
|
+
const adAccountId = args?.adAccountId || "{adAccountId}";
|
|
19
|
+
const entityType = args?.entityType || "campaign";
|
|
20
|
+
return `# Snapchat Bulk Operations Workflow
|
|
21
|
+
|
|
22
|
+
## Advertiser ID: \`${adAccountId}\`
|
|
23
|
+
## Entity Type: \`${entityType}\`
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Option 1: Bulk Status Update (most common)
|
|
28
|
+
|
|
29
|
+
Pause, enable, or delete multiple entities in one call:
|
|
30
|
+
|
|
31
|
+
\`\`\`json
|
|
32
|
+
snapchat_bulk_update_status({
|
|
33
|
+
"entityType": "${entityType}",
|
|
34
|
+
"adAccountId": "${adAccountId}",
|
|
35
|
+
"entityIds": ["ID_1", "ID_2", "ID_3"],
|
|
36
|
+
"operationStatus": "DISABLE"
|
|
37
|
+
})
|
|
38
|
+
\`\`\`
|
|
39
|
+
|
|
40
|
+
**Operation status values:**
|
|
41
|
+
- \`ENABLE\` — Activate entities
|
|
42
|
+
- \`DISABLE\` — Pause entities
|
|
43
|
+
- \`DELETE\` — Permanently delete (irreversible!)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Option 2: Bulk Create Entities (up to 50)
|
|
48
|
+
|
|
49
|
+
Create multiple entities of the same type in one call:
|
|
50
|
+
|
|
51
|
+
\`\`\`json
|
|
52
|
+
snapchat_bulk_create_entities({
|
|
53
|
+
"entityType": "${entityType}",
|
|
54
|
+
"adAccountId": "${adAccountId}",
|
|
55
|
+
"items": [
|
|
56
|
+
{
|
|
57
|
+
"campaign_name": "Campaign A",
|
|
58
|
+
"objective_type": "TRAFFIC",
|
|
59
|
+
"budget_mode": "BUDGET_MODE_DAY",
|
|
60
|
+
"budget": 100
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"campaign_name": "Campaign B",
|
|
64
|
+
"objective_type": "CONVERSIONS",
|
|
65
|
+
"budget_mode": "BUDGET_MODE_DAY",
|
|
66
|
+
"budget": 200
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
})
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Option 3: Bulk Update Entities (up to 50)
|
|
75
|
+
|
|
76
|
+
Update specific fields on multiple entities:
|
|
77
|
+
|
|
78
|
+
\`\`\`json
|
|
79
|
+
snapchat_bulk_update_entities({
|
|
80
|
+
"entityType": "${entityType}",
|
|
81
|
+
"adAccountId": "${adAccountId}",
|
|
82
|
+
"items": [
|
|
83
|
+
{ "entityId": "ID_1", "data": { "budget": 150 } },
|
|
84
|
+
{ "entityId": "ID_2", "data": { "budget": 250 } }
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Option 4: Bulk Bid Adjustment (ad groups only)
|
|
92
|
+
|
|
93
|
+
Safe read-modify-write bid adjustment:
|
|
94
|
+
|
|
95
|
+
\`\`\`json
|
|
96
|
+
snapchat_adjust_bids({
|
|
97
|
+
"adAccountId": "${adAccountId}",
|
|
98
|
+
"adjustments": [
|
|
99
|
+
{ "adGroupId": "ADGROUP_ID_1", "bidPrice": 1.5 },
|
|
100
|
+
{ "adGroupId": "ADGROUP_ID_2", "bidPrice": 2.0 }
|
|
101
|
+
],
|
|
102
|
+
"reason": "Increase bids to improve delivery"
|
|
103
|
+
})
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Tips for Bulk Operations
|
|
109
|
+
|
|
110
|
+
1. **List first**: Use \`snapchat_list_entities\` to get entity IDs before bulk operations
|
|
111
|
+
2. **Validate first**: Use \`snapchat_validate_entity\` to check payloads before bulk create
|
|
112
|
+
3. **Status update is batched**: Snapchat accepts IDs array in one API call
|
|
113
|
+
4. **Create/Update is sequential**: Processed concurrently (5 at a time) by the MCP tool
|
|
114
|
+
5. **Max 50 items**: Per bulk create/update call (more = multiple calls)
|
|
115
|
+
6. **Error handling**: Partial failures are reported — some may succeed while others fail
|
|
116
|
+
|
|
117
|
+
## Workflow: Pause all campaigns → Adjust → Re-enable
|
|
118
|
+
|
|
119
|
+
\`\`\`
|
|
120
|
+
1. snapchat_list_entities (get campaign IDs)
|
|
121
|
+
2. snapchat_bulk_update_status (DISABLE all)
|
|
122
|
+
3. snapchat_bulk_update_entities (adjust budgets/settings)
|
|
123
|
+
4. snapchat_bulk_update_status (ENABLE selected)
|
|
124
|
+
\`\`\`
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=bulk-operations-workflow.prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-operations-workflow.prompt.js","sourceRoot":"","sources":["../../../../src/mcp-server/prompts/definitions/bulk-operations-workflow.prompt.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,4BAA4B,GAAW;IAClD,IAAI,EAAE,mCAAmC;IACzC,WAAW,EACT,0FAA0F;IAC5F,SAAS,EAAE;QACT;YACE,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,wBAAwB;YACrC,QAAQ,EAAE,IAAI;SACf;QACD;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,mDAAmD;YAChE,QAAQ,EAAE,KAAK;SAChB;KACF;CACF,CAAC;AAEF,MAAM,UAAU,gCAAgC,CAAC,IAA6B;IAC5E,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,eAAe,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,UAAU,CAAC;IAElD,OAAO;;sBAEa,WAAW;oBACb,UAAU;;;;;;;;;;mBAUX,UAAU;oBACT,WAAW;;;;;;;;;;;;;;;;;;;mBAmBZ,UAAU;oBACT,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;mBA0BZ,UAAU;oBACT,WAAW;;;;;;;;;;;;;;;;oBAgBX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4B9B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Prompt } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare const campaignSetupWorkflowPrompt: Prompt;
|
|
3
|
+
export declare function getCampaignSetupWorkflowMessage(args?: Record<string, string>): string;
|
|
4
|
+
//# sourceMappingURL=campaign-setup-workflow.prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"campaign-setup-workflow.prompt.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/prompts/definitions/campaign-setup-workflow.prompt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAEjE,eAAO,MAAM,2BAA2B,EAAE,MAgBzC,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAwGrF"}
|