mcp-scraper 0.19.0 → 0.21.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.
Files changed (56) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/api-server.cjs +3342 -2655
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +3 -3
  5. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  6. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  7. package/dist/bin/mcp-scraper-cli.js +1 -1
  8. package/dist/bin/mcp-scraper-install.cjs +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-install.js +1 -1
  11. package/dist/bin/mcp-stdio-server.cjs +113 -19
  12. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-stdio-server.js +5 -5
  14. package/dist/bin/paa-harvest.cjs.map +1 -1
  15. package/dist/bin/paa-harvest.js +3 -3
  16. package/dist/{chunk-GL4BW4CP.js → chunk-DZBGULWW.js} +61 -9
  17. package/dist/chunk-DZBGULWW.js.map +1 -0
  18. package/dist/{chunk-D7ZT27HY.js → chunk-GMZFQRH2.js} +2 -2
  19. package/dist/{chunk-HL33CGJF.js → chunk-HXGZMMW5.js} +29 -2
  20. package/dist/chunk-HXGZMMW5.js.map +1 -0
  21. package/dist/{chunk-HE2LQPJ2.js → chunk-JBME5WJR.js} +2 -2
  22. package/dist/chunk-JWIE5NCR.js +284 -0
  23. package/dist/chunk-JWIE5NCR.js.map +1 -0
  24. package/dist/chunk-L4LMSXLO.js +7 -0
  25. package/dist/chunk-L4LMSXLO.js.map +1 -0
  26. package/dist/{chunk-RUGJE5EB.js → chunk-TUSLATZY.js} +3 -3
  27. package/dist/{chunk-O2S5TOCG.js → chunk-XHJJQRNQ.js} +111 -22
  28. package/dist/chunk-XHJJQRNQ.js.map +1 -0
  29. package/dist/{chunk-2HDMYW4B.js → chunk-ZJDANZTQ.js} +2 -2
  30. package/dist/{db-LIOTIWVN.js → db-EONGTNJM.js} +2 -2
  31. package/dist/{extract-bundle-U4D5LW5W.js → extract-bundle-HMCYUVBJ.js} +58 -5
  32. package/dist/extract-bundle-HMCYUVBJ.js.map +1 -0
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.js +3 -3
  35. package/dist/{server-VWXDE64Y.js → server-PH3VJ74X.js} +937 -745
  36. package/dist/server-PH3VJ74X.js.map +1 -0
  37. package/dist/{site-extract-repository-NVSZH35Y.js → site-extract-repository-YNPXEZCB.js} +4 -4
  38. package/dist/{worker-AM2DHUWG.js → worker-45WEWCMQ.js} +6 -6
  39. package/docs/mcp-tool-manifest.generated.json +181 -28
  40. package/docs/specs/meta-ad-creative-media-resolution-spec.md +3 -3
  41. package/docs/specs/unified-credit-and-scheduled-execution-billing-spec.md +1007 -0
  42. package/package.json +2 -2
  43. package/dist/chunk-GL4BW4CP.js.map +0 -1
  44. package/dist/chunk-HL33CGJF.js.map +0 -1
  45. package/dist/chunk-O2S5TOCG.js.map +0 -1
  46. package/dist/chunk-OQHYDW4Q.js +0 -7
  47. package/dist/chunk-OQHYDW4Q.js.map +0 -1
  48. package/dist/extract-bundle-U4D5LW5W.js.map +0 -1
  49. package/dist/server-VWXDE64Y.js.map +0 -1
  50. /package/dist/{chunk-D7ZT27HY.js.map → chunk-GMZFQRH2.js.map} +0 -0
  51. /package/dist/{chunk-HE2LQPJ2.js.map → chunk-JBME5WJR.js.map} +0 -0
  52. /package/dist/{chunk-RUGJE5EB.js.map → chunk-TUSLATZY.js.map} +0 -0
  53. /package/dist/{chunk-2HDMYW4B.js.map → chunk-ZJDANZTQ.js.map} +0 -0
  54. /package/dist/{db-LIOTIWVN.js.map → db-EONGTNJM.js.map} +0 -0
  55. /package/dist/{site-extract-repository-NVSZH35Y.js.map → site-extract-repository-YNPXEZCB.js.map} +0 -0
  56. /package/dist/{worker-AM2DHUWG.js.map → worker-45WEWCMQ.js.map} +0 -0
