Skip to content

Bind integration credentials to their endpoints and report real access in the Plugins directory #443

Description

@linear-code

Problem

The new Plugins directory lists every integrations.sh service and lets a bot connect to any of them. The first version had server-side gaps: a saved API key was not tied to the MCP endpoint it was approved for, OAuth services reported connected when access had failed or the key was removed, a catalog refresh that failed while offline left the directory broken until restart, and names, search results, and the featured list were rough.

Goal

  • A saved MCP credential is bound to the approved endpoint. It is never sent to a different endpoint, it is removed with its server, and reuse only happens on the same endpoint.
  • Access state is real: an OAuth failure or a removed key shows as not connected, using access health rather than "a key exists".
  • After an offline or failed refresh, the directory recovers on the next periodic refresh, and concurrent searches during recovery share one refresh.
  • Service names read as product names, search ignores noise, and each card notes the service's capabilities.
  • Six featured services, in order: Gmail, Composio, Context.dev, Google Calendar, Notion, GitHub. Cards show their discovery badges.

Acceptance criteria

  • Endpoint binding, deletion, and reuse covered by regression tests
  • OAuth failure and key removal show the right state
  • Periodic and deduplicated search recovery after an offline refresh
  • Readable names, less search noise, capability notes, six featured services with discovery badges, internal docs updated
  • Merged clients checked on an isolated dev server: Settings → Plugins at desktop and mobile widths, connect and remove a key-based service, and see the state change
  • One real account sign-in through an OAuth service
  • PR opened and merged

How to verify

vp test run apps/server/src/integrations

Then, on an isolated dev server from the branch, open Plugins, connect a featured key-based service, remove its key, and confirm the card returns to not connected. Repeat with the network off during a refresh and confirm the directory recovers.

Out of scope

  • The Plugins page layout and design (owned by the parent integrations.sh work)
  • Choosing between Executor and a generic OpenAPI tool for integration calls

Context

  • Work lives on the local branch cos/integrations-sh on Leo's machine (17 commits ahead of main, not pushed, no PR). The server fixes are commit 36ea9e212 fix(server): bind integration keys and report real access. Later commits on the same branch tidy the web directory, strip markup from integrations.sh descriptions, label Composio's card as an API key, and say plainly when sign-in services don't reach OpenCode bots.
  • Verification on 2026-10-05: 84 focused tests in nine suites passed; targeted lint and server and web tsgo passed. Before the fix, the same run reproduced 13 regression failures. Not checked: merged live clients and real account sign-in, which belong to the parent task because the worker was told not to start dev servers.
  • Code: apps/server/src/integrations/ (IntegrationsCatalog.ts, model.ts with the featured list). User docs: docs/user/plugins.md on the branch.

Created with Claude Opus 5.5 in Claude Code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions