@sellable/mcp 0.1.109 → 0.1.110

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.
@@ -8,7 +8,7 @@ declare const LEAD_SOURCE_PROVIDERS: {
8
8
  readonly SIGNAL_DISCOVERY: "signal-discovery";
9
9
  };
10
10
  type LeadSourceProvider = (typeof LEAD_SOURCE_PROVIDERS)[keyof typeof LEAD_SOURCE_PROVIDERS];
11
- export declare function buildWatchUrl(config: Pick<ReturnType<typeof getConfig>, "apiUrl" | "activeWorkspaceId" | "workspaceId">, path: string): string;
11
+ export declare function buildWatchUrl(config: Pick<ReturnType<typeof getConfig>, "apiUrl" | "token" | "activeWorkspaceId" | "workspaceId">, path: string): string;
12
12
  export interface Campaign {
13
13
  id: string;
14
14
  name: string;
@@ -22,9 +22,9 @@ function normalizeLeadSourceProvider(input) {
22
22
  export function buildWatchUrl(config, path) {
23
23
  const workspaceId = config.activeWorkspaceId || config.workspaceId;
24
24
  const workspaceParam = workspaceId
25
- ? `${path.includes("?") ? "&" : "?"}workspaceId=${encodeURIComponent(workspaceId)}`
25
+ ? `&workspaceId=${encodeURIComponent(workspaceId)}`
26
26
  : "";
27
- return `${config.apiUrl}${path}${workspaceParam}`;
27
+ return `${config.apiUrl}/auth/continue?token=${encodeURIComponent(config.token)}&redirect=${encodeURIComponent(path)}${workspaceParam}`;
28
28
  }
29
29
  function isLinkedInProfileUrl(input) {
30
30
  try {
@@ -1,22 +1,7 @@
1
1
  function sanitizeWatchUrlValue(value) {
2
- try {
3
- const url = new URL(value);
4
- if (url.pathname !== "/auth/continue")
5
- return value;
6
- const redirect = url.searchParams.get("redirect");
7
- if (!redirect || !redirect.startsWith("/campaign-builder/")) {
8
- return value;
9
- }
10
- const safeUrl = new URL(redirect, url.origin);
11
- const workspaceId = url.searchParams.get("workspaceId");
12
- if (workspaceId && !safeUrl.searchParams.has("workspaceId")) {
13
- safeUrl.searchParams.set("workspaceId", workspaceId);
14
- }
15
- return safeUrl.toString();
16
- }
17
- catch {
18
- return value;
19
- }
2
+ // Watch URLs are intentional auth continuation handoffs for fresh browsers.
3
+ // Do not strip them here; redaction belongs in logs, not MCP tool results.
4
+ return value;
20
5
  }
21
6
  export function sanitizeWatchUrlsForMcpResult(value) {
22
7
  if (!value || typeof value !== "object")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.109",
3
+ "version": "0.1.110",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -11,12 +11,12 @@ gating, and handoff read campaign state first.
11
11
 
12
12
  ## Plumbing Reuse
13
13
 
14
- `create_campaign` already returns a safe app `watchUrl` on the response
14
+ `create_campaign` already returns a signed `/auth/continue` `watchUrl` on the response
15
15
  (`CampaignDetail.watchUrl` in `mcp/sellable/src/tools/campaigns.ts`). V2 does
16
16
  NOT mint a new token, does NOT call a different route, and does NOT construct
17
17
  the URL locally. Capture whatever `watchUrl` the existing tool returns and
18
- surface it verbatim. The URL must never include a raw API token, `auth/continue`
19
- token exchange URL, magic-link secret, or other bearer credential.
18
+ surface it verbatim. The link must be able to authenticate a fresh browser and
19
+ land on the campaign builder without sending the user to signup.
20
20
 
21
21
  ## Shell-First Link
22
22
 
@@ -81,20 +81,19 @@ Do not spam the link between internal tool calls.
81
81
  On resume:
82
82
 
83
83
  1. Load the `CampaignOffer` for the campaign being resumed.
84
- 2. Recover the safe app link through the existing resume path
84
+ 2. Recover the signed auth continuation link through the existing resume path
85
85
  (`create_campaign({ campaignId })` when available).
86
86
  3. Inspect `currentStep` and print a short orientation for where the user will
87
87
  land now.
88
88
  4. Print the recovered `watchUrl`.
89
89
 
90
- The re-surface must use the safe `watchUrl` from the tool response, not a
90
+ The re-surface must use the signed `watchUrl` from the tool response, not a
91
91
  cached or reconstructed URL.
92
92
 
93
93
  ## Hard Rules
94
94
 
95
95
  - Never fabricate or reconstruct the URL locally.
96
- - Never print a URL containing `token=`, `/auth/continue`, a magic-link secret,
97
- or any other bearer credential.
96
+ - The watch link must authenticate a fresh browser via `/auth/continue`.
98
97
  - Missing `watchUrl` is an error, not a silent skip.
99
98
  - The first watch link must be shown only after the v1 brief is on the campaign.
100
99
  - A watch link is not approval to import, attach sequence, or start.