@@ -10,10 +10,10 @@ import {
10
10
  saveExtractPages,
11
11
  setExtractJobTotal,
12
12
  settleExtractJob
13
- } from "./chunk-RUGJE5EB.js";
14
- import "./chunk-HL33CGJF.js";
13
+ } from "./chunk-TUSLATZY.js";
14
+ import "./chunk-HXGZMMW5.js";
15
15
  import "./chunk-M2S27J6Z.js";
16
- import "./chunk-GL4BW4CP.js";
16
+ import "./chunk-DZBGULWW.js";
17
17
  export {
18
18
  completeExtractJob,
19
19
  countSuccessfulPages,
@@ -27,4 +27,4 @@ export {
27
27
  setExtractJobTotal,
28
28
  settleExtractJob
29
29
  };
30
- //# sourceMappingURL=site-extract-repository-NVSZH35Y.js.map
30
+ //# sourceMappingURL=site-extract-repository-YNPXEZCB.js.map
@@ -3,19 +3,19 @@ import {
3
3
  createHarvestAttemptRecorder,
4
4
  harvestProblemResponse,
5
5
  serializeHarvestProblem
6
- } from "./chunk-HE2LQPJ2.js";
6
+ } from "./chunk-JBME5WJR.js";
7
7
  import {
8
8
  harvest
9
- } from "./chunk-2HDMYW4B.js";
9
+ } from "./chunk-ZJDANZTQ.js";
10
10
  import {
11
11
  browserServiceApiKey,
12
12
  runWithCostContext
13
- } from "./chunk-D7ZT27HY.js";
13
+ } from "./chunk-GMZFQRH2.js";
14
14
  import "./chunk-K443GQY5.js";
15
15
  import "./chunk-XGIPATLV.js";
16
16
  import {
17
17
  MC_COSTS
18
- } from "./chunk-HL33CGJF.js";
18
+ } from "./chunk-HXGZMMW5.js";
19
19
  import "./chunk-M2S27J6Z.js";
20
20
  import {
21
21
  claimPendingJob,
@@ -24,7 +24,7 @@ import {
24
24
  debitMc,
25
25
  failJob,
26
26
  listHarvestAttempts
27
- } from "./chunk-GL4BW4CP.js";
27
+ } from "./chunk-DZBGULWW.js";
28
28
 
29
29
  // src/api/webhook.ts
