[connectors] Support connectors part 1 - App server & MCP#9667
[connectors] Support connectors part 1 - App server & MCP#9667mzeng-openai merged 12 commits intomainfrom
Conversation
…/connectors_codex_cli_1
…/connectors_codex_cli_1
| connectors: Vec<ConnectorInfo>, | ||
| } | ||
|
|
||
| pub async fn list_connectors(config: &Config) -> anyhow::Result<Vec<ConnectorInfo>> { |
There was a problem hiding this comment.
There are two types of connectors:
- Connectors that are already connected by the user, and we have a link that we can use to authenticate it
- Connectors that have not been installed by the user. We need the user to install it on ChatGPT UI.
In the UI we mix them together and use is_accessible to distinguish them. This methods does the merge.
| Ok(merge_connectors(connectors, accessible)) | ||
| } | ||
|
|
||
| pub async fn list_all_connectors(config: &Config) -> anyhow::Result<Vec<ConnectorInfo>> { |
There was a problem hiding this comment.
List all available connectors regardless of whether they are installed or not.
| servers | ||
| } | ||
|
|
||
| pub(crate) fn effective_mcp_servers( |
There was a problem hiding this comment.
Add codex apps MCP as an always on built-in MCP.
|
|
||
| connectors | ||
| .into_iter() | ||
| .filter(|connector| connector_inserted_in_messages(connector, &user_messages)) |
There was a problem hiding this comment.
Include connectors mentioned in the user messages as tools.
| }) | ||
| } | ||
|
|
||
| fn filter_codex_apps_mcp_tools( |
There was a problem hiding this comment.
Find the mcp tools that are associated with connectors.
| pub is_accessible: bool, | ||
| } | ||
|
|
||
| pub async fn list_accessible_connectors_from_mcp_tools( |
There was a problem hiding this comment.
We collect the actually accessible mcp tools from the gateway MCP tool list.
| params: v2::SkillsListParams, | ||
| response: v2::SkillsListResponse, | ||
| }, | ||
| AppsList => "app/list" { |
There was a problem hiding this comment.
nit: apps/list similar to skills/list
There was a problem hiding this comment.
ironically @owenlin0 just said the other way, because all the other protocols are singular.
There was a problem hiding this comment.
it reads very strangely: App*s*List => "app/list"
There was a problem hiding this comment.
it does read strangely, but only for /list methods
thread/list
thread/start
thread/archive
... etc.
owenlin0
left a comment
There was a problem hiding this comment.
should we also add some integration tests at codex-rs/app-server/tests/suite/v2/app_list.rs? can probably ask codex to generate some
| params: v2::SkillsListParams, | ||
| response: v2::SkillsListResponse, | ||
| }, | ||
| AppsList => "app/list" { |
There was a problem hiding this comment.
nit: AppsList -> AppList
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] | ||
| #[serde(rename_all = "camelCase")] | ||
| #[ts(export_to = "v2/")] | ||
| pub struct AppInfo { |
There was a problem hiding this comment.
nit: should we just call this App? AppInfo sounds redundant (like ThreadInfo for a thread/list API)
There was a problem hiding this comment.
I'm mostly trying to avoid confusing this with the actual codex app itself.
There was a problem hiding this comment.
it's ok, you get to own the word "app" in the app-server API
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] | ||
| #[serde(rename_all = "camelCase")] | ||
| #[ts(export_to = "v2/")] | ||
| pub struct AppsListResponse { |
In order to make Codex work with connectors, we add a built-in gateway MCP that acts as a transparent proxy between the client and the connectors. The gateway MCP collects actions that are accessible to the user and sends them down to the user, when a connector action is chosen to be called, the client invokes the action through the gateway MCP as well.