@cesteral/linkedin-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 +304 -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/linkedin-auth-adapter.d.ts +38 -0
- package/dist/auth/linkedin-auth-adapter.d.ts.map +1 -0
- package/dist/auth/linkedin-auth-adapter.js +110 -0
- package/dist/auth/linkedin-auth-adapter.js.map +1 -0
- package/dist/auth/linkedin-auth-strategy.d.ts +14 -0
- package/dist/auth/linkedin-auth-strategy.d.ts.map +1 -0
- package/dist/auth/linkedin-auth-strategy.js +50 -0
- package/dist/auth/linkedin-auth-strategy.js.map +1 -0
- package/dist/config/index.d.ts +100 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +37 -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 +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/prompts/definitions/analytics-reporting-workflow.prompt.d.ts +4 -0
- package/dist/mcp-server/prompts/definitions/analytics-reporting-workflow.prompt.d.ts.map +1 -0
- package/dist/mcp-server/prompts/definitions/analytics-reporting-workflow.prompt.js +108 -0
- package/dist/mcp-server/prompts/definitions/analytics-reporting-workflow.prompt.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 +177 -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 +171 -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 +109 -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 +213 -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 +151 -0
- package/dist/mcp-server/prompts/definitions/entity-update-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 +217 -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 +98 -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 +91 -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/analytics-reference.resource.d.ts +3 -0
- package/dist/mcp-server/resources/definitions/analytics-reference.resource.d.ts.map +1 -0
- package/dist/mcp-server/resources/definitions/analytics-reference.resource.js +162 -0
- package/dist/mcp-server/resources/definitions/analytics-reference.resource.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 +164 -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 +144 -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 +127 -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 +54 -0
- package/dist/mcp-server/resources/definitions/index.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 +122 -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 +128 -0
- package/dist/mcp-server/server.js.map +1 -0
- package/dist/mcp-server/tools/definitions/adjust-bids.tool.d.ts +213 -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 +174 -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 +128 -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 +95 -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 +183 -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 +122 -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 +140 -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 +109 -0
- package/dist/mcp-server/tools/definitions/bulk-update-status.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/create-entity.tool.d.ts +117 -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 +98 -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 +93 -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 +100 -0
- package/dist/mcp-server/tools/definitions/delete-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/duplicate-entity.tool.d.ts +95 -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 +89 -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 +75 -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 +68 -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 +75 -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 +71 -0
- package/dist/mcp-server/tools/definitions/get-ad-previews.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-analytics-breakdowns.tool.d.ts +223 -0
- package/dist/mcp-server/tools/definitions/get-analytics-breakdowns.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-analytics-breakdowns.tool.js +152 -0
- package/dist/mcp-server/tools/definitions/get-analytics-breakdowns.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-analytics.tool.d.ts +325 -0
- package/dist/mcp-server/tools/definitions/get-analytics.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-analytics.tool.js +154 -0
- package/dist/mcp-server/tools/definitions/get-analytics.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-delivery-forecast.tool.d.ts +95 -0
- package/dist/mcp-server/tools/definitions/get-delivery-forecast.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-delivery-forecast.tool.js +90 -0
- package/dist/mcp-server/tools/definitions/get-delivery-forecast.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.d.ts +75 -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 +75 -0
- package/dist/mcp-server/tools/definitions/get-entity.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.d.ts +81 -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 +76 -0
- package/dist/mcp-server/tools/definitions/get-targeting-options.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +23 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +69 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-ad-accounts.tool.d.ts +141 -0
- package/dist/mcp-server/tools/definitions/list-ad-accounts.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/list-ad-accounts.tool.js +84 -0
- package/dist/mcp-server/tools/definitions/list-ad-accounts.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/list-entities.tool.d.ts +165 -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 +112 -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 +102 -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 +98 -0
- package/dist/mcp-server/tools/definitions/search-targeting.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/update-entity.tool.d.ts +104 -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 +88 -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 +75 -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 +99 -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 +69 -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 +98 -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 +168 -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 +200 -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 +13 -0
- package/dist/mcp-server/tools/utils/entity-mapping.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/entity-mapping.js +68 -0
- package/dist/mcp-server/tools/utils/entity-mapping.js.map +1 -0
- package/dist/mcp-server/tools/utils/media-types.d.ts +12 -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 +49 -0
- package/dist/mcp-server/transports/streamable-http-transport.d.ts.map +1 -0
- package/dist/mcp-server/transports/streamable-http-transport.js +91 -0
- package/dist/mcp-server/transports/streamable-http-transport.js.map +1 -0
- package/dist/services/linkedin/linkedin-http-client.d.ts +20 -0
- package/dist/services/linkedin/linkedin-http-client.d.ts.map +1 -0
- package/dist/services/linkedin/linkedin-http-client.js +147 -0
- package/dist/services/linkedin/linkedin-http-client.js.map +1 -0
- package/dist/services/linkedin/linkedin-reporting-service.d.ts +26 -0
- package/dist/services/linkedin/linkedin-reporting-service.d.ts.map +1 -0
- package/dist/services/linkedin/linkedin-reporting-service.js +69 -0
- package/dist/services/linkedin/linkedin-reporting-service.js.map +1 -0
- package/dist/services/linkedin/linkedin-service.d.ts +84 -0
- package/dist/services/linkedin/linkedin-service.d.ts.map +1 -0
- package/dist/services/linkedin/linkedin-service.js +195 -0
- package/dist/services/linkedin/linkedin-service.js.map +1 -0
- package/dist/services/linkedin/types.d.ts +166 -0
- package/dist/services/linkedin/types.d.ts.map +1 -0
- package/dist/services/linkedin/types.js +31 -0
- package/dist/services/linkedin/types.js.map +1 -0
- package/dist/services/session-services.d.ts +18 -0
- package/dist/services/session-services.d.ts.map +1 -0
- package/dist/services/session-services.js +16 -0
- package/dist/services/session-services.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,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resolveSessionServices } from "../utils/resolve-session.js";
|
|
3
|
+
const TOOL_NAME = "linkedin_search_targeting";
|
|
4
|
+
const TOOL_TITLE = "Search LinkedIn Ads Targeting Facets";
|
|
5
|
+
const TOOL_DESCRIPTION = `Search LinkedIn audience targeting facets.
|
|
6
|
+
|
|
7
|
+
**Supported facet types:**
|
|
8
|
+
- MEMBER_INTERESTS: Professional interests
|
|
9
|
+
- MEMBER_SKILLS: Skills and expertise
|
|
10
|
+
- MEMBER_JOB_TITLE: Job titles
|
|
11
|
+
- MEMBER_JOB_FUNCTION: Job functions (e.g., Engineering, Marketing)
|
|
12
|
+
- MEMBER_INDUSTRY: Industry types
|
|
13
|
+
- MEMBER_SENIORITY: Seniority levels
|
|
14
|
+
- MEMBER_COMPANY_SIZE: Company size ranges
|
|
15
|
+
- GEO: Geographic locations
|
|
16
|
+
- MEMBER_SCHOOLS: Educational institutions
|
|
17
|
+
|
|
18
|
+
Returns matching facet options with their LinkedIn URNs for use in targeting criteria.`;
|
|
19
|
+
export const SearchTargetingInputSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
facetType: z.string().describe("Targeting facet type to search (e.g., MEMBER_INTERESTS, GEO)"),
|
|
22
|
+
query: z.string().optional().describe("Search query string to filter results"),
|
|
23
|
+
limit: z
|
|
24
|
+
.number()
|
|
25
|
+
.int()
|
|
26
|
+
.min(1)
|
|
27
|
+
.max(100)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Maximum number of results (default 20)"),
|
|
30
|
+
})
|
|
31
|
+
.describe("Parameters for searching LinkedIn targeting facets");
|
|
32
|
+
export const SearchTargetingOutputSchema = z
|
|
33
|
+
.object({
|
|
34
|
+
facetType: z.string(),
|
|
35
|
+
results: z.array(z.record(z.any())),
|
|
36
|
+
count: z.number(),
|
|
37
|
+
timestamp: z.string().datetime(),
|
|
38
|
+
})
|
|
39
|
+
.describe("Targeting search result");
|
|
40
|
+
export async function searchTargetingLogic(input, context, sdkContext) {
|
|
41
|
+
const { linkedInService } = resolveSessionServices(sdkContext);
|
|
42
|
+
const result = (await linkedInService.searchTargeting(input.facetType, input.query, input.limit, context));
|
|
43
|
+
const elements = result.elements ?? [];
|
|
44
|
+
return {
|
|
45
|
+
facetType: input.facetType,
|
|
46
|
+
results: elements,
|
|
47
|
+
count: elements.length,
|
|
48
|
+
timestamp: new Date().toISOString(),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function searchTargetingResponseFormatter(result) {
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: `Targeting search results for ${result.facetType}\nFound ${result.count} options\n\n${JSON.stringify(result.results, null, 2)}\n\nTimestamp: ${result.timestamp}`,
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
export const searchTargetingTool = {
|
|
60
|
+
name: TOOL_NAME,
|
|
61
|
+
title: TOOL_TITLE,
|
|
62
|
+
description: TOOL_DESCRIPTION,
|
|
63
|
+
inputSchema: SearchTargetingInputSchema,
|
|
64
|
+
outputSchema: SearchTargetingOutputSchema,
|
|
65
|
+
annotations: {
|
|
66
|
+
readOnlyHint: true,
|
|
67
|
+
openWorldHint: true,
|
|
68
|
+
idempotentHint: true,
|
|
69
|
+
destructiveHint: false,
|
|
70
|
+
},
|
|
71
|
+
inputExamples: [
|
|
72
|
+
{
|
|
73
|
+
label: "Search for job titles",
|
|
74
|
+
input: {
|
|
75
|
+
facetType: "MEMBER_JOB_TITLE",
|
|
76
|
+
query: "software engineer",
|
|
77
|
+
limit: 20,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
label: "Browse geographic locations",
|
|
82
|
+
input: {
|
|
83
|
+
facetType: "GEO",
|
|
84
|
+
query: "United Kingdom",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
label: "List seniority levels",
|
|
89
|
+
input: {
|
|
90
|
+
facetType: "MEMBER_SENIORITY",
|
|
91
|
+
limit: 50,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
logic: searchTargetingLogic,
|
|
96
|
+
responseFormatter: searchTargetingResponseFormatter,
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=search-targeting.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-targeting.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-targeting.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RequestContext, McpTextContent } from "@cesteral/shared";
|
|
3
|
+
import type { SdkContext } from "@cesteral/shared";
|
|
4
|
+
export declare const UpdateEntityInputSchema: z.ZodObject<{
|
|
5
|
+
entityType: z.ZodEnum<[string, ...string[]]>;
|
|
6
|
+
entityUrn: z.ZodString;
|
|
7
|
+
data: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
entityType: string;
|
|
10
|
+
entityUrn: string;
|
|
11
|
+
data: Record<string, any>;
|
|
12
|
+
}, {
|
|
13
|
+
entityType: string;
|
|
14
|
+
entityUrn: string;
|
|
15
|
+
data: Record<string, any>;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const UpdateEntityOutputSchema: z.ZodObject<{
|
|
18
|
+
success: z.ZodBoolean;
|
|
19
|
+
entityUrn: z.ZodString;
|
|
20
|
+
entityType: z.ZodString;
|
|
21
|
+
timestamp: z.ZodString;
|
|
22
|
+
}, "strip", z.ZodTypeAny, {
|
|
23
|
+
entityType: string;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
entityUrn: string;
|
|
26
|
+
success: boolean;
|
|
27
|
+
}, {
|
|
28
|
+
entityType: string;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
entityUrn: string;
|
|
31
|
+
success: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
type UpdateEntityInput = z.infer<typeof UpdateEntityInputSchema>;
|
|
34
|
+
type UpdateEntityOutput = z.infer<typeof UpdateEntityOutputSchema>;
|
|
35
|
+
export declare function updateEntityLogic(input: UpdateEntityInput, context: RequestContext, sdkContext?: SdkContext): Promise<UpdateEntityOutput>;
|
|
36
|
+
export declare function updateEntityResponseFormatter(result: UpdateEntityOutput): McpTextContent[];
|
|
37
|
+
export declare const updateEntityTool: {
|
|
38
|
+
name: string;
|
|
39
|
+
title: string;
|
|
40
|
+
description: string;
|
|
41
|
+
inputSchema: z.ZodObject<{
|
|
42
|
+
entityType: z.ZodEnum<[string, ...string[]]>;
|
|
43
|
+
entityUrn: z.ZodString;
|
|
44
|
+
data: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
entityType: string;
|
|
47
|
+
entityUrn: string;
|
|
48
|
+
data: Record<string, any>;
|
|
49
|
+
}, {
|
|
50
|
+
entityType: string;
|
|
51
|
+
entityUrn: string;
|
|
52
|
+
data: Record<string, any>;
|
|
53
|
+
}>;
|
|
54
|
+
outputSchema: z.ZodObject<{
|
|
55
|
+
success: z.ZodBoolean;
|
|
56
|
+
entityUrn: z.ZodString;
|
|
57
|
+
entityType: z.ZodString;
|
|
58
|
+
timestamp: z.ZodString;
|
|
59
|
+
}, "strip", z.ZodTypeAny, {
|
|
60
|
+
entityType: string;
|
|
61
|
+
timestamp: string;
|
|
62
|
+
entityUrn: string;
|
|
63
|
+
success: boolean;
|
|
64
|
+
}, {
|
|
65
|
+
entityType: string;
|
|
66
|
+
timestamp: string;
|
|
67
|
+
entityUrn: string;
|
|
68
|
+
success: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
annotations: {
|
|
71
|
+
readOnlyHint: boolean;
|
|
72
|
+
openWorldHint: boolean;
|
|
73
|
+
idempotentHint: boolean;
|
|
74
|
+
destructiveHint: boolean;
|
|
75
|
+
};
|
|
76
|
+
inputExamples: ({
|
|
77
|
+
label: string;
|
|
78
|
+
input: {
|
|
79
|
+
entityType: string;
|
|
80
|
+
entityUrn: string;
|
|
81
|
+
data: {
|
|
82
|
+
status: string;
|
|
83
|
+
dailyBudget?: undefined;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
} | {
|
|
87
|
+
label: string;
|
|
88
|
+
input: {
|
|
89
|
+
entityType: string;
|
|
90
|
+
entityUrn: string;
|
|
91
|
+
data: {
|
|
92
|
+
dailyBudget: {
|
|
93
|
+
amount: string;
|
|
94
|
+
currencyCode: string;
|
|
95
|
+
};
|
|
96
|
+
status?: undefined;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
})[];
|
|
100
|
+
logic: typeof updateEntityLogic;
|
|
101
|
+
responseFormatter: typeof updateEntityResponseFormatter;
|
|
102
|
+
};
|
|
103
|
+
export {};
|
|
104
|
+
//# sourceMappingURL=update-entity.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-entity.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/update-entity.tool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgBnD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EASwB,CAAC;AAE7D,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;EAOF,CAAC;AAEpC,KAAK,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACjE,KAAK,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEnE,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAgB7B;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,kBAAkB,GAAG,cAAc,EAAE,CAO1F;AAED,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC5B,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resolveSessionServices } from "../utils/resolve-session.js";
|
|
3
|
+
import { getEntityTypeEnum } from "../utils/entity-mapping.js";
|
|
4
|
+
const TOOL_NAME = "linkedin_update_entity";
|
|
5
|
+
const TOOL_TITLE = "Update LinkedIn Ads Entity";
|
|
6
|
+
const TOOL_DESCRIPTION = `Update an existing LinkedIn Ads entity via PATCH (partial update).
|
|
7
|
+
|
|
8
|
+
**Supported entity types:** ${getEntityTypeEnum().join(", ")}
|
|
9
|
+
|
|
10
|
+
Uses X-Restli-Method: PARTIAL_UPDATE semantics — only provided fields are updated.
|
|
11
|
+
|
|
12
|
+
**Gotchas:**
|
|
13
|
+
- LinkedIn PATCH uses a \`patch.$set\` wrapper internally; just provide the fields to update.
|
|
14
|
+
- Status values: ACTIVE, PAUSED, DRAFT, ARCHIVED, CANCELED
|
|
15
|
+
- Budget changes are applied immediately.
|
|
16
|
+
- Writes are rate-limited at 3x read cost.`;
|
|
17
|
+
export const UpdateEntityInputSchema = z
|
|
18
|
+
.object({
|
|
19
|
+
entityType: z.enum(getEntityTypeEnum()).describe("Type of entity to update"),
|
|
20
|
+
entityUrn: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1)
|
|
23
|
+
.describe("The entity URN to update (e.g., urn:li:sponsoredCampaign:123)"),
|
|
24
|
+
data: z.record(z.any()).describe("Fields to update as key-value pairs"),
|
|
25
|
+
})
|
|
26
|
+
.describe("Parameters for updating a LinkedIn Ads entity");
|
|
27
|
+
export const UpdateEntityOutputSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
success: z.boolean(),
|
|
30
|
+
entityUrn: z.string(),
|
|
31
|
+
entityType: z.string(),
|
|
32
|
+
timestamp: z.string().datetime(),
|
|
33
|
+
})
|
|
34
|
+
.describe("Entity update result");
|
|
35
|
+
export async function updateEntityLogic(input, context, sdkContext) {
|
|
36
|
+
const { linkedInService } = resolveSessionServices(sdkContext);
|
|
37
|
+
await linkedInService.updateEntity(input.entityType, input.entityUrn, input.data, context);
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
entityUrn: input.entityUrn,
|
|
41
|
+
entityType: input.entityType,
|
|
42
|
+
timestamp: new Date().toISOString(),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function updateEntityResponseFormatter(result) {
|
|
46
|
+
return [
|
|
47
|
+
{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `${result.entityType} ${result.entityUrn} updated successfully\n\nTimestamp: ${result.timestamp}`,
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
export const updateEntityTool = {
|
|
54
|
+
name: TOOL_NAME,
|
|
55
|
+
title: TOOL_TITLE,
|
|
56
|
+
description: TOOL_DESCRIPTION,
|
|
57
|
+
inputSchema: UpdateEntityInputSchema,
|
|
58
|
+
outputSchema: UpdateEntityOutputSchema,
|
|
59
|
+
annotations: {
|
|
60
|
+
readOnlyHint: false,
|
|
61
|
+
openWorldHint: false,
|
|
62
|
+
idempotentHint: false,
|
|
63
|
+
destructiveHint: true,
|
|
64
|
+
},
|
|
65
|
+
inputExamples: [
|
|
66
|
+
{
|
|
67
|
+
label: "Pause a campaign",
|
|
68
|
+
input: {
|
|
69
|
+
entityType: "campaign",
|
|
70
|
+
entityUrn: "urn:li:sponsoredCampaign:123456789",
|
|
71
|
+
data: { status: "PAUSED" },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
label: "Update campaign daily budget",
|
|
76
|
+
input: {
|
|
77
|
+
entityType: "campaign",
|
|
78
|
+
entityUrn: "urn:li:sponsoredCampaign:123456789",
|
|
79
|
+
data: {
|
|
80
|
+
dailyBudget: { amount: "100.00", currencyCode: "USD" },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
logic: updateEntityLogic,
|
|
86
|
+
responseFormatter: updateEntityResponseFormatter,
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=update-entity.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-entity.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/update-entity.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RequestContext, McpTextContent } from "@cesteral/shared";
|
|
3
|
+
import type { SdkContext } from "@cesteral/shared";
|
|
4
|
+
export declare const UploadImageInputSchema: z.ZodObject<{
|
|
5
|
+
adAccountUrn: z.ZodString;
|
|
6
|
+
mediaUrl: z.ZodString;
|
|
7
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
adAccountUrn: string;
|
|
10
|
+
mediaUrl: string;
|
|
11
|
+
filename?: string | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
adAccountUrn: string;
|
|
14
|
+
mediaUrl: string;
|
|
15
|
+
filename?: string | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const UploadImageOutputSchema: z.ZodObject<{
|
|
18
|
+
assetUrn: z.ZodString;
|
|
19
|
+
uploadedAt: z.ZodString;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
assetUrn: string;
|
|
22
|
+
uploadedAt: string;
|
|
23
|
+
}, {
|
|
24
|
+
assetUrn: string;
|
|
25
|
+
uploadedAt: string;
|
|
26
|
+
}>;
|
|
27
|
+
type UploadImageInput = z.infer<typeof UploadImageInputSchema>;
|
|
28
|
+
type UploadImageOutput = z.infer<typeof UploadImageOutputSchema>;
|
|
29
|
+
export declare function uploadImageLogic(input: UploadImageInput, context: RequestContext, sdkContext?: SdkContext): Promise<UploadImageOutput>;
|
|
30
|
+
export declare function uploadImageResponseFormatter(result: UploadImageOutput): McpTextContent[];
|
|
31
|
+
export declare const uploadImageTool: {
|
|
32
|
+
name: string;
|
|
33
|
+
title: string;
|
|
34
|
+
description: string;
|
|
35
|
+
inputSchema: z.ZodObject<{
|
|
36
|
+
adAccountUrn: z.ZodString;
|
|
37
|
+
mediaUrl: z.ZodString;
|
|
38
|
+
filename: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, "strip", z.ZodTypeAny, {
|
|
40
|
+
adAccountUrn: string;
|
|
41
|
+
mediaUrl: string;
|
|
42
|
+
filename?: string | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
adAccountUrn: string;
|
|
45
|
+
mediaUrl: string;
|
|
46
|
+
filename?: string | undefined;
|
|
47
|
+
}>;
|
|
48
|
+
outputSchema: z.ZodObject<{
|
|
49
|
+
assetUrn: z.ZodString;
|
|
50
|
+
uploadedAt: z.ZodString;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
assetUrn: string;
|
|
53
|
+
uploadedAt: string;
|
|
54
|
+
}, {
|
|
55
|
+
assetUrn: string;
|
|
56
|
+
uploadedAt: string;
|
|
57
|
+
}>;
|
|
58
|
+
annotations: {
|
|
59
|
+
readOnlyHint: boolean;
|
|
60
|
+
openWorldHint: boolean;
|
|
61
|
+
idempotentHint: boolean;
|
|
62
|
+
destructiveHint: boolean;
|
|
63
|
+
};
|
|
64
|
+
inputExamples: {
|
|
65
|
+
label: string;
|
|
66
|
+
input: {
|
|
67
|
+
adAccountUrn: string;
|
|
68
|
+
mediaUrl: string;
|
|
69
|
+
};
|
|
70
|
+
}[];
|
|
71
|
+
logic: typeof uploadImageLogic;
|
|
72
|
+
responseFormatter: typeof uploadImageResponseFormatter;
|
|
73
|
+
};
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=upload-image.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-image.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/upload-image.tool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAkBnD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;EAQyB,CAAC;AAE7D,eAAO,MAAM,uBAAuB;;;;;;;;;EAOQ,CAAC;AAE7C,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/D,KAAK,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAEjE,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAsD5B;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAOxF;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuB3B,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resolveSessionServices } from "../utils/resolve-session.js";
|
|
3
|
+
import { downloadFileToBuffer, McpError, JsonRpcErrorCode } from "@cesteral/shared";
|
|
4
|
+
const TOOL_NAME = "linkedin_upload_image";
|
|
5
|
+
const TOOL_TITLE = "Upload Image to LinkedIn Ads";
|
|
6
|
+
const TOOL_DESCRIPTION = `Upload an image to LinkedIn Ads from a URL.
|
|
7
|
+
|
|
8
|
+
The server downloads the image and uploads it to LinkedIn's Digital Media Assets library.
|
|
9
|
+
Uses LinkedIn's 3-step upload flow: register → upload binary → confirm.
|
|
10
|
+
|
|
11
|
+
**Image requirements:**
|
|
12
|
+
- Formats: JPEG, PNG, GIF
|
|
13
|
+
- Min: 400x400px (Sponsored Content), recommended 1200x627px
|
|
14
|
+
- Max file size: 5MB
|
|
15
|
+
- Aspect ratios: 1.91:1 (horizontal), 1:1 (square), 2:3 (vertical)
|
|
16
|
+
|
|
17
|
+
**Usage:** The returned assetUrn is referenced in creative → content → media → reference`;
|
|
18
|
+
export const UploadImageInputSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
adAccountUrn: z
|
|
21
|
+
.string()
|
|
22
|
+
.describe("LinkedIn Ad Account URN (e.g., urn:li:sponsoredAccount:123456)"),
|
|
23
|
+
mediaUrl: z.string().url().describe("Publicly accessible URL of the image to upload"),
|
|
24
|
+
filename: z.string().optional().describe("Override filename"),
|
|
25
|
+
})
|
|
26
|
+
.describe("Parameters for uploading an image to LinkedIn");
|
|
27
|
+
export const UploadImageOutputSchema = z
|
|
28
|
+
.object({
|
|
29
|
+
assetUrn: z
|
|
30
|
+
.string()
|
|
31
|
+
.describe("Asset URN (urn:li:digitalmediaAsset:...) for use in creative payloads"),
|
|
32
|
+
uploadedAt: z.string().datetime(),
|
|
33
|
+
})
|
|
34
|
+
.describe("Uploaded LinkedIn image asset");
|
|
35
|
+
export async function uploadImageLogic(input, context, sdkContext) {
|
|
36
|
+
const { linkedInService } = resolveSessionServices(sdkContext);
|
|
37
|
+
const registerPayload = {
|
|
38
|
+
registerUploadRequest: {
|
|
39
|
+
owner: input.adAccountUrn,
|
|
40
|
+
recipes: ["urn:li:digitalmediaRecipe:ads-image"],
|
|
41
|
+
serviceRelationships: [
|
|
42
|
+
{
|
|
43
|
+
identifier: "urn:li:userGeneratedContent",
|
|
44
|
+
relationshipType: "OWNER",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const registerResult = (await linkedInService.client.post("/v2/assets?action=registerUpload", registerPayload, context));
|
|
50
|
+
const uploadRequest = registerResult.value?.uploadMechanism?.["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"];
|
|
51
|
+
const uploadUrl = uploadRequest?.uploadUrl;
|
|
52
|
+
const assetUrn = registerResult.value?.asset;
|
|
53
|
+
if (!uploadUrl || !assetUrn) {
|
|
54
|
+
throw new McpError(JsonRpcErrorCode.InternalError, "LinkedIn register upload failed: missing uploadUrl or asset URN");
|
|
55
|
+
}
|
|
56
|
+
const { buffer, contentType } = await downloadFileToBuffer(input.mediaUrl, 120_000, context);
|
|
57
|
+
const MAX_IMAGE_SIZE = 5 * 1024 * 1024;
|
|
58
|
+
if (buffer.length > MAX_IMAGE_SIZE) {
|
|
59
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Image file too large: ${(buffer.length / 1024 / 1024).toFixed(1)}MB exceeds LinkedIn's 5MB limit`);
|
|
60
|
+
}
|
|
61
|
+
await linkedInService.client.putBinary(uploadUrl, buffer, contentType, context);
|
|
62
|
+
return {
|
|
63
|
+
assetUrn,
|
|
64
|
+
uploadedAt: new Date().toISOString(),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function uploadImageResponseFormatter(result) {
|
|
68
|
+
return [
|
|
69
|
+
{
|
|
70
|
+
type: "text",
|
|
71
|
+
text: `Image uploaded to LinkedIn!\n\nAsset URN: ${result.assetUrn}\n\nUse assetUrn in creative.content.media.reference for Sponsored Content.`,
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
export const uploadImageTool = {
|
|
76
|
+
name: TOOL_NAME,
|
|
77
|
+
title: TOOL_TITLE,
|
|
78
|
+
description: TOOL_DESCRIPTION,
|
|
79
|
+
inputSchema: UploadImageInputSchema,
|
|
80
|
+
outputSchema: UploadImageOutputSchema,
|
|
81
|
+
annotations: {
|
|
82
|
+
readOnlyHint: false,
|
|
83
|
+
openWorldHint: true,
|
|
84
|
+
idempotentHint: false,
|
|
85
|
+
destructiveHint: true,
|
|
86
|
+
},
|
|
87
|
+
inputExamples: [
|
|
88
|
+
{
|
|
89
|
+
label: "Upload a banner image for LinkedIn ads",
|
|
90
|
+
input: {
|
|
91
|
+
adAccountUrn: "urn:li:sponsoredAccount:123456",
|
|
92
|
+
mediaUrl: "https://example.com/banner-1200x627.jpg",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
logic: uploadImageLogic,
|
|
97
|
+
responseFormatter: uploadImageResponseFormatter,
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=upload-image.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-image.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/upload-image.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { RequestContext, McpTextContent } from "@cesteral/shared";
|
|
3
|
+
import type { SdkContext } from "@cesteral/shared";
|
|
4
|
+
export declare const UploadVideoInputSchema: z.ZodObject<{
|
|
5
|
+
adAccountUrn: z.ZodString;
|
|
6
|
+
mediaUrl: z.ZodString;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
adAccountUrn: string;
|
|
9
|
+
mediaUrl: string;
|
|
10
|
+
}, {
|
|
11
|
+
adAccountUrn: string;
|
|
12
|
+
mediaUrl: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const UploadVideoOutputSchema: z.ZodObject<{
|
|
15
|
+
assetUrn: z.ZodString;
|
|
16
|
+
uploadedAt: z.ZodString;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
assetUrn: string;
|
|
19
|
+
uploadedAt: string;
|
|
20
|
+
}, {
|
|
21
|
+
assetUrn: string;
|
|
22
|
+
uploadedAt: string;
|
|
23
|
+
}>;
|
|
24
|
+
type UploadVideoInput = z.infer<typeof UploadVideoInputSchema>;
|
|
25
|
+
type UploadVideoOutput = z.infer<typeof UploadVideoOutputSchema>;
|
|
26
|
+
export declare function uploadVideoLogic(input: UploadVideoInput, context: RequestContext, sdkContext?: SdkContext): Promise<UploadVideoOutput>;
|
|
27
|
+
export declare function uploadVideoResponseFormatter(result: UploadVideoOutput): McpTextContent[];
|
|
28
|
+
export declare const uploadVideoTool: {
|
|
29
|
+
name: string;
|
|
30
|
+
title: string;
|
|
31
|
+
description: string;
|
|
32
|
+
inputSchema: z.ZodObject<{
|
|
33
|
+
adAccountUrn: z.ZodString;
|
|
34
|
+
mediaUrl: z.ZodString;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
adAccountUrn: string;
|
|
37
|
+
mediaUrl: string;
|
|
38
|
+
}, {
|
|
39
|
+
adAccountUrn: string;
|
|
40
|
+
mediaUrl: string;
|
|
41
|
+
}>;
|
|
42
|
+
outputSchema: z.ZodObject<{
|
|
43
|
+
assetUrn: z.ZodString;
|
|
44
|
+
uploadedAt: z.ZodString;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
assetUrn: string;
|
|
47
|
+
uploadedAt: string;
|
|
48
|
+
}, {
|
|
49
|
+
assetUrn: string;
|
|
50
|
+
uploadedAt: string;
|
|
51
|
+
}>;
|
|
52
|
+
annotations: {
|
|
53
|
+
readOnlyHint: boolean;
|
|
54
|
+
openWorldHint: boolean;
|
|
55
|
+
idempotentHint: boolean;
|
|
56
|
+
destructiveHint: boolean;
|
|
57
|
+
};
|
|
58
|
+
inputExamples: {
|
|
59
|
+
label: string;
|
|
60
|
+
input: {
|
|
61
|
+
adAccountUrn: string;
|
|
62
|
+
mediaUrl: string;
|
|
63
|
+
};
|
|
64
|
+
}[];
|
|
65
|
+
logic: typeof uploadVideoLogic;
|
|
66
|
+
responseFormatter: typeof uploadVideoResponseFormatter;
|
|
67
|
+
};
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=upload-video.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-video.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/upload-video.tool.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAkBnD,eAAO,MAAM,sBAAsB;;;;;;;;;EAOwB,CAAC;AAE5D,eAAO,MAAM,uBAAuB;;;;;;;;;EAOQ,CAAC;AAE7C,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC/D,KAAK,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAEjE,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,UAAU,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAsD5B;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAOxF;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuB3B,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { resolveSessionServices } from "../utils/resolve-session.js";
|
|
3
|
+
import { downloadFileToBuffer, McpError, JsonRpcErrorCode } from "@cesteral/shared";
|
|
4
|
+
const TOOL_NAME = "linkedin_upload_video";
|
|
5
|
+
const TOOL_TITLE = "Upload Video to LinkedIn Ads";
|
|
6
|
+
const TOOL_DESCRIPTION = `Upload a video to LinkedIn Ads from a URL.
|
|
7
|
+
|
|
8
|
+
The server downloads the video and uploads it to LinkedIn's Digital Media Assets library.
|
|
9
|
+
Uses LinkedIn's 3-step upload flow: register → upload binary → confirm.
|
|
10
|
+
|
|
11
|
+
**Video requirements:**
|
|
12
|
+
- Formats: MP4 (H.264)
|
|
13
|
+
- Max file size: 200MB
|
|
14
|
+
- Duration: 3 seconds to 30 minutes
|
|
15
|
+
- Recommended: 1920x1080px (16:9), 1080x1080px (1:1)
|
|
16
|
+
|
|
17
|
+
**Usage:** The returned assetUrn is referenced in creative → content → media → reference`;
|
|
18
|
+
export const UploadVideoInputSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
adAccountUrn: z
|
|
21
|
+
.string()
|
|
22
|
+
.describe("LinkedIn Ad Account URN (e.g., urn:li:sponsoredAccount:123456)"),
|
|
23
|
+
mediaUrl: z.string().url().describe("Publicly accessible URL of the video to upload"),
|
|
24
|
+
})
|
|
25
|
+
.describe("Parameters for uploading a video to LinkedIn");
|
|
26
|
+
export const UploadVideoOutputSchema = z
|
|
27
|
+
.object({
|
|
28
|
+
assetUrn: z
|
|
29
|
+
.string()
|
|
30
|
+
.describe("Asset URN (urn:li:digitalmediaAsset:...) for use in creative payloads"),
|
|
31
|
+
uploadedAt: z.string().datetime(),
|
|
32
|
+
})
|
|
33
|
+
.describe("Uploaded LinkedIn video asset");
|
|
34
|
+
export async function uploadVideoLogic(input, context, sdkContext) {
|
|
35
|
+
const { linkedInService } = resolveSessionServices(sdkContext);
|
|
36
|
+
const registerPayload = {
|
|
37
|
+
registerUploadRequest: {
|
|
38
|
+
owner: input.adAccountUrn,
|
|
39
|
+
recipes: ["urn:li:digitalmediaRecipe:ads-video"],
|
|
40
|
+
serviceRelationships: [
|
|
41
|
+
{
|
|
42
|
+
identifier: "urn:li:userGeneratedContent",
|
|
43
|
+
relationshipType: "OWNER",
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const registerResult = (await linkedInService.client.post("/v2/assets?action=registerUpload", registerPayload, context));
|
|
49
|
+
const uploadRequest = registerResult.value?.uploadMechanism?.["com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest"];
|
|
50
|
+
const uploadUrl = uploadRequest?.uploadUrl;
|
|
51
|
+
const assetUrn = registerResult.value?.asset;
|
|
52
|
+
if (!uploadUrl || !assetUrn) {
|
|
53
|
+
throw new McpError(JsonRpcErrorCode.InternalError, "LinkedIn register upload failed: missing uploadUrl or asset URN");
|
|
54
|
+
}
|
|
55
|
+
const { buffer, contentType } = await downloadFileToBuffer(input.mediaUrl, 300_000, context);
|
|
56
|
+
const MAX_VIDEO_SIZE = 200 * 1024 * 1024;
|
|
57
|
+
if (buffer.length > MAX_VIDEO_SIZE) {
|
|
58
|
+
throw new McpError(JsonRpcErrorCode.InternalError, `Video file too large: ${(buffer.length / 1024 / 1024).toFixed(1)}MB exceeds LinkedIn's 200MB limit`);
|
|
59
|
+
}
|
|
60
|
+
await linkedInService.client.putBinary(uploadUrl, buffer, contentType, context);
|
|
61
|
+
return {
|
|
62
|
+
assetUrn,
|
|
63
|
+
uploadedAt: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function uploadVideoResponseFormatter(result) {
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `Video uploaded to LinkedIn!\n\nAsset URN: ${result.assetUrn}\n\nUse assetUrn in creative.content.media.reference for Sponsored Content.`,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
export const uploadVideoTool = {
|
|
75
|
+
name: TOOL_NAME,
|
|
76
|
+
title: TOOL_TITLE,
|
|
77
|
+
description: TOOL_DESCRIPTION,
|
|
78
|
+
inputSchema: UploadVideoInputSchema,
|
|
79
|
+
outputSchema: UploadVideoOutputSchema,
|
|
80
|
+
annotations: {
|
|
81
|
+
readOnlyHint: false,
|
|
82
|
+
openWorldHint: true,
|
|
83
|
+
idempotentHint: false,
|
|
84
|
+
destructiveHint: true,
|
|
85
|
+
},
|
|
86
|
+
inputExamples: [
|
|
87
|
+
{
|
|
88
|
+
label: "Upload a video ad for LinkedIn",
|
|
89
|
+
input: {
|
|
90
|
+
adAccountUrn: "urn:li:sponsoredAccount:123456",
|
|
91
|
+
mediaUrl: "https://example.com/video-ad-1080p.mp4",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
logic: uploadVideoLogic,
|
|
96
|
+
responseFormatter: uploadVideoResponseFormatter,
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=upload-video.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-video.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/upload-video.tool.ts"],"names":[],"mappings":"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"}
|