30
30
  async function deliverWebhook(url, payload, retries = 3) {
@@ -132,4 +132,4 @@ export {
132
132
  startWorker,
133
133
  tickOnce
134
134
  };
135
- //# sourceMappingURL=worker-AM2DHUWG.js.map
135
+ //# sourceMappingURL=worker-45WEWCMQ.js.map
@@ -1,12 +1,12 @@
1
1
  {
2
- "generatedAt": "2026-07-13T04:02:37.913Z",
2
+ "generatedAt": "2026-07-14T17:00:17.517Z",
3
3
  "generatedFrom": "dist/bin/mcp-stdio-server.js",
4
4
  "serverInfo": {
5
5
  "name": "mcp-scraper",
6
- "version": "0.19.0"
6
+ "version": "0.21.0"
7
7
  },
8
8
  "counts": {
9
- "unified_stdio": 158
9
+ "unified_stdio": 159
10
10
  },
11
11
  "surfaces": {
12
12
  "unified_stdio": [
@@ -55,6 +55,7 @@
55
55
  "call_service_connection_action",
56
56
  "capture_serp_page_snapshots",
57
57
  "capture_serp_snapshot",
58
+ "check_site_export",
58
59
  "cost-usage",
59
60
  "create-channel",
60
61
  "create-scheduled-action",
@@ -1702,6 +1703,16 @@
1702
1703
  "minimum": 1,
1703
1704
  "maximum": 100,
1704
1705
  "description": "When rotateProxies is on, pages fetched per proxy before rotating. Default 30."
1706
+ },
1707
+ "background": {
1708
+ "type": "boolean",
1709
+ "default": false,
1710
+ "description": "Run the audit as a background job instead of blocking this call, returning a jobId immediately — poll it with check_site_export to get a downloadable zip (full audit report, all page content, plus real image files if downloadImages is set) once ready. Use for large sites where a synchronous call would be slow."
1711
+ },
1712
+ "downloadImages": {
1713
+ "type": "boolean",
1714
+ "default": false,
1715
+ "description": "Download every discovered image as a real file into the export bundle (not just image URLs/stats). OFF by default — must be explicitly set true. Implies background regardless of the background flag, since downloading a whole site's images is too slow to run synchronously. Capped at 20 images/page and 500 images/site."
1705
1716
  }
1706
1717
  },
1707
1718
  "required": [
@@ -1718,23 +1729,27 @@
1718
1729
  },
1719
1730
  "pageCount": {
1720
1731
  "type": "integer",
1721
- "minimum": 0
1732
+ "minimum": 0,
1733
+ "description": "Absent when background is true — the audit has not finished yet."
1722
1734
  },
1723
1735
  "durationMs": {
1724
1736
  "type": "number",
1725
- "minimum": 0
1737
+ "minimum": 0,
1738
+ "description": "Absent when background is true — the audit has not finished yet."
1726
1739
  },
1727
1740
  "bulkFolder": {
1728
1741
  "type": [
1729
1742
  "string",
1730
1743
  "null"
1731
- ]
1744
+ ],
1745
+ "description": "Absent when background is true — the audit has not finished yet."
1732
1746
  },
1733
1747
  "issues": {
1734
1748
  "type": "object",
1735
1749
  "additionalProperties": {
1736
1750
  "type": "number"
1737
- }
1751
+ },
1752
+ "description": "Absent when background is true — the audit has not finished yet."
1738
1753
  },
1739
1754
  "images": {
1740
1755
  "type": "object",
@@ -1762,7 +1777,8 @@
1762
1777
  "over100kb",
1763
1778
  "legacyFormat"
1764
1779
  ],
1765
- "additionalProperties": false
1780
+ "additionalProperties": false,
1781
+ "description": "Absent when background is true — the audit has not finished yet."
1766
1782
  },
1767
1783
  "links": {
1768
1784
  "type": "object",
@@ -1795,7 +1811,8 @@
1795
1811
  "brokenInternal",
1796
1812
  "externalDomains"
1797
1813
  ],
1798
- "additionalProperties": false
1814
+ "additionalProperties": false,
1815
+ "description": "Absent when background is true — the audit has not finished yet."
1799
1816
  },
1800
1817
  "artifact": {
1801
1818
  "type": "object",
@@ -1821,16 +1838,25 @@
1821
1838
  "preview"
1822
1839
  ],
1823
1840
  "additionalProperties": false
1841
+ },
1842
+ "jobId": {
1843
+ "type": "string",
1844
+ "description": "Present when background (or downloadImages) was set — poll with check_site_export."
1845
+ },
1846
+ "status": {
1847
+ "type": "string",
1848
+ "enum": [
1849
+ "pending"
1850
+ ],
1851
+ "description": "Present when background (or downloadImages) was set."
1852
+ },
1853
+ "statusUrl": {
1854
+ "type": "string",
1855
+ "description": "Present when background (or downloadImages) was set — informational; use check_site_export with jobId, not this URL directly."
1824
1856
  }
