@chainpatrol/mcp 1.10.0 → 1.10.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @chainpatrol/mcp
2
2
 
3
+ ## 1.10.2
4
+
5
+ ### Patch Changes
6
+
7
+ - aa164fd: Fixed the MCP handshake `instructions` to reflect the tools actually exposed
8
+ when a server is narrowed with `only` (the CLI's `--tools` flag, or a caller
9
+ like the web app's blocklist-only endpoint). Previously every server —
10
+ narrowed or not — advertised the full-API instructions and told the client to
11
+ call `user_orgs` first, even when `user_orgs` wasn't in the exposed tool set.
12
+ A client following that advice would hit "unknown tool" before ever reaching
13
+ the tool it wanted. Supporting work in `@chainpatrol/web` (a new
14
+ blocklist-only MCP route) is a private package and doesn't need a version
15
+ bump.
16
+ - adce1d5: The MCP server now reports its real version in the initialize handshake.
17
+
18
+ `PACKAGE_VERSION` was a hand-maintained literal that changesets does not
19
+ know about, so it went stale on every release: 1.10.1 shipped announcing
20
+ itself as `1.10.0`, the same drift #7804 had already corrected once. It is
21
+ now read from package.json and inlined by tsup at build time, so the
22
+ published server still does no filesystem lookup and the two cannot
23
+ disagree again.
24
+
25
+ ## 1.10.1
26
+
27
+ ### Patch Changes
28
+
29
+ - a6ffc93: The `attachmentUrls` argument on `report_create` is no longer described as images only.
30
+ It has always accepted a URL to any file, but the description read "URLs of images to
31
+ attach to the report", which led API clients to believe evidence files such as `.eml`
32
+ messages were out of scope and had to be left out or hosted elsewhere.
33
+
34
+ It now says that any file type is accepted and points at `POST /attachment/upload` for
35
+ callers who want to send us the bytes rather than host the file themselves. No behaviour
36
+ changes — the schema still accepts the same array of URLs. The wording comes from
37
+ @chainpatrol/validation, a private package, and reaches the manifest and the published
38
+ OpenAPI spec through the external API router.
39
+
40
+ - 4481e9c: Filtering reports by `reviewStatuses: ["ESCALATE"]` now matches proposals escalated to
41
+ the customer. The filter previously read `Proposal.isEscalated`, which is only written
42
+ for team escalations, so customer escalations were invisible to it. It now also matches
43
+ a live `ESCALATE` review, the way `SKIP` already reads review history.
44
+
45
+ Expect larger result sets and higher report counts for organizations that use customer
46
+ escalations. The same fix applies to the report list, the per-status counts, and the CSV
47
+ export, backed by changes in the private packages @chainpatrol/core, @chainpatrol/trpc,
48
+ and @chainpatrol/external-trpc. The generated MCP tool manifest picks up a new
49
+ description for the `reviewStatuses` argument spelling out which options read current
50
+ status and which read review history.
51
+
3
52
  ## 1.10.0
4
53
 
5
54
  ### Minor Changes
@@ -622,7 +622,7 @@ var tools_default = {
622
622
  },
623
623
  source: {
624
624
  type: "string",
625
- description: "Detection source key, from `GET /detection/sources`. The source must support the `organization` scope; global-only sources cannot be configured per organization. One of 55 values, e.g. meta_ads_search, telegram_channels_search, telegram_user_search, telegram_channels_search_vetric, telegram_user_search_vetric, facebook_page_search_vetric, facebook_user_search_vetric, instagram_account_search_vetric. Full list: resource chainpatrol://enums/source"
625
+ description: "Detection source key, from `GET /detection/sources`. The source must support the `organization` scope; global-only sources cannot be configured per organization. One of 57 values, e.g. meta_ads_search, telegram_channels_search, telegram_user_search, telegram_channels_search_vetric, telegram_user_search_vetric, facebook_page_search_vetric, facebook_user_search_vetric, facebook_post_search_vetric. Full list: resource chainpatrol://enums/source"
626
626
  },
627
627
  status: {
628
628
  type: "string",
@@ -1023,7 +1023,7 @@ var tools_default = {
1023
1023
  },
1024
1024
  filters: {
1025
1025
  type: "array",
1026
- description: "Filters to apply to the results. Each clause filters on one property. Accepted values per property \u2014 `source`: One of 55 values, e.g. meta_ads_search, telegram_channels_search, telegram_user_search, telegram_channels_search_vetric, telegram_user_search_vetric, facebook_page_search_vetric, facebook_user_search_vetric, instagram_account_search_vetric. Full list: resource chainpatrol://enums/source; `confidence`: none, low, medium, high; `liveness`: UNKNOWN, ALIVE, DEAD; `watchlist`: ENABLED, DISABLED; `assetStatus`: UNKNOWN, ALLOWED, BLOCKED; `reported`: reported, not_reported; `assetType`: One of 92 values, e.g. URL, PAGE, ADDRESS, DISCORD, LINKEDIN, TWITTER, FACEBOOK, YOUTUBE. Full list: resource chainpatrol://enums/asset_type; `brand`: number values; `deleted`: string values; `countryCode`: string values.",
1026
+ description: "Filters to apply to the results. Each clause filters on one property. Accepted values per property \u2014 `source`: One of 57 values, e.g. meta_ads_search, telegram_channels_search, telegram_user_search, telegram_channels_search_vetric, telegram_user_search_vetric, facebook_page_search_vetric, facebook_user_search_vetric, facebook_post_search_vetric. Full list: resource chainpatrol://enums/source; `confidence`: none, low, medium, high; `liveness`: UNKNOWN, ALIVE, DEAD; `watchlist`: ENABLED, DISABLED; `assetStatus`: UNKNOWN, ALLOWED, BLOCKED; `reported`: reported, not_reported; `assetType`: One of 92 values, e.g. URL, PAGE, ADDRESS, DISCORD, LINKEDIN, TWITTER, FACEBOOK, YOUTUBE. Full list: resource chainpatrol://enums/asset_type; `brand`: number values; `deleted`: string values; `countryCode`: string values.",
1027
1027
  items: {
1028
1028
  type: "object",
1029
1029
  properties: {
@@ -3016,7 +3016,8 @@ var tools_default = {
3016
3016
  "SKIP",
3017
3017
  "ESCALATE"
3018
3018
  ]
3019
- }
3019
+ },
3020
+ description: "Filter to reports with at least one proposal matching any of these review outcomes. `APPROVE` and `REJECT` match the proposal's current review status. `SKIP` and `ESCALATE` match the review history, so a proposal that was escalated still matches after the escalation is answered."
3020
3021
  },
3021
3022
  assetTypes: {
3022
3023
  type: "array",
@@ -3111,7 +3112,7 @@ var tools_default = {
3111
3112
  type: "string",
3112
3113
  format: "uri"
3113
3114
  },
3114
- description: "URLs of images to attach to the report"
3115
+ description: "URLs of files to attach to the report as evidence. Any file type, not only images: .eml/.msg messages, PDFs, and documents are all supported. Upload a file to POST /attachment/upload to get a URL, or pass a publicly reachable URL you host yourself."
3115
3116
  },
3116
3117
  externalSubmissionLink: {
3117
3118
  type: "string",
@@ -3165,7 +3166,7 @@ var tools_default = {
3165
3166
  properties: {
3166
3167
  type: {
3167
3168
  type: "string",
3168
- description: "Enrichment type One of 39 values, e.g. content_and_metadata, browser_capture, ownership_and_registration, geolocation_and_ip, dns, tls, tcp, post. Full list: resource chainpatrol://enums/asset_scan_enrichment_type"
3169
+ description: "Enrichment type One of 40 values, e.g. content_and_metadata, browser_capture, ownership_and_registration, geolocation_and_ip, dns, tls, tcp, post. Full list: resource chainpatrol://enums/asset_scan_enrichment_type"
3169
3170
  },
3170
3171
  source: {
3171
3172
  type: "string",
@@ -3990,6 +3991,7 @@ var tools_default = {
3990
3991
  "linkedin_profile",
3991
3992
  "meta_ad",
3992
3993
  "google_ad",
3994
+ "adlibrary_ad",
3993
3995
  "contract_deployer"
3994
3996
  ],
3995
3997
  usedBy: [
@@ -4115,6 +4117,7 @@ var tools_default = {
4115
4117
  "telegram_user_search_vetric",
4116
4118
  "facebook_page_search_vetric",
4117
4119
  "facebook_user_search_vetric",
4120
+ "facebook_post_search_vetric",
4118
4121
  "instagram_account_search_vetric",
4119
4122
  "twitter_search_vetric",
4120
4123
  "linkedin_people_search_vetric",
@@ -4160,6 +4163,7 @@ var tools_default = {
4160
4163
  "linkedin_company_search",
4161
4164
  "bing_ads_search",
4162
4165
  "tik_tok_ads_search",
4166
+ "adlibrary_ads_search",
4163
4167
  "dnsdb",
4164
4168
  "daily_motion_search",
4165
4169
  "watchlist"
@@ -4220,6 +4224,17 @@ function toErrorResult(error) {
4220
4224
  content: [{ type: "text", text: message }]
4221
4225
  };
4222
4226
  }
4227
+ var RESOURCE_HINT = "Where a parameter's description points at a `chainpatrol://` resource, read it before guessing a value.";
4228
+ function buildInstructions(tools, isNarrowed) {
4229
+ if (!isNarrowed) {
4230
+ return "ChainPatrol threat intelligence and brand protection. Every public API capability is available here as a tool: checking and searching assets, reports, proposals, detections, takedowns, metrics, healthchecks and organization management.\n\nMost tools are scoped to one organization. Credentials can reach more than one, and there is no implicit default, so call `user_orgs` first and pass the slug explicitly.\n\n" + RESOURCE_HINT;
4231
+ }
4232
+ const names = tools.map((tool) => tool.name).sort().join(", ");
4233
+ const orgScoping = tools.some((tool) => tool.name === "user_orgs") ? "Most tools are scoped to one organization. Credentials can reach more than one, and there is no implicit default, so call `user_orgs` first and pass the slug explicitly.\n\n" : "These tools resolve their organization from the credential in use \u2014 there is no org slug to pass.\n\n";
4234
+ return `ChainPatrol threat intelligence. This server exposes a narrowed set of tools: ${names}.
4235
+
4236
+ ${orgScoping}${RESOURCE_HINT}`;
4237
+ }
4223
4238
  function createChainPatrolMcpServer(options) {
4224
4239
  const tools = selectTools(options.only);
4225
4240
  const resources = buildResources(manifest, tools);
@@ -4228,6 +4243,7 @@ function createChainPatrolMcpServer(options) {
4228
4243
  tools.map((tool) => tool.name)
4229
4244
  );
4230
4245
  const byName = new Map(tools.map((tool) => [tool.name, tool]));
4246
+ const isNarrowed = Boolean(options.only && options.only.length > 0);
4231
4247
  const server = new Server(
4232
4248
  {
4233
4249
  name: options.serverName ?? "chainpatrol",
@@ -4235,7 +4251,7 @@ function createChainPatrolMcpServer(options) {
4235
4251
  },
4236
4252
  {
4237
4253
  capabilities: { tools: {}, resources: {}, prompts: {} },
4238
- instructions: "ChainPatrol threat intelligence and brand protection. Every public API capability is available here as a tool: checking and searching assets, reports, proposals, detections, takedowns, metrics, healthchecks and organization management.\n\nMost tools are scoped to one organization. Credentials can reach more than one, and there is no implicit default, so call `user_orgs` first and pass the slug explicitly.\n\nWhere a parameter's description points at a `chainpatrol://` resource, read it before guessing a value."
4254
+ instructions: buildInstructions(tools, isNarrowed)
4239
4255
  }
4240
4256
  );
4241
4257
  server.setRequestHandler(ListToolsRequestSchema, () => ({
@@ -4448,8 +4464,73 @@ function toolsFromEnvironment(env = process.env) {
4448
4464
  return names.length > 0 ? names : void 0;
4449
4465
  }
4450
4466
 
4467
+ // package.json
4468
+ var package_default = {
4469
+ name: "@chainpatrol/mcp",
4470
+ description: "The official ChainPatrol MCP server \u2014 every public API capability as an MCP tool",
4471
+ author: "ChainPatrol <support@chainpatrol.io>",
4472
+ version: "1.10.2",
4473
+ license: "UNLICENSED",
4474
+ homepage: "https://chainpatrol.com/docs/mcp",
4475
+ keywords: [
4476
+ "chainpatrol",
4477
+ "mcp",
4478
+ "model-context-protocol",
4479
+ "agent"
4480
+ ],
4481
+ type: "module",
4482
+ exports: {
4483
+ ".": {
4484
+ types: "./dist/index.d.ts",
4485
+ import: "./dist/index.js"
4486
+ },
4487
+ "./config": {
4488
+ types: "./dist/chainpatrol-config.d.ts",
4489
+ import: "./dist/chainpatrol-config.js"
4490
+ }
4491
+ },
4492
+ bin: {
4493
+ "chainpatrol-mcp": "./dist/stdio-bin.js"
4494
+ },
4495
+ files: [
4496
+ "./dist/**"
4497
+ ],
4498
+ publishConfig: {
4499
+ access: "public",
4500
+ provenance: false
4501
+ },
4502
+ scripts: {
4503
+ build: "tsup",
4504
+ dev: "tsup --watch",
4505
+ "tools:generate": "tsx scripts/generate-tools.ts",
4506
+ "tools:check": "tsx scripts/generate-tools.ts --check",
4507
+ typecheck: "tsc --noEmit",
4508
+ test: "vitest run --config vitest.config.unit.ts",
4509
+ "lint:eslint": "eslint . --flag unstable_native_nodejs_ts_config --cache --cache-location .cache/.eslintcache",
4510
+ lint: "npx oxlint ."
4511
+ },
4512
+ dependencies: {
4513
+ "@modelcontextprotocol/sdk": "catalog:",
4514
+ luxon: "catalog:",
4515
+ zod: "catalog:"
4516
+ },
4517
+ devDependencies: {
4518
+ "@chainpatrol/eslint-config": "workspace:*",
4519
+ "@chainpatrol/external-trpc": "workspace:*",
4520
+ "@chainpatrol/tsconfig": "workspace:*",
4521
+ "@types/luxon": "catalog:",
4522
+ "@types/node": "catalog:",
4523
+ eslint: "catalog:",
4524
+ tsup: "^8.5.0",
4525
+ tsx: "catalog:",
4526
+ typescript: "catalog:",
4527
+ vitest: "catalog:",
4528
+ "zod-to-json-schema": "^3.24.5"
4529
+ }
4530
+ };
4531
+
4451
4532
  // src/version.ts
4452
- var PACKAGE_VERSION = "1.10.0";
4533
+ var PACKAGE_VERSION = package_default.version;
4453
4534
 
4454
4535
  export {
4455
4536
  PROMPTS,
@@ -4465,4 +4546,4 @@ export {
4465
4546
  toolsFromEnvironment,
4466
4547
  PACKAGE_VERSION
4467
4548
  };
4468
- //# sourceMappingURL=chunk-AHMNJBKL.js.map
4549
+ //# sourceMappingURL=chunk-JBDTADFL.js.map