Skip to content

[Epic] Unified Connector + Tool framework — any system, any agent (runtime · MCP · API) #84

Description

@serge-ivo

Epic: Unified Connector + Tool framework — connect any system, use it from any agent (runtime · MCP · API)

Decision: connectors and tools are two layers, not one. A connector = authenticated access to an external system (auth + scopes + grant to specific resources). A tool = an LLM-callable action (name + schema + handler). A connector provides tools. One tool definition surfaces in the agent runtime, MCP, and the HTTP API.

Why (evidence, 2026-08-01 investigation)

  • Connectors today are ingest-only (Drive/WorkDrive import to KB); the only live connector tool is Gmail find_confirmation_link. No connector→tool bridge (lib/connector-*.ts, routes/drive.ts).
  • Tools are a fixed, triple-defined catalog: runtime AGENT_TOOLS/STORAGE_TOOLS + switch/case executors, and ~97 hand-written MCP tools — names even drift (search_knowledge vs search_agent_knowledge). Adding one capability = edit 3 places.
  • GitHub is 100% hardwired into Coder (routes/coding.ts, lib/github-issues.ts): actions status, issues, next-issue, private clone. No other agent can use GitHub. installationTokenForOwner is reusable in code but exposed nowhere.

What exists to build on

lib/connector-oauth.ts (HMAC state + refresh-token store), instance_connector_grants (0044), envelope crypto (user_api_keys), fetch_url + key-proxy, GitHub-App tokens.

Target

  • One ToolDef (name, description, JSON schema, handler, tier, connector?) → runtime + MCP + API auto-derive.
  • Connector registry: {id, auth(oauth|token|app), scopes(read/write), grantModel(user | instance-resource), tools[]}, reusing OAuth + grants + crypto. Handlers get a connectorClient(provider) that mints the token + enforces grant/scope.
  • New connector = declare in one place → appears everywhere.

Children (sequence)

  • Single tool registry (one def → runtime + MCP + API)
  • Connector framework (registry, auth, grants, scopes, connector→tool bridge, per-instance enable/consent)
  • Generic tool-call API + MCP auto-generation from the registry
  • GitHub connector — de-hardwire Coder (actions/issues/PRs/files/deploy → github_* tools)
  • Google Sheets connector (read + WRITE) — the "populate my hotels list" example
  • Connector consent + write-scope safety + admin visibility

Non-goals

Per-connector bespoke routes (the current pattern). The point is: add a connector once, get tools everywhere, with no route/MCP/runtime duplication.

Issues (sequence)

  1. [connectors] Single tool registry — one definition → runtime + MCP + API #85 Single tool registry (enabling refactor)
  2. [connectors] Connector framework — registry, auth, grants, scopes, tool bridge #86 Connector framework
  3. [connectors] Generic tool-call API + MCP auto-generation #87 Generic tool-call API + MCP auto-gen
  4. [connectors] GitHub connector — de-hardwire Coder #88 GitHub connector (de-hardwire Coder)
  5. [connectors] Google Sheets connector (read + write) — the hotels-list case #89 Google Sheets connector (read+write)
  6. [connectors] Connector consent + write-scope safety + admin visibility #90 Consent + write-safety + admin visibility (gates writes)

Gated by #68 (focus bet). Write-safety shares the trust model with #75.


Status update 2026-08-04

All six children (#85#90) are closed, implemented and tested — the boxes above were never
ticked, so this epic read as not-started. Live today: lib/connectors/registry.ts with 7
connectors (github, meta, tmux, browser, http, web-search, mcp), connectorClient auth dispatch,
capabilities.tools gating, the write-consent gate (migration 0051), and all three surfaces
deriving from one ToolDef.

One gap the epic did not anticipate, found while building the first connector whose endpoint
is named by the subscriber at runtime (outbound MCP): the auth model assumes the operator knows
the remote system at build time (pre-registered client, secretRef in operator env, confidential
client). That is unfillable for a user-named endpoint. Tracked in #180 (dcr-oauth2) and #181
(unattended credential survivability); design in docs/connector-auth.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    connectorsConnector + tool frameworkenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions