@cesteral/tiktok-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 +347 -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/tiktok-auth-adapter.d.ts +40 -0
- package/dist/auth/tiktok-auth-adapter.d.ts.map +1 -0
- package/dist/auth/tiktok-auth-adapter.js +126 -0
- package/dist/auth/tiktok-auth-adapter.js.map +1 -0
- package/dist/auth/tiktok-auth-strategy.d.ts +14 -0
- package/dist/auth/tiktok-auth-strategy.d.ts.map +1 -0
- package/dist/auth/tiktok-auth-strategy.js +54 -0
- package/dist/auth/tiktok-auth-strategy.js.map +1 -0
- package/dist/config/index.d.ts +120 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +55 -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 +47 -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 +104 -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 +200 -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 +93 -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 +97 -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 +182 -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 +147 -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 +135 -0
- package/dist/mcp-server/resources/definitions/entity-schemas.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/index.d.ts +8 -0
- package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/index.js +79 -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 +165 -0
- package/dist/mcp-server/resources/definitions/reporting-reference.resource.js.map +1 -0
- package/dist/mcp-server/resources/definitions/targeting-reference.resource.d.ts +3 -0
- package/dist/mcp-server/resources/definitions/targeting-reference.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/targeting-reference.resource.js +134 -0
- package/dist/mcp-server/resources/definitions/targeting-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 +151 -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 +112 -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 +193 -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 +130 -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 +153 -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 +137 -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 +115 -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 +103 -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 +105 -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 +85 -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 +89 -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 +74 -0
- package/dist/mcp-server/tools/definitions/get-ad-preview.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ad-previews.tool.d.ts +89 -0
- package/dist/mcp-server/tools/definitions/get-ad-previews.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-ad-previews.tool.js +83 -0
- package/dist/mcp-server/tools/definitions/get-ad-previews.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-audience-estimate.tool.d.ts +85 -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 +88 -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 +174 -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 +303 -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 +178 -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 +127 -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 +120 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +78 -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 +58 -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 +167 -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 +114 -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 +131 -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 +123 -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 +153 -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 +117 -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 +111 -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 +89 -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 +87 -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 +82 -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 +88 -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 +113 -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 +197 -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 +237 -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 +22 -0
- package/dist/mcp-server/tools/utils/entity-mapping.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/entity-mapping.js +121 -0
- package/dist/mcp-server/tools/utils/entity-mapping.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 +59 -0
- package/dist/mcp-server/transports/streamable-http-transport.d.ts.map +1 -0
- package/dist/mcp-server/transports/streamable-http-transport.js +107 -0
- package/dist/mcp-server/transports/streamable-http-transport.js.map +1 -0
- package/dist/services/session-services.d.ts +21 -0
- package/dist/services/session-services.d.ts.map +1 -0
- package/dist/services/session-services.js +25 -0
- package/dist/services/session-services.js.map +1 -0
- package/dist/services/tiktok/tiktok-http-client.d.ts +19 -0
- package/dist/services/tiktok/tiktok-http-client.d.ts.map +1 -0
- package/dist/services/tiktok/tiktok-http-client.js +184 -0
- package/dist/services/tiktok/tiktok-http-client.js.map +1 -0
- package/dist/services/tiktok/tiktok-reporting-service.d.ts +62 -0
- package/dist/services/tiktok/tiktok-reporting-service.d.ts.map +1 -0
- package/dist/services/tiktok/tiktok-reporting-service.js +129 -0
- package/dist/services/tiktok/tiktok-reporting-service.js.map +1 -0
- package/dist/services/tiktok/tiktok-service.d.ts +86 -0
- package/dist/services/tiktok/tiktok-service.d.ts.map +1 -0
- package/dist/services/tiktok/tiktok-service.js +217 -0
- package/dist/services/tiktok/tiktok-service.js.map +1 -0
- package/dist/services/tiktok/types.d.ts +161 -0
- package/dist/services/tiktok/types.d.ts.map +1 -0
- package/dist/services/tiktok/types.js +31 -0
- package/dist/services/tiktok/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,126 @@
|
|
|
1
|
+
import { extractHeader, fetchWithTimeout, fingerprintCredentials, JsonRpcErrorCode, McpError, OAuth2RefreshAdapterBase, } from "@cesteral/shared";
|
|
2
|
+
async function fetchTikTokUserId(token, baseUrl, apiVersion) {
|
|
3
|
+
const response = await fetchWithTimeout(`${baseUrl}/open_api/${apiVersion}/user/info/`, 10_000, undefined, {
|
|
4
|
+
method: "GET",
|
|
5
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
6
|
+
});
|
|
7
|
+
if (!response.ok) {
|
|
8
|
+
const errorBody = await response.text().catch(() => "");
|
|
9
|
+
throw new McpError(JsonRpcErrorCode.Unauthorized, `TikTok token validation HTTP error: ${response.status} ${response.statusText}. ${errorBody.substring(0, 200)}`);
|
|
10
|
+
}
|
|
11
|
+
const data = (await response.json());
|
|
12
|
+
if (data.code !== 0) {
|
|
13
|
+
throw new McpError(JsonRpcErrorCode.Unauthorized, `TikTok token validation failed: code=${data.code} message=${data.message}`);
|
|
14
|
+
}
|
|
15
|
+
return data.data?.display_name ?? data.data?.email ?? "unknown";
|
|
16
|
+
}
|
|
17
|
+
export class TikTokAccessTokenAdapter {
|
|
18
|
+
accessToken;
|
|
19
|
+
_advertiserId;
|
|
20
|
+
baseUrl;
|
|
21
|
+
apiVersion;
|
|
22
|
+
validated = false;
|
|
23
|
+
_userId = "";
|
|
24
|
+
constructor(accessToken, _advertiserId, baseUrl = "https://business-api.tiktok.com", apiVersion = "v1.3") {
|
|
25
|
+
this.accessToken = accessToken;
|
|
26
|
+
this._advertiserId = _advertiserId;
|
|
27
|
+
this.baseUrl = baseUrl;
|
|
28
|
+
this.apiVersion = apiVersion;
|
|
29
|
+
}
|
|
30
|
+
get userId() {
|
|
31
|
+
return this._userId;
|
|
32
|
+
}
|
|
33
|
+
get advertiserId() {
|
|
34
|
+
return this._advertiserId;
|
|
35
|
+
}
|
|
36
|
+
async getAccessToken() {
|
|
37
|
+
return this.accessToken;
|
|
38
|
+
}
|
|
39
|
+
async validate() {
|
|
40
|
+
if (this.validated)
|
|
41
|
+
return;
|
|
42
|
+
this._userId = await fetchTikTokUserId(this.accessToken, this.baseUrl, this.apiVersion);
|
|
43
|
+
this.validated = true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export class TikTokRefreshTokenAdapter extends OAuth2RefreshAdapterBase {
|
|
47
|
+
_advertiserId;
|
|
48
|
+
baseUrl;
|
|
49
|
+
apiVersion;
|
|
50
|
+
_userId = "";
|
|
51
|
+
constructor(credentials, _advertiserId, baseUrl = "https://business-api.tiktok.com", apiVersion = "v1.3") {
|
|
52
|
+
super({
|
|
53
|
+
platformName: "TikTok",
|
|
54
|
+
credentials,
|
|
55
|
+
requestToken: async (refreshToken) => {
|
|
56
|
+
const response = await fetchWithTimeout(`${baseUrl}/open_api/${apiVersion}/oauth2/access_token/`, 10_000, undefined, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: { "Content-Type": "application/json" },
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
app_id: credentials.appId,
|
|
61
|
+
secret: credentials.appSecret,
|
|
62
|
+
grant_type: "refresh_token",
|
|
63
|
+
refresh_token: refreshToken,
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const errorBody = await response.text().catch(() => "");
|
|
68
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `TikTok token refresh failed: ${response.status} ${response.statusText}. ${errorBody.substring(0, 200)}`);
|
|
69
|
+
}
|
|
70
|
+
const data = (await response.json());
|
|
71
|
+
if (data.code !== 0 || !data.data?.access_token) {
|
|
72
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `TikTok token refresh failed: code=${data.code} message=${data.message}`);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
access_token: data.data.access_token,
|
|
76
|
+
expires_in: data.data.expires_in,
|
|
77
|
+
refresh_token: data.data.refresh_token,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
this._advertiserId = _advertiserId;
|
|
82
|
+
this.baseUrl = baseUrl;
|
|
83
|
+
this.apiVersion = apiVersion;
|
|
84
|
+
}
|
|
85
|
+
get userId() {
|
|
86
|
+
return this._userId;
|
|
87
|
+
}
|
|
88
|
+
get advertiserId() {
|
|
89
|
+
return this._advertiserId;
|
|
90
|
+
}
|
|
91
|
+
async validate() {
|
|
92
|
+
const token = await this.getAccessToken();
|
|
93
|
+
this._userId = await fetchTikTokUserId(token, this.baseUrl, this.apiVersion);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export function parseTikTokRefreshCredentialsFromHeaders(headers) {
|
|
97
|
+
const appId = extractHeader(headers, "x-tiktok-app-id");
|
|
98
|
+
const appSecret = extractHeader(headers, "x-tiktok-app-secret");
|
|
99
|
+
const refreshToken = extractHeader(headers, "x-tiktok-refresh-token");
|
|
100
|
+
if (!appId || !appSecret || !refreshToken) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
return { appId, appSecret, refreshToken };
|
|
104
|
+
}
|
|
105
|
+
export function parseTikTokTokenFromHeaders(headers) {
|
|
106
|
+
const authHeader = extractHeader(headers, "authorization");
|
|
107
|
+
if (!authHeader) {
|
|
108
|
+
throw new Error("Missing required Authorization header");
|
|
109
|
+
}
|
|
110
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
111
|
+
if (!match || !match[1]) {
|
|
112
|
+
throw new Error("Authorization header must use Bearer scheme");
|
|
113
|
+
}
|
|
114
|
+
return match[1];
|
|
115
|
+
}
|
|
116
|
+
export function getTikTokAdvertiserIdFromHeaders(headers) {
|
|
117
|
+
const advertiserId = extractHeader(headers, "x-tiktok-advertiser-id");
|
|
118
|
+
if (!advertiserId) {
|
|
119
|
+
throw new Error("Missing required X-TikTok-Advertiser-Id header");
|
|
120
|
+
}
|
|
121
|
+
return advertiserId;
|
|
122
|
+
}
|
|
123
|
+
export function getTikTokCredentialFingerprint(accessToken, advertiserId) {
|
|
124
|
+
return fingerprintCredentials(accessToken, advertiserId);
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=tiktok-auth-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiktok-auth-adapter.js","sourceRoot":"","sources":["../../src/auth/tiktok-auth-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Logger } from "pino";
|
|
2
|
+
import { BearerAuthStrategyBase, type BearerAdapterResult } from "@cesteral/shared";
|
|
3
|
+
export declare class TikTokBearerAuthStrategy extends BearerAuthStrategyBase {
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly apiVersion;
|
|
6
|
+
protected readonly authType = "tiktok-bearer";
|
|
7
|
+
protected readonly platformName = "TikTok";
|
|
8
|
+
constructor(baseUrl: string, logger?: Logger, apiVersion?: string);
|
|
9
|
+
protected resolveRefreshBranch(headers: Record<string, string | string[] | undefined>): Promise<BearerAdapterResult | null>;
|
|
10
|
+
protected resolveAccessBranch(headers: Record<string, string | string[] | undefined>): Promise<BearerAdapterResult>;
|
|
11
|
+
protected getRefreshFingerprint(headers: Record<string, string | string[] | undefined>): string | undefined;
|
|
12
|
+
protected getTokenFingerprint(headers: Record<string, string | string[] | undefined>): string;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=tiktok-auth-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiktok-auth-strategy.d.ts","sourceRoot":"","sources":["../../src/auth/tiktok-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;AAUpF,qBAAa,wBAAyB,SAAQ,sBAAsB;IAKhE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAExB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAN7B,SAAS,CAAC,QAAQ,CAAC,QAAQ,mBAAmB;IAC9C,SAAS,CAAC,QAAQ,CAAC,YAAY,YAAY;gBAGxB,OAAO,EAAE,MAAM,EAChC,MAAM,CAAC,EAAE,MAAM,EACE,UAAU,GAAE,MAAe;cAK9B,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;cAuBtB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,OAAO,CAAC,mBAAmB,CAAC;IAoB/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 { TikTokAccessTokenAdapter, TikTokRefreshTokenAdapter, parseTikTokTokenFromHeaders, parseTikTokRefreshCredentialsFromHeaders, getTikTokAdvertiserIdFromHeaders, getTikTokCredentialFingerprint, } from "./tiktok-auth-adapter.js";
|
|
3
|
+
export class TikTokBearerAuthStrategy extends BearerAuthStrategyBase {
|
|
4
|
+
baseUrl;
|
|
5
|
+
apiVersion;
|
|
6
|
+
authType = "tiktok-bearer";
|
|
7
|
+
platformName = "TikTok";
|
|
8
|
+
constructor(baseUrl, logger, apiVersion = "v1.3") {
|
|
9
|
+
super(logger);
|
|
10
|
+
this.baseUrl = baseUrl;
|
|
11
|
+
this.apiVersion = apiVersion;
|
|
12
|
+
}
|
|
13
|
+
async resolveRefreshBranch(headers) {
|
|
14
|
+
const refreshCreds = parseTikTokRefreshCredentialsFromHeaders(headers);
|
|
15
|
+
if (!refreshCreds)
|
|
16
|
+
return null;
|
|
17
|
+
const advertiserId = getTikTokAdvertiserIdFromHeaders(headers);
|
|
18
|
+
const adapter = new TikTokRefreshTokenAdapter(refreshCreds, advertiserId, this.baseUrl, this.apiVersion);
|
|
19
|
+
await adapter.validate();
|
|
20
|
+
return {
|
|
21
|
+
adapter,
|
|
22
|
+
fingerprint: getTikTokCredentialFingerprint(refreshCreds.appId, advertiserId),
|
|
23
|
+
userId: adapter.userId,
|
|
24
|
+
authFlow: "refresh-token",
|
|
25
|
+
logContext: { advertiserId },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async resolveAccessBranch(headers) {
|
|
29
|
+
const token = parseTikTokTokenFromHeaders(headers);
|
|
30
|
+
const advertiserId = getTikTokAdvertiserIdFromHeaders(headers);
|
|
31
|
+
const adapter = new TikTokAccessTokenAdapter(token, advertiserId, this.baseUrl, this.apiVersion);
|
|
32
|
+
await adapter.validate();
|
|
33
|
+
return {
|
|
34
|
+
adapter,
|
|
35
|
+
fingerprint: getTikTokCredentialFingerprint(token, advertiserId),
|
|
36
|
+
userId: adapter.userId,
|
|
37
|
+
authFlow: "static-token",
|
|
38
|
+
logContext: { advertiserId },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
getRefreshFingerprint(headers) {
|
|
42
|
+
const refreshCreds = parseTikTokRefreshCredentialsFromHeaders(headers);
|
|
43
|
+
if (!refreshCreds)
|
|
44
|
+
return undefined;
|
|
45
|
+
const advertiserId = getTikTokAdvertiserIdFromHeaders(headers);
|
|
46
|
+
return getTikTokCredentialFingerprint(refreshCreds.appId, advertiserId);
|
|
47
|
+
}
|
|
48
|
+
getTokenFingerprint(headers) {
|
|
49
|
+
const token = parseTikTokTokenFromHeaders(headers);
|
|
50
|
+
const advertiserId = getTikTokAdvertiserIdFromHeaders(headers);
|
|
51
|
+
return getTikTokCredentialFingerprint(token, advertiserId);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=tiktok-auth-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tiktok-auth-strategy.js","sourceRoot":"","sources":["../../src/auth/tiktok-auth-strategy.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,sBAAsB,EAA4B,MAAM,kBAAkB,CAAC;AACpF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,wCAAwC,EACxC,gCAAgC,EAChC,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAElC,MAAM,OAAO,wBAAyB,SAAQ,sBAAsB;IAK/C;IAEA;IANA,QAAQ,GAAG,eAAe,CAAC;IAC3B,YAAY,GAAG,QAAQ,CAAC;IAE3C,YACmB,OAAe,EAChC,MAAe,EACE,aAAqB,MAAM;QAE5C,KAAK,CAAC,MAAM,CAAC,CAAC;QAJG,YAAO,GAAP,OAAO,CAAQ;QAEf,eAAU,GAAV,UAAU,CAAiB;IAG9C,CAAC;IAES,KAAK,CAAC,oBAAoB,CAClC,OAAsD;QAEtD,MAAM,YAAY,GAAG,wCAAwC,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,YAAY,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAC3C,YAAY,EACZ,YAAY,EACZ,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,UAAU,CAChB,CAAC;QACF,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzB,OAAO;YACL,OAAO;YAEP,WAAW,EAAE,8BAA8B,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC;YAC7E,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,eAAe;YACzB,UAAU,EAAE,EAAE,YAAY,EAAE;SAC7B,CAAC;IACJ,CAAC;IAES,KAAK,CAAC,mBAAmB,CACjC,OAAsD;QAEtD,MAAM,KAAK,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,IAAI,wBAAwB,CAC1C,KAAK,EACL,YAAY,EACZ,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,UAAU,CAChB,CAAC;QACF,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEzB,OAAO;YACL,OAAO;YACP,WAAW,EAAE,8BAA8B,CAAC,KAAK,EAAE,YAAY,CAAC;YAChE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,EAAE,YAAY,EAAE;SAC7B,CAAC;IACJ,CAAC;IAES,qBAAqB,CAC7B,OAAsD;QAEtD,MAAM,YAAY,GAAG,wCAAwC,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACpC,MAAM,YAAY,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;QAC/D,OAAO,8BAA8B,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC1E,CAAC;IAES,mBAAmB,CAAC,OAAsD;QAClF,MAAM,KAAK,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,YAAY,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;QAC/D,OAAO,8BAA8B,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -0,0 +1,120 @@
|
|
|
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<["tiktok-bearer", "jwt", "none"]>>;
|
|
19
|
+
tiktokApiBaseUrl: z.ZodDefault<z.ZodString>;
|
|
20
|
+
tiktokApiVersion: z.ZodDefault<z.ZodString>;
|
|
21
|
+
tiktokRateLimitPerMinute: z.ZodDefault<z.ZodNumber>;
|
|
22
|
+
tiktokAccessToken: z.ZodOptional<z.ZodString>;
|
|
23
|
+
tiktokAdvertiserId: z.ZodOptional<z.ZodString>;
|
|
24
|
+
tiktokAppId: z.ZodOptional<z.ZodString>;
|
|
25
|
+
tiktokAppSecret: z.ZodOptional<z.ZodString>;
|
|
26
|
+
tiktokRefreshToken: z.ZodOptional<z.ZodString>;
|
|
27
|
+
tiktokReportPollIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
28
|
+
tiktokReportMaxPollAttempts: z.ZodDefault<z.ZodNumber>;
|
|
29
|
+
tiktokVideoUploadPollIntervalMs: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
tiktokVideoUploadMaxPollAttempts: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
}, "strip", z.ZodTypeAny, {
|
|
32
|
+
serviceName: string;
|
|
33
|
+
port: number;
|
|
34
|
+
otelServiceName: string;
|
|
35
|
+
mcpAuthMode: "tiktok-bearer" | "jwt" | "none";
|
|
36
|
+
tiktokApiBaseUrl: string;
|
|
37
|
+
tiktokApiVersion: string;
|
|
38
|
+
tiktokRateLimitPerMinute: number;
|
|
39
|
+
tiktokReportPollIntervalMs: number;
|
|
40
|
+
tiktokReportMaxPollAttempts: number;
|
|
41
|
+
tiktokVideoUploadPollIntervalMs: number;
|
|
42
|
+
tiktokVideoUploadMaxPollAttempts: number;
|
|
43
|
+
host: string;
|
|
44
|
+
nodeEnv: "development" | "production" | "test";
|
|
45
|
+
mcpStatefulSessionTimeoutMs: number;
|
|
46
|
+
logLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
47
|
+
mcpLogLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
48
|
+
otelEnabled: boolean;
|
|
49
|
+
tiktokAccessToken?: string | undefined;
|
|
50
|
+
tiktokAdvertiserId?: string | undefined;
|
|
51
|
+
tiktokAppId?: string | undefined;
|
|
52
|
+
tiktokAppSecret?: string | undefined;
|
|
53
|
+
tiktokRefreshToken?: string | undefined;
|
|
54
|
+
mcpAuthSecretKey?: string | undefined;
|
|
55
|
+
mcpAllowedOrigins?: string | undefined;
|
|
56
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
57
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
58
|
+
gcsBucketName?: string | undefined;
|
|
59
|
+
}, {
|
|
60
|
+
serviceName?: string | undefined;
|
|
61
|
+
port?: number | undefined;
|
|
62
|
+
otelServiceName?: string | undefined;
|
|
63
|
+
mcpAuthMode?: "tiktok-bearer" | "jwt" | "none" | undefined;
|
|
64
|
+
tiktokApiBaseUrl?: string | undefined;
|
|
65
|
+
tiktokApiVersion?: string | undefined;
|
|
66
|
+
tiktokRateLimitPerMinute?: number | undefined;
|
|
67
|
+
tiktokAccessToken?: string | undefined;
|
|
68
|
+
tiktokAdvertiserId?: string | undefined;
|
|
69
|
+
tiktokAppId?: string | undefined;
|
|
70
|
+
tiktokAppSecret?: string | undefined;
|
|
71
|
+
tiktokRefreshToken?: string | undefined;
|
|
72
|
+
tiktokReportPollIntervalMs?: number | undefined;
|
|
73
|
+
tiktokReportMaxPollAttempts?: number | undefined;
|
|
74
|
+
tiktokVideoUploadPollIntervalMs?: number | undefined;
|
|
75
|
+
tiktokVideoUploadMaxPollAttempts?: number | undefined;
|
|
76
|
+
host?: string | undefined;
|
|
77
|
+
nodeEnv?: "development" | "production" | "test" | undefined;
|
|
78
|
+
mcpStatefulSessionTimeoutMs?: number | undefined;
|
|
79
|
+
mcpAuthSecretKey?: string | undefined;
|
|
80
|
+
mcpAllowedOrigins?: string | undefined;
|
|
81
|
+
logLevel?: "debug" | "info" | "notice" | "warning" | "error" | undefined;
|
|
82
|
+
mcpLogLevel?: "debug" | "info" | "notice" | "warning" | "error" | undefined;
|
|
83
|
+
otelEnabled?: boolean | undefined;
|
|
84
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
85
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
86
|
+
gcsBucketName?: string | undefined;
|
|
87
|
+
}>;
|
|
88
|
+
export type AppConfig = z.infer<typeof ConfigSchema>;
|
|
89
|
+
export declare function parseConfig(): AppConfig;
|
|
90
|
+
export declare const mcpConfig: {
|
|
91
|
+
serviceName: string;
|
|
92
|
+
port: number;
|
|
93
|
+
otelServiceName: string;
|
|
94
|
+
mcpAuthMode: "tiktok-bearer" | "jwt" | "none";
|
|
95
|
+
tiktokApiBaseUrl: string;
|
|
96
|
+
tiktokApiVersion: string;
|
|
97
|
+
tiktokRateLimitPerMinute: number;
|
|
98
|
+
tiktokReportPollIntervalMs: number;
|
|
99
|
+
tiktokReportMaxPollAttempts: number;
|
|
100
|
+
tiktokVideoUploadPollIntervalMs: number;
|
|
101
|
+
tiktokVideoUploadMaxPollAttempts: number;
|
|
102
|
+
host: string;
|
|
103
|
+
nodeEnv: "development" | "production" | "test";
|
|
104
|
+
mcpStatefulSessionTimeoutMs: number;
|
|
105
|
+
logLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
106
|
+
mcpLogLevel: "debug" | "info" | "notice" | "warning" | "error";
|
|
107
|
+
otelEnabled: boolean;
|
|
108
|
+
tiktokAccessToken?: string | undefined;
|
|
109
|
+
tiktokAdvertiserId?: string | undefined;
|
|
110
|
+
tiktokAppId?: string | undefined;
|
|
111
|
+
tiktokAppSecret?: string | undefined;
|
|
112
|
+
tiktokRefreshToken?: string | undefined;
|
|
113
|
+
mcpAuthSecretKey?: string | undefined;
|
|
114
|
+
mcpAllowedOrigins?: string | undefined;
|
|
115
|
+
otelExporterOtlpTracesEndpoint?: string | undefined;
|
|
116
|
+
otelExporterOtlpMetricsEndpoint?: string | undefined;
|
|
117
|
+
gcsBucketName?: string | undefined;
|
|
118
|
+
};
|
|
119
|
+
export {};
|
|
120
|
+
//# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiChB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAErD,wBAAgB,WAAW,IAAI,SAAS,CA6CvC;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
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("tiktok-mcp"),
|
|
6
|
+
port: z.number().int().min(1).max(65535).default(3007),
|
|
7
|
+
otelServiceName: z.string().default("tiktok-mcp"),
|
|
8
|
+
mcpAuthMode: z.enum(["tiktok-bearer", "jwt", "none"]).default("tiktok-bearer"),
|
|
9
|
+
tiktokApiBaseUrl: z.string().url().default("https://business-api.tiktok.com"),
|
|
10
|
+
tiktokApiVersion: z.string().default("v1.3"),
|
|
11
|
+
tiktokRateLimitPerMinute: z.number().default(10),
|
|
12
|
+
tiktokAccessToken: z.string().optional(),
|
|
13
|
+
tiktokAdvertiserId: z.string().optional(),
|
|
14
|
+
tiktokAppId: z.string().optional(),
|
|
15
|
+
tiktokAppSecret: z.string().optional(),
|
|
16
|
+
tiktokRefreshToken: z.string().optional(),
|
|
17
|
+
tiktokReportPollIntervalMs: z.number().default(2_000),
|
|
18
|
+
tiktokReportMaxPollAttempts: z.number().default(30),
|
|
19
|
+
tiktokVideoUploadPollIntervalMs: z.number().default(20_000),
|
|
20
|
+
tiktokVideoUploadMaxPollAttempts: z.number().default(30),
|
|
21
|
+
});
|
|
22
|
+
export function parseConfig() {
|
|
23
|
+
const defaultHost = getDefaultHost();
|
|
24
|
+
const rawConfig = {
|
|
25
|
+
...getBaseEnvConfig(defaultHost),
|
|
26
|
+
serviceName: process.env.SERVICE_NAME,
|
|
27
|
+
...(process.env.TIKTOK_MCP_PORT ? { port: Number(process.env.TIKTOK_MCP_PORT) } : {}),
|
|
28
|
+
host: process.env.TIKTOK_MCP_HOST || defaultHost,
|
|
29
|
+
tiktokApiBaseUrl: process.env.TIKTOK_API_BASE_URL,
|
|
30
|
+
tiktokApiVersion: process.env.TIKTOK_API_VERSION,
|
|
31
|
+
tiktokRateLimitPerMinute: process.env.TIKTOK_RATE_LIMIT_PER_MINUTE
|
|
32
|
+
? Number(process.env.TIKTOK_RATE_LIMIT_PER_MINUTE)
|
|
33
|
+
: undefined,
|
|
34
|
+
tiktokAccessToken: process.env.TIKTOK_ACCESS_TOKEN,
|
|
35
|
+
tiktokAdvertiserId: process.env.TIKTOK_ADVERTISER_ID,
|
|
36
|
+
tiktokAppId: process.env.TIKTOK_APP_ID,
|
|
37
|
+
tiktokAppSecret: process.env.TIKTOK_APP_SECRET,
|
|
38
|
+
tiktokRefreshToken: process.env.TIKTOK_REFRESH_TOKEN,
|
|
39
|
+
tiktokReportPollIntervalMs: process.env.TIKTOK_REPORT_POLL_INTERVAL_MS
|
|
40
|
+
? Number(process.env.TIKTOK_REPORT_POLL_INTERVAL_MS)
|
|
41
|
+
: undefined,
|
|
42
|
+
tiktokReportMaxPollAttempts: process.env.TIKTOK_REPORT_MAX_POLL_ATTEMPTS
|
|
43
|
+
? Number(process.env.TIKTOK_REPORT_MAX_POLL_ATTEMPTS)
|
|
44
|
+
: undefined,
|
|
45
|
+
tiktokVideoUploadPollIntervalMs: process.env.TIKTOK_VIDEO_UPLOAD_POLL_INTERVAL_MS
|
|
46
|
+
? Number(process.env.TIKTOK_VIDEO_UPLOAD_POLL_INTERVAL_MS)
|
|
47
|
+
: undefined,
|
|
48
|
+
tiktokVideoUploadMaxPollAttempts: process.env.TIKTOK_VIDEO_UPLOAD_MAX_POLL_ATTEMPTS
|
|
49
|
+
? Number(process.env.TIKTOK_VIDEO_UPLOAD_MAX_POLL_ATTEMPTS)
|
|
50
|
+
: undefined,
|
|
51
|
+
};
|
|
52
|
+
return parseConfigWithSchema(ConfigSchema, rawConfig);
|
|
53
|
+
}
|
|
54
|
+
export const mcpConfig = parseConfig();
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,UAAU,EAAE,CAAC;AAEb,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC;IAE3C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC;IAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACtD,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC;IAGjD,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC;IAG9E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC;IAC7E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAI5C,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAGhD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAGzC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAGzC,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACrD,2BAA2B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAGnD,+BAA+B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IAC3D,gCAAgC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACzD,CAAC,CAAC;AAIH,MAAM,UAAU,WAAW;IACzB,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,MAAM,SAAS,GAA4B;QACzC,GAAG,gBAAgB,CAAC,WAAW,CAAC;QAGhC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,WAAW;QAGhD,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;QACjD,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAChD,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B;YAChE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;YAClD,CAAC,CAAC,SAAS;QAGb,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAClD,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAGpD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;QACtC,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC9C,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAGpD,0BAA0B,EAAE,OAAO,CAAC,GAAG,CAAC,8BAA8B;YACpE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;YACpD,CAAC,CAAC,SAAS;QACb,2BAA2B,EAAE,OAAO,CAAC,GAAG,CAAC,+BAA+B;YACtE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;YACrD,CAAC,CAAC,SAAS;QAGb,+BAA+B,EAAE,OAAO,CAAC,GAAG,CAAC,oCAAoC;YAC/E,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;YAC1D,CAAC,CAAC,SAAS;QACb,gCAAgC,EAAE,OAAO,CAAC,GAAG,CAAC,qCAAqC;YACjF,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC;YAC3D,CAAC,CAAC,SAAS;KACd,CAAC;IAEF,OAAO,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,EAAE,CAAC"}
|
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,47 @@
|
|
|
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 { TikTokAccessTokenAdapter } from "./auth/tiktok-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("tiktok-mcp", transportMode, otelLogMixin());
|
|
12
|
+
async function setupStdioCredentials(sessionId) {
|
|
13
|
+
const accessToken = mcpConfig.tiktokAccessToken;
|
|
14
|
+
const advertiserId = mcpConfig.tiktokAdvertiserId;
|
|
15
|
+
if (!accessToken || !advertiserId) {
|
|
16
|
+
logger.warn("No TikTok credentials found in env vars. " +
|
|
17
|
+
"Set TIKTOK_ACCESS_TOKEN and TIKTOK_ADVERTISER_ID for stdio mode.");
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const authAdapter = new TikTokAccessTokenAdapter(accessToken, advertiserId, mcpConfig.tiktokApiBaseUrl, mcpConfig.tiktokApiVersion);
|
|
21
|
+
await authAdapter.validate();
|
|
22
|
+
const services = createSessionServices(authAdapter, {
|
|
23
|
+
baseUrl: mcpConfig.tiktokApiBaseUrl,
|
|
24
|
+
reportPollIntervalMs: mcpConfig.tiktokReportPollIntervalMs,
|
|
25
|
+
reportMaxPollAttempts: mcpConfig.tiktokReportMaxPollAttempts,
|
|
26
|
+
apiVersion: mcpConfig.tiktokApiVersion,
|
|
27
|
+
}, logger, rateLimiter);
|
|
28
|
+
sessionServiceStore.set(sessionId, services);
|
|
29
|
+
logger.info("Stdio session services created successfully");
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
bootstrapMcpServer({
|
|
33
|
+
serviceName: "tiktok-mcp",
|
|
34
|
+
config: mcpConfig,
|
|
35
|
+
logger,
|
|
36
|
+
transportMode,
|
|
37
|
+
initOtel: initializeOpenTelemetry,
|
|
38
|
+
setupStdioSession: setupStdioCredentials,
|
|
39
|
+
createMcpServer,
|
|
40
|
+
runStdio: runStdioServer,
|
|
41
|
+
startHttp: startHttpServer,
|
|
42
|
+
onShutdown: () => rateLimiter.destroy(),
|
|
43
|
+
}).catch((err) => {
|
|
44
|
+
logger.fatal({ err }, "Failed to start tiktok-mcp");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
});
|
|
47
|
+
//# 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,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,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,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC,CAAC;AAM/E,KAAK,UAAU,qBAAqB,CAAC,SAAiB;IACpD,MAAM,WAAW,GAAG,SAAS,CAAC,iBAAiB,CAAC;IAChD,MAAM,YAAY,GAAG,SAAS,CAAC,kBAAkB,CAAC;IAElD,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CACT,2CAA2C;YACzC,kEAAkE,CACrE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,wBAAwB,CAC9C,WAAW,EACX,YAAY,EACZ,SAAS,CAAC,gBAAgB,EAC1B,SAAS,CAAC,gBAAgB,CAC3B,CAAC;IAGF,MAAM,WAAW,CAAC,QAAQ,EAAE,CAAC;IAE7B,MAAM,QAAQ,GAAG,qBAAqB,CACpC,WAAW,EACX;QACE,OAAO,EAAE,SAAS,CAAC,gBAAgB;QACnC,oBAAoB,EAAE,SAAS,CAAC,0BAA0B;QAC1D,qBAAqB,EAAE,SAAS,CAAC,2BAA2B;QAC5D,UAAU,EAAE,SAAS,CAAC,gBAAgB;KACvC,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,YAAY;IACzB,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,4BAA4B,CAAC,CAAC;IACpD,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: "tiktok_bulk_operations_workflow",
|
|
3
|
+
description: "Guide for performing bulk create, update, and status operations on TikTok Ads entities",
|
|
4
|
+
arguments: [
|
|
5
|
+
{
|
|
6
|
+
name: "advertiserId",
|
|
7
|
+
description: "TikTok 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 advertiserId = args?.advertiserId || "{advertiserId}";
|
|
19
|
+
const entityType = args?.entityType || "campaign";
|
|
20
|
+
return `# TikTok Bulk Operations Workflow
|
|
21
|
+
|
|
22
|
+
## Advertiser ID: \`${advertiserId}\`
|
|
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
|
+
tiktok_bulk_update_status({
|
|
33
|
+
"entityType": "${entityType}",
|
|
34
|
+
"advertiserId": "${advertiserId}",
|
|
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
|
+
tiktok_bulk_create_entities({
|
|
53
|
+
"entityType": "${entityType}",
|
|
54
|
+
"advertiserId": "${advertiserId}",
|
|
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
|
+
tiktok_bulk_update_entities({
|
|
80
|
+
"entityType": "${entityType}",
|
|
81
|
+
"advertiserId": "${advertiserId}",
|
|
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
|
+
tiktok_adjust_bids({
|
|
97
|
+
"advertiserId": "${advertiserId}",
|
|
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 \`tiktok_list_entities\` to get entity IDs before bulk operations
|
|
111
|
+
2. **Validate first**: Use \`tiktok_validate_entity\` to check payloads before bulk create
|
|
112
|
+
3. **Status update is batched**: TikTok 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. tiktok_list_entities (get campaign IDs)
|
|
121
|
+
2. tiktok_bulk_update_status (DISABLE all)
|
|
122
|
+
3. tiktok_bulk_update_entities (adjust budgets/settings)
|
|
123
|
+
4. tiktok_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,iCAAiC;IACvC,WAAW,EACT,wFAAwF;IAC1F,SAAS,EAAE;QACT;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,sBAAsB;YACnC,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,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,gBAAgB,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,UAAU,CAAC;IAElD,OAAO;;sBAEa,YAAY;oBACd,UAAU;;;;;;;;;;mBAUX,UAAU;qBACR,YAAY;;;;;;;;;;;;;;;;;;;mBAmBd,UAAU;qBACR,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;mBA0Bd,UAAU;qBACR,YAAY;;;;;;;;;;;;;;;;qBAgBZ,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BhC,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,CAuFrF"}
|