The connector framework lands in Phase 4 (LEGATE_AGENT_BUILD_PLAN.md Section 9).
A connector is a Python class conforming to a common Connector protocol:
validate_config, test_connection, list_tools, and async execute.
Connectors register their tools at startup; adding one requires only dropping in
a conforming module — no core changes.
Planned v1 connectors: HTTP/REST, outbound Webhook, Email (IMAP/SMTP), Slack, Stripe, Database (Postgres/MySQL), and the internal RAG knowledge base.
Implemented:
| Type | Tools | Notes |
|---|---|---|
http |
http.call |
Authenticated, any method. Sensitive (write-capable). |
slack |
slack.post_message, slack.list_channels, slack.reply_thread |
Slack Web API. |
email |
email.send, email.draft, email.search |
SMTP/IMAP; email.send is sensitive. |
github |
github.get_issue, github.list_issues, github.create_issue, github.comment_issue |
GitHub REST API; base_url supports Enterprise. Writes are sensitive. |
notion |
notion.search, notion.query_database, notion.create_page, notion.append_block |
Notion API; writes are sensitive. |
webhook |
webhook.send |
POST JSON to a fixed URL with optional HMAC-SHA256 signing. Sensitive. |
postgres |
postgres.query, postgres.execute |
External PostgreSQL. query is read-only (SELECT/CTE only, run in a READ ONLY transaction, row-capped); execute is sensitive and refuses statement chaining. |
mysql |
mysql.query, mysql.execute |
MySQL/MariaDB sibling of postgres (shared guard + row caps); reads run in a session READ ONLY transaction. |
stripe |
stripe.get_customer, stripe.list_charges, stripe.create_refund |
Acts on a workspace's own Stripe account; create_refund is sensitive. Separate from the platform's internal billing. |
google |
gsheets.read_range, gsheets.append_row, gdrive.list_files, gdrive.get_file |
Google Sheets + Drive under one OAuth2 credential (refresh-token flow). gsheets.append_row is sensitive. |
mcp |
dynamic | A remote MCP server (Streamable HTTP). Tools are discovered from the server and namespaced mcp.<id>.<tool>; see below. |
Each connector's write tools are marked is_sensitive, so they route through the
policy engine and (when configured) the human-approval inbox; reads run without
approval. New connector types register in legate/connectors/registry.py and are
exposed automatically through GET /connector-types, the schema-driven install
wizard, and agent tool allow-lists — no core changes required.
Credentials are stored with envelope encryption (legate/vault) and never
returned by the API. The built-in read-only http.request tool (no credentials)
remains available separately from the http connector.
Legate is an MCP client: register a remote MCP server by URL (config url,
optional secret token) and its tools become available to agents and workflows.
- Transport: Streamable HTTP (JSON or SSE responses). Handshake is
initialize->notifications/initialized->tools/list/tools/call(legate/mcp/client.py). - Discovery + caching: on install and on "test connection" the server's tools
are fetched and cached on the connector row (
config_json.mcp_tools), so tool resolution needs no network call per run. Re-test to refresh after the server's tools change. - Naming: each tool is registered as
mcp.<connector-id8>.<tool>(unique across servers, grouped under one "MCP" section in the UI); the server is still called with its original tool name. - Safety: a tool is treated as sensitive (routed through approval) unless the
server marks it
annotations.readOnlyHint = true.
Both SQL connectors share BaseSqlConnector, so the guard is identical.
*.query is defended in depth: the statement is checked (single statement,
must start with SELECT/WITH, no data-modifying keywords, comments stripped
first) and executed inside a READ ONLY transaction, so a write cannot slip
through even if the text check is fooled. Results are capped (default 100 rows,
hard max 1000). postgres.execute permits a single data-modifying statement and,
being sensitive, is policy/approval gated.