Skip to content

Latest commit

 

History

History
117 lines (98 loc) · 6.99 KB

FLOW.md

File metadata and controls

117 lines (98 loc) · 6.99 KB

Data & call flow — AgentStack Cursor plugin

Gene: repo.plugins.oauth_device_code.gen1 · repo.plugins.hooks.contract.gen1 · repo.plugins.capability_routing.gen1
Version: 0.4.24 · Start here for install → MCP → hooks; one-pager: MCP_QUICKSTART.md

Repo layout (Cursor 2.6+)

Path Role
.cursor-plugin/marketplace.json Required for Cursor “Add marketplace” / GitHub install (pluginRoot: plugins, source: agentstack)
.cursor-plugin/listing.json AgentStack publisher SoT (screenshots, privacy, pricing) — not Cursor’s marketplace schema
plugins/agentstack/ Plugin package: plugin.json, URL-only mcp.json, rules, skills, commands, agents, hooks, assets, vendored kernel
scripts/ Validate / smoke / local install tooling
sequenceDiagram
  participant User
  participant Init as agentstack-init
  participant DC as device-code.mjs
  participant AS as agentstack.tech
  participant MCP as Cursor MCP client
  participant Hooks as hooks lifecycle
  participant Snap as agentstack-capabilities.json

  User->>Init: /agentstack-authorize (or sessionStart auto Device Code)
  Init->>DC: node hooks/scripts/device-code.mjs
  DC->>AS: POST /api/oauth2/device/authorize
  AS-->>DC: device_code + user_code
  User->>AS: /activate approve
  loop poll
    DC->>AS: POST /api/oauth2/token
    Note over AS: 400 + authorization_pending until approved
  end
  AS-->>DC: access_token (+ refresh_token when grant provides it; PAT is long-lived user_api_key)
  DC->>MCP: write ~/.cursor/mcp.json Bearer (agentstack-mcp.lock)
  DC->>MCP: sync plugin cache mcp.json Bearer (all marketplace copies)
  opt AGENTSTACK_MCP_CACHE_CLEAR=1
    DC->>AS: POST /mcp/cache/clear
  end
  DC->>AS: GET /mcp/actions (capability.lock — one fetch at a time)
  DC->>Snap: flat actions[] snapshot
  Hooks->>MCP: sessionStart Bearer rotate near expiry (refresh_token file) or Connect reminder
  Hooks->>Snap: refresh if older than 24h (same capability.lock)
  MCP->>AS: agentstack.execute steps
  Note over MCP,AS: tools/list can false-green — diagnose requires tools/call auth.get_profile
  Hooks->>Snap: beforeMCPExecution auth-bridge, session-handoff, cap-check, semantic-anchor
Loading

Artifacts on disk

Path Writer Reader
~/.cursor/mcp.json device-code, session-start Cursor MCP, hooks
~/.cursor/agentstack-refresh device-code, session-start session-start
~/.cursor/agentstack-capabilities.json device-code, session-start, capability-refresh pre-mcp-cap-check, diagnose
~/.cursor/agentstack-device.lock device-code session-start, diagnose
~/.cursor/agentstack-project /agentstack-login device-code, session-start
~/.cursor/agentstack-telemetry.jsonl post-tool-* (opt-in only) session-end flush, diagnose
~/.cursor/plugins/local/agentstack scripts/install-local.mjs Cursor local plugins
~/.cursor/plugins/cache/agentstack/… Cursor marketplace install Cursor may prefer this over local — must not ship $schema
~/.cursor/plugins/marketplaces/… Cursor “Add marketplace” snapshot Same — refresh with scripts/refresh-cursor-runtime.mjs --fix

Catalog shape

Live GET /mcp/actions returns { domains: { [name]: Entry[] }, total_actions }.
Local snapshot stores flat actions: Entry[] via tenantActionsFromCatalog (tenant-facing filter; mirrors doc_audience.py).

Validate / CI uses vendored docs/CAPABILITY_MATRIX.md plus scripts/lib/stale-actions.mjs — no monorepo-only imports in the publish repo.

Local health

node scripts/diagnose-local.mjs
node scripts/diagnose-local.mjs --fix --seed-snapshot

sessionStart (--from-hook from hooks.json) normalizes lean mcpServers.agentstack (drops ecosystem X-Project-ID=1, applies agentstack-project when it is a tenant), refreshes the flat capability snapshot when stale, and emits a compact auth card (profileBriefFromJwt — no /api/auth/me on session start). If the gate still needs login it spawns device-code.mjs once (lock file). Tests must not pass --from-hook. Live MCP health: node scripts/diagnose-local.mjs probes auth.get_profile via execute (not list-only). Logs go to stderr; stdout is JSON. Stale marketplace cache: scripts/refresh-cursor-runtime.mjs --fix. Same card: /agentstack-status.

MCP registration plane (0.4.24)

Plugin panel: plugin.json mcpServers: "./mcp.json" → URL-only streamable-http (no Bearer, no variables API-key form). Cursor shows AgentStack MCP — click Connect (G-A174 login). Status: sessionStart card + /agentstack-status. Hooks / Device Code: /agentstack-authorize still writes ~/.cursor/mcp.json (user-agentstack). Forbidden: ${AGENTSTACK_ACCESS_TOKEN} or any Authorization in the shipped plugin mcp.json (G-A162), an inline mcpServers object in plugin.json, and variables.AGENTSTACK_ACCESS_TOKEN (old Configure window).

flowchart LR
  subgraph forbidden [Anti-pattern]
    PH["plugin mcp.json Authorization placeholder"]
    PH --> CS1[empty plugin-agentstack-*]
  end
  subgraph pluginPlane [Plugin 0.4.24]
    PJ["plugin.json mcpServers ./mcp.json"]
    PJ --> MCPF[URL-only mcp.json]
    MCPF --> CS3[plugin AgentStack MCP]
    CS3 --> CON[Connect G-A174]
  end
  subgraph userPlane [Device Code]
    DC[device-code.mjs]
    DC --> UM[~/.cursor/mcp.json]
    UM --> CS2[user-agentstack]
  end
  CS3 --> TL[tools/list: 1 tool]
  CS2 --> TL
  TL --> AC[GET /mcp/actions catalog]
Loading
Anti-pattern Symptom Fix
Empty Bearer in plugin mcp.json discovery.list OK, execute unauthorized 0.4.24 URL-only file; Reload; Connect
Inline mcpServers object in plugin.json Duplicate / broken registration Path string ./mcp.json only
Stale marketplace cache Old plugin without MCP or with placeholder refresh-cursor-runtime.mjs --fix
Backend lists 2 tools Two agentstack_execute in tools panel Deploy core 0.4.16
projects.get_project in chat DNA protected / provider keys in the model transcript (G-A175) Prefer auth.get_profile / projects.get_stats; list with projects.get_projects (accessible_only default, honor limit)
Cursor mcp_auth from the agent Wrong client / login loop User clicks Connect on plugin MCP (G-A174). Agent does not call mcp_auth.
MCP tool-call chip has no logo Cursor loads marketplace cache (not the git tree). Cache still had white logo.svg. SVG gradients often rasterize empty. user-agentstack chips ignore SEP-973. SoT logo = assets/logo.png. refresh-cursor-runtime.mjs --fix copies PNG + plugin.json into ~/.cursor/plugins/cache. Reload Window. Plugin Connect.

Plugin ships plugins/agentstack/mcp.json (OAuth URL-only). User Device Code template: mcp.example.json.

Full call/data map: docs/plugins/MCP_DEDUPE_FLOW.md.