@sellable/mcp 0.1.901 → 0.1.902

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.
@@ -16,7 +16,7 @@ export type WaitForCliLoginInput = {
16
16
  /** Test-only: override poll interval. Not exposed in inputSchema. */
17
17
  pollIntervalMs?: number;
18
18
  };
19
- type CliLoginErrorType = "rate_limited" | "send_failed" | "expired" | "already_consumed" | "timeout" | "tool_timeout_guard" | "network_error" | "not_implemented";
19
+ type CliLoginErrorType = "rate_limited" | "send_failed" | "expired" | "already_consumed" | "timeout" | "tool_timeout_guard" | "network_error" | "managed_agent_service_credential" | "not_implemented";
20
20
  type CliLoginErrorPayload = {
21
21
  ok: false;
22
22
  error: {
@@ -1,4 +1,4 @@
1
- import { writeNewConfig } from "../auth.js";
1
+ import { getConfiguredCredentialIntent, writeNewConfig } from "../auth.js";
2
2
  /**
3
3
  * Sellable CLI login tools.
4
4
  *
@@ -58,6 +58,13 @@ function resolveApiUrl() {
58
58
  process.env.SELLABLE_BASE_URL ??
59
59
  "https://app.sellable.dev");
60
60
  }
61
+ function managedAgentAlreadyAuthenticated() {
62
+ return (process.env.SELLABLE_AGENT_RUNTIME === "1" &&
63
+ getConfiguredCredentialIntent() === "agent_service");
64
+ }
65
+ function managedAgentLoginRefusal() {
66
+ return errorPayload("managed_agent_service_credential", "This managed Agent is already authenticated.", "Use the connected integration directly. A browser login would replace the Agent's scoped service credential and is not allowed.");
67
+ }
61
68
  export const startCliLoginToolDef = {
62
69
  name: "start_cli_login",
63
70
  description: "Start the CLI login handoff. Triggers a magic-link email to the supplied email address. " +
@@ -97,6 +104,9 @@ export const waitForCliLoginToolDef = {
97
104
  },
98
105
  };
99
106
  export async function handleStartCliLogin(args) {
107
+ if (managedAgentAlreadyAuthenticated()) {
108
+ return managedAgentLoginRefusal();
109
+ }
100
110
  const apiUrl = resolveApiUrl();
101
111
  let res;
102
112
  try {
@@ -174,6 +184,9 @@ export async function handleWaitForCliLogin(args) {
174
184
  continue;
175
185
  }
176
186
  if (body.status === "ready") {
187
+ if (managedAgentAlreadyAuthenticated()) {
188
+ return managedAgentLoginRefusal();
189
+ }
177
190
  const { configPath } = writeNewConfig({
178
191
  token: body.token,
179
192
  activeWorkspaceId: body.activeWorkspaceId,
@@ -364,6 +364,9 @@ export function toolError(action, error) {
364
364
  catch {
365
365
  // Plain-text body; fall through to the generic shape below.
366
366
  }
367
+ const structuredRouteRefusal = typeof forwarded.error === "string" ||
368
+ typeof forwarded.outcome === "string" ||
369
+ typeof forwarded.attribution === "string";
367
370
  return envelope({
368
371
  ok: false,
369
372
  outcome: typeof forwarded.outcome === "string" ? forwarded.outcome : "refused",
@@ -377,7 +380,9 @@ export function toolError(action, error) {
377
380
  : `integration_${action}_failed`,
378
381
  guidance: typeof forwarded.guidance === "string"
379
382
  ? forwarded.guidance
380
- : (error.guidance ?? null),
383
+ : structuredRouteRefusal
384
+ ? null
385
+ : (error.guidance ?? null),
381
386
  result: forwarded.detail ?? null,
382
387
  });
383
388
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.901",
3
+ "version": "0.1.902",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code, Codex, and Hermes campaign workflows",
6
6
  "main": "dist/index.js",