1825
1857
  },
1826
1858
  "required": [
1827
- "url",
1828
- "pageCount",
1829
- "durationMs",
1830
- "bulkFolder",
1831
- "issues",
1832
- "images",
1833
- "links"
1859
+ "url"
1834
1860
  ],
1835
1861
  "additionalProperties": false,
1836
1862
  "$schema": "http://json-schema.org/draft-07/schema#"
@@ -4557,6 +4583,98 @@
4557
4583
  "taskSupport": "forbidden"
4558
4584
  }
4559
4585
  },
4586
+ {
4587
+ "name": "check_site_export",
4588
+ "title": "Check Site Export",
4589
+ "description": "Poll the status of a background extract_site or audit_site job (one started with background or downloadImages set). Returns a downloadable zip URL (all page content, plus real image files if downloadImages was set) once status is complete.",
4590
+ "inputSchema": {
4591
+ "type": "object",
4592
+ "properties": {
4593
+ "jobId": {
4594
+ "type": "string",
4595
+ "minLength": 1,
4596
+ "description": "The jobId returned by extract_site or audit_site when called with background (or downloadImages) set — poll this until status is \"complete\" (or \"failed\")."
4597
+ }
4598
+ },
4599
+ "required": [
4600
+ "jobId"
4601
+ ],
4602
+ "additionalProperties": false,
4603
+ "$schema": "http://json-schema.org/draft-07/schema#"
4604
+ },
4605
+ "outputSchema": {
4606
+ "type": "object",
4607
+ "properties": {
4608
+ "jobId": {
4609
+ "type": "string"
4610
+ },
4611
+ "status": {
4612
+ "type": "string",
4613
+ "enum": [
4614
+ "pending",
4615
+ "running",
4616
+ "complete",
4617
+ "failed"
4618
+ ]
4619
+ },
4620
+ "startUrl": {
4621
+ "type": "string"
4622
+ },
4623
+ "totalUrls": {
4624
+ "type": "integer",
4625
+ "minimum": 0
4626
+ },
4627
+ "doneUrls": {
4628
+ "type": "integer",
4629
+ "minimum": 0
4630
+ },
4631
+ "bundleUrl": {
4632
+ "type": [
4633
+ "string",
4634
+ "null"
4635
+ ],
4636
+ "description": "Downloadable zip URL once status is complete; null otherwise."
4637
+ },
4638
+ "bundleBytes": {
4639
+ "anyOf": [
4640
+ {
4641
+ "type": "integer",
4642
+ "minimum": 0
4643
+ },
4644
+ {
4645
+ "type": "null"
4646
+ }
4647
+ ],
4648
+ "description": "Zip size in bytes once status is complete; null otherwise."
4649
+ },
4650
+ "error": {
4651
+ "type": [
4652
+ "string",
4653
+ "null"
4654
+ ],
4655
+ "description": "Present with a message when status is failed."
4656
+ }
4657
+ },
4658
+ "required": [
4659
+ "jobId",
4660
+ "status",
4661
+ "bundleUrl",
4662
+ "bundleBytes"
4663
+ ],
4664
+ "additionalProperties": false,
4665
+ "$schema": "http://json-schema.org/draft-07/schema#"
4666
+ },
4667
+ "annotations": {
4668
+ "title": "Check Site Export",
4669
+ "readOnlyHint": true,
4670
+ "destructiveHint": false,
4671
+ "idempotentHint": false,
4672
+ "openWorldHint": true
4673
+ },
4674
+ "execution": {
4675
+ "taskSupport": "forbidden"
4676
+ }
4677
+ },
4560
4678
  {
4561
4679
  "name": "cost-usage",
4562
4680
  "title": "Cost & Usage",
@@ -4799,7 +4917,7 @@
4799
4917
  {
4800
4918
  "name": "create-scheduled-action",
4801
4919
  "title": "Create Scheduled Action",
4802
- "description": "Create a scheduled action in agent mode (default) or connection_sync mode. Agent mode asks an agent to follow the description and write a result into the target vault. connection_sync deterministically runs the approved read-only tools on bound service connections and ingests their data; it requires at least one connection to be bound before execution. Cadence 'once' runs a single time then completes permanently. Requires an active scheduling subscription and write access to the target vault.",
4920
+ "description": "Create a Credit-metered scheduled action in agent mode (default) or connection_sync mode. Each execution has a 75-Credit base charge; agent model usage is added at 1.5 times OpenRouter's actual reported cost. Agent mode follows the description and writes a result into the target vault. connection_sync deterministically runs approved read-only tools on bound service connections and ingests their data. Cadence 'once' runs a single time then completes permanently. Requires write access to the target vault.",
4803
4921
  "inputSchema": {
4804
4922
  "type": "object",
4805
4923
  "properties": {
@@ -4884,7 +5002,7 @@
4884
5002
  },
4885
5003
  "code": {
4886
5004
  "type": "string",
4887
- "description": "Machine-readable denial code: not_enabled when no scheduling subscription is active."
5005
+ "description": "Machine-readable denial code when creation is refused."
4888
5006
  }
4889
5007
  },
4890
5008
  "required": [
@@ -6749,6 +6867,16 @@
6749
6867
  ]
6750
6868
  },
6751
6869
  "description": "Per-page output formats: markdown, links, json, images are captured cheaply from HTML; branding (site-level logo/colors/fonts) requires a browser and adds time. Defaults to markdown+links."
6870
+ },
6871
+ "background": {
6872
+ "type": "boolean",
6873
+ "default": false,
6874
+ "description": "Run the crawl as a background job instead of blocking this call, returning a jobId immediately — poll it with check_site_export to get a downloadable zip (all page content, plus real image files if downloadImages is set) once ready. Use for large sites where a synchronous call would be slow."
6875
+ },
6876
+ "downloadImages": {
6877
+ "type": "boolean",
6878
+ "default": false,
6879
+ "description": "Download every discovered image as a real file into the export bundle (not just image URLs/stats). OFF by default — must be explicitly set true. Implies background regardless of the background flag, since downloading a whole site's images is too slow to run synchronously. Capped at 20 images/page and 500 images/site."
6752
6880
  }
6753
6881
  },
6754
6882
  "required": [
@@ -6765,7 +6893,8 @@
6765
6893
  },
6766
6894
  "pageCount": {
6767
6895
  "type": "integer",
6768
- "minimum": 0
6896
+ "minimum": 0,
6897
+ "description": "Absent when background is true — the crawl has not finished yet."
6769
6898
  },
6770
6899
  "pages": {
6771
6900
  "type": "array",
@@ -6794,11 +6923,13 @@
6794
6923
  "schemaTypes"
6795
6924
  ],
6796
6925
  "additionalProperties": false
6797
- }
6926
+ },
6927
+ "description": "Absent when background is true — the crawl has not finished yet."
6798
6928
  },
6799
6929
  "durationMs": {
6800
6930
  "type": "number",
6801
- "minimum": 0
6931
+ "minimum": 0,
6932
+ "description": "Absent when background is true — the crawl has not finished yet."
6802
6933
  },
6803
6934
  "truncatedCount": {
6804
6935
  "type": "integer",
@@ -6828,13 +6959,25 @@
6828
6959
  "preview"
6829
6960
  ],
6830
6961
  "additionalProperties": false
6962
+ },
6963
+ "jobId": {
6964
+ "type": "string",
6965
+ "description": "Present when background (or downloadImages) was set — poll with check_site_export."
6966
+ },
6967
+ "status": {
6968
+ "type": "string",
6969
+ "enum": [
6970
+ "pending"
6971
+ ],
6972
+ "description": "Present when background (or downloadImages) was set."
6973
+ },
6974
+ "statusUrl": {
6975
+ "type": "string",
6976
+ "description": "Present when background (or downloadImages) was set — informational; use check_site_export with jobId, not this URL directly."
6831
6977
  }
