MCP integration strategy

July 6, 2026 · View on GitHub

Product notes on MCP OAuth and connection tiers. Requirements overview: OAUTH_REQUIREMENTS.md. Operational setup: OAUTH_AND_HOSTING.md. Node / install: SETUP.md.

OAuth and status (shipped vs deferred)

Shipped

AreaBehavior
Token without expiryAccess tokens with no expires_at are treated as valid (isOAuthAccessTokenExpired returns false when expiry is missing).
Status endpointGET /api/oauth/:serviceId/status returns authenticated: hasToken && !isExpired plus hasToken, isExpired, hasRefreshToken, expiresAt.
Collection warningsMCP OAuth warnings use stored token + discovery context; dashboard calls use x-agent-deck-client: dashboard so warnings do not require an Authorization header on the API.
Frontend status queryService details modal polls /api/oauth/:id/status when MCP discovery reports OAuth required; stops polling once authenticated is true.
Token storageClient secrets + access/refresh tokens in macOS Keychain (OAuthClientSecretVault, OAuthTokenVault); see SETUP.md.

Deferred

  • Auth profiles on presets — seeded cards do not carry per-vendor OAuth app presets or connection tiers.
  • RFC 8707 resource parameter — not sent on authorize/token requests yet.
  • CIMD (Client ID Metadata Documents) — dynamic registration without stored client secret not implemented.
  • Post-callback polish — deep-link back to dashboard, clearer error surfaces, and idempotent callback handling if gaps appear in the field.

Architecture direction (not implemented)

MCP hub is the right shape

Agent Deck should remain an MCP hub: one agent-facing endpoint, deck-scoped tool surface. The hard part is OAuth policy per vendor, not the MCP protocol itself.

Tiered connection catalog

TierUser actionExamples
AutoDCR + PKCE, minimal setupLinear, Notion (when vendor allows)
BYO OAuth appUser creates OAuth app, pastes client id/secretGoogle, Slack
BYO credential / PATAPI key or personal token in vaultGitHub PAT, custom MCP
Host-onlyAuth delegated to Cursor / ClaudeNative connectors in IDE
Local stdioUser runs process locallyObsidian, custom scripts

Provider reality (default seeded cards)

CardTypical auth pathNotes
LinearAuto (DCR/PKCE)Works with current auto-setup flow
NotionAutoSimilar to Linear
GitHubBYO OAuth or PATHosted at api.githubcopilot.com; all GitHub users; Copilot only for specific tools
Google (Gmail / Calendar / Drive)Local stdio or BYO remoteNot seeded — remote MCP needs GCP + preview APIs; see GOOGLE_DRIVE_WORKAROUND.md
SlackBYO OAuth appSlack requires a registered app for non-partner MCP clients; see below
Draw.ioVariableRemote MCP may have no OAuth; may need alternate auth
FigmaBYO OAuth appNot seeded — vendor allowlist blocks third-party OAuth today
DocmostBYO instance URLNot seeded (self-hosted)
ObsidianLocal stdioNot seeded as remote preset

Alternatives considered

ApproachProsCons
Native plugins / connectorsBest UX per host; uses host OAuthFragmented; not deck-portable
OAuth broker (Nango, etc.)Faster vendor coverageExtra dependency, cost, trust boundary
Delegate auth to host appZero secret handling in Agent DeckDeck tools not portable across clients
Single SaaS OAuth app (Agent Deck-owned)One-click for usersVendor approval, compliance, rate limits
  • MCP = stable agent-facing interface (tools, resources, deck binding).
  • Connectors = per-app modules that own auth tier, discovery, and token refresh.
  • Preset cards advertise connection tier + setup steps, not only a URL.

Connection capability matrix (default presets)

PresetMCP remoteOAuth autoBYO appPAT / headerLocal stdio
Linear
Notion
GitHub
Google Drive (manual local)
Google remote MCP (manual)
Slack— / managed
Figma✓ (allowlist)
Draw.io?
Obsidian (manual)

Legend: = supported path today or planned first-class; ? = vendor-dependent; = not applicable.

Slack MCP — why a “Slack app” is required

Slack’s hosted MCP (https://mcp.slack.com/mcp) does not support Dynamic Client Registration. Official docs state that MCP clients must be backed by a registered Slack app with a fixed client ID (Slack MCP server).

ClientWhat the user sees
Cursor, Claude Code, Claude.ai, PerplexityOne-click — Slack pre-registered OAuth apps for these partners
Agent Deck (and other third-party hubs)Must supply your app’s Client ID + Secret, then complete user OAuth

This is OAuth client identity, not “building a Slack product.” You are registering who is allowed to run the MCP OAuth flow on your behalf. Workspace admins can approve that app like any other internal Slack app.

On api.slack.com/apps: choose Create New App → From scratch (one-time). Name it, pick workspace, then enable MCP under Agents & AI Apps, set redirect URL and scopes, copy Client ID/Secret into Agent Deck.

Required beyond redirect URL + scopes (easy to miss):

  • Agents & AI Apps → enable MCP on the Slack app
  • PKCE opt-in under OAuth & Permissions (recommended)
  • App must be internal or marketplace-published (unlisted apps cannot use MCP)
  • Some authorize flows need a minimal bot user even though MCP uses user tokens at runtime

| Managed (Agent Deck–owned app) | One-click when env/host holds secret | Slack (when AGENT_DECK_SLACK_* set) |

Slack: path to non-technical users

  1. Now (maintainers): Register one Slack app — see SLACK_OAUTH_APP.md. Set AGENT_DECK_SLACK_CLIENT_ID + AGENT_DECK_SLACK_CLIENT_SECRETsetupMode: managed.
  2. Next (hosted): OAuth callback on agent-deck.dev so end users never touch env vars or manifests.
  3. Long-term: Slack Marketplace / partner listing (Cursor-style).
  4. Alternatives if hosted is not ready: OAuth broker; host-only Slack in Cursor/Claude; do not promise one-click Slack on pure local OSS without secrets.

Helping users with hard setups (shipped vs planned)

HelpStatusNotes
Pre-filled Slack app manifest + Copy manifest / Open creatorShippeddocs/examples/slack-mcp.manifest.json; UI buttons in OAuth panel
Connection tier badge on cards (“~10 min manual”)PlannedSurface setupMode on preset cards
Agent Deck–owned OAuth appsShipped (Slack env)Hosted HTTPS + secrets; see SLACK_OAUTH_APP
OAuth broker integrationPlannedNango-style; tradeoffs in alternatives table
Bearer token / vault credential pathPlannedSkip OAuth UI for power users
Interactive agent-deck setup slack CLI wizardPlannedSame steps, terminal checklist

Next implementation steps (suggested)

  1. Tag each preset with connectionTier in seed data and surface it in the service details UI.
  2. Split OAuth flows: auto-setup vs manual-credentials vs vault-token.
  3. Add RFC 8707 resource when discovery provides resource metadata.