6832
6978
  },
6833
6979
  "required": [
6834
- "url",
6835
- "pageCount",
6836
- "pages",
6837
- "durationMs"
6980
+ "url"
6838
6981
  ],
6839
6982
  "additionalProperties": false,
6840
6983
  "$schema": "http://json-schema.org/draft-07/schema#"
@@ -8249,7 +8392,7 @@
8249
8392
  {
8250
8393
  "name": "get-schedule-status",
8251
8394
  "title": "Get Schedule Status",
8252
- "description": "Get your own Scheduled Actions subscription status: whether it is active, your monthly quota, and how much you have used this period.",
8395
+ "description": "Get the Credit-metered Scheduled Actions policy. Scheduling is included rather than sold as a separate subscription: each execution has a 75-Credit base charge, and agent model usage is billed at 1.5 times OpenRouter's actual reported cost.",
8253
8396
  "inputSchema": {
8254
8397
  "type": "object",
8255
8398
  "properties": {},
@@ -8264,6 +8407,16 @@
8264
8407
  "enabled": {
8265
8408
  "type": "boolean"
8266
8409
  },
8410
+ "billingMode": {
8411
+ "type": "string",
8412
+ "const": "credits"
8413
+ },
8414
+ "runBaseCredits": {
8415
+ "type": "number"
8416
+ },
8417
+ "llmCostMultiplier": {
8418
+ "type": "number"
8419
+ },
8267
8420
  "quotaPerPeriod": {
8268
8421
  "type": "number"
8269
8422
  },
@@ -16552,7 +16705,7 @@
16552
16705
  {
16553
16706
  "name": "set-schedule-entitlement",
16554
16707
  "title": "Set Schedule Entitlement",
16555
- "description": "Set whether an identity has an active Scheduled Actions subscription, its monthly execution quota, and (optionally) an mcp-scraper API key for scheduled actions to call mcp-scraper on their behalf. Called by mcp-scraper's Stripe webhook on subscribe/renew/cancel. Requires admin scope.",
16708
+ "description": "Legacy migration and account-recovery control for old Scheduled Actions entitlements. New scheduling is Credit-metered and does not require a separate subscription. This admin-only tool may preserve a legacy API-key delegation or recover historical entitlement rows during migration.",
16556
16709
  "inputSchema": {
16557
16710
  "type": "object",
16558
16711
  "properties": {
@@ -16567,7 +16720,7 @@
16567
16720
  },
16568
16721
  "quotaPerPeriod": {
16569
16722
  "type": "number",
16570
- "description": "Monthly execution quota. Optional; defaults to 1000, or leaves the existing value unchanged if already set."
16723
+ "description": "Legacy monthly execution quota retained only for historical-row compatibility; it does not price new Credit-metered runs."
16571
16724
  },
16572
16725
  "mcpScraperApiKey": {
16573
16726
  "type": "string",
@@ -2,20 +2,20 @@
2
2
 
3
3
  - **Request:** Replace the brittle manual path from a connected Meta ad-account ad to visible creative images, playable/transcribable video, and trustworthy analysis signals. Preserve the generic connected-service tools, but make the correct path directly discoverable and callable from the external MCP and scheduled Mastra agents.
4
4
  - **Lane:** MCP Build using Mastra, with a provider-native Nango read primitive and an external MCP composition tool.
5
- - **Capability:** `meta_ad_creative_media` for media buyers, ad directors, analysts, and agents. Given a tenant-owned Meta connection plus an `adId` or creative reference, return the resolved creative media, render bounded images as MCP image content, and optionally transcribe or start frame analysis for the video.
5
+ - **Capability:** `meta_ad_creative_media` for media buyers, ad directors, analysts, and agents. Given a tenant-owned Meta connection plus an `adId`, return the resolved creative media, render bounded images as MCP image content, and provide exact explicit follow-up calls for video transcription or frame analysis when video media is present.
6
6
  - **Inputs:** This report; the MCP Scraper, scheduler, Nango integration, and SDK repositories; current Meta Graph API behavior; current MCP content/result specification; existing `facebook_page_intel`, `facebook_ad_transcribe`, `facebook_video_transcribe`, `video_frame_analysis`, `get-ad`, `get-ad-creative`, `get-ad-image`, and `get-ad-video` implementations.
7
7
  - **Missing Context:** None that blocks implementation. Default behavior is read-only resolution with image inclusion. Transcription and frame analysis are explicit opt-ins because they spend credits; ad mutations remain outside this tool.
8
8
  - **Evidence Plan:** Inspect current source and live schemas; verify Meta media fields against primary sources; verify MCP image content against the protocol/SDK; test a connected Meta ad when a safe fixture or user-owned ad ID is available; never run a write operation during verification.
9
9
  - **Target Runtime:** `mcp-scraper` hosted MCP and npm stdio package; `mcp-scraper-scheduler` on Vercel/Mastra; source-controlled Nango functions deployed to the Meta Marketing integration; generated Node/Python/CLI/cURL SDK contracts.
10
10
  - **Agents:** Existing scheduled-action Mastra agent receives the provider-native resolver through its per-run connection toolset. No new supervisor or model route is required; creative interpretation remains with the calling vision-capable model.
11
11
  - **Skills:** Existing MCP Scraper and Mastra operating guidance. No new workspace skill is required.
12
- - **Workflows:** Resolve ad and creative deterministically; collect bounded media descriptors; derive durable organic post/reel candidates; hydrate image/video metadata; attach safe image bytes; optionally call the appropriate transcription route or start the existing asynchronous video-frame analysis workflow.
12
+ - **Workflows:** Resolve ad and creative deterministically; collect bounded media descriptors; derive organic post/reel candidates; hydrate image/video metadata; attach safe image bytes; recommend the appropriate explicit transcription route or existing asynchronous video-frame analysis workflow without spending those credits inside the read tool.
13
13
  - **Tools:**
14
14
  - Provider read: `resolve-ad-creative-media` in the Meta Nango integration.
15
15
  - External MCP composition: `meta_ad_creative_media`.
16
16
  - Existing lower-level tools remain available and cross-reference the new path.
17
17
  - **MCP:** `meta_ad_creative_media` returns text plus structured content. Successfully fetched creative images are additional MCP `image` content blocks with MIME type and base64 data. Videos remain URL/metadata plus transcript or asynchronous analysis receipt; raw video is not embedded in context.
18
- - **Data Shape:** Stable media descriptor with ad/creative IDs, account/page/post IDs, public post URL, media type, image assets, video assets, selected transcription route, transcript signal, warnings, and next actions. Image content indices map descriptors to MCP content blocks.
18
+ - **Data Shape:** Stable media descriptor with ad/creative IDs, account/page/post IDs, unverified public-post candidate, media type, image assets, video assets, selected follow-up route, warnings, limitations, and next actions. Image content indices map descriptors to MCP content blocks. Transcript calls separately return their transcript signal.
19
19
  - **Signals:** Not required. Video frame analysis continues through its existing asynchronous status tool.
20
20
  - **Background Tasks:** Resolution and transcription are foreground bounded calls. Deep video analysis uses the existing asynchronous `video_frame_analysis` run/status path.
21
21
  - **Guardrails:** Tenant ownership and live provider policy; read-only provider function; explicit opt-in for credit-spending work; SSRF-safe HTTPS image fetching; Meta/CDN host allowlist; redirect validation; MIME allowlist; per-image and image-count limits; no tokens or signed query strings in logs; untrusted-provider-data labeling; action switch is not required for reads.