MCPcopy Create free account
hub / github.com/MatterAIOrg/OrbCode / connectOne

Method connectOne

src/mcp/manager.ts:82–127  ·  view source on GitHub ↗

Connect (or reconnect) a single server by name. * When `skipUnauthOAuth` is set, OAuth servers with no stored tokens are * marked needs-auth instead of opening a browser (used at startup). * When `authIntercept` is provided, the caller controls the OAuth UI * (surfacing the auth URL, pro

(name: string, options?: { skipUnauthOAuth?: boolean; authIntercept?: AuthIntercept; forceOAuth?: boolean })

Source from the content-addressed store, hash-verified

80 * config is treated as `oauth: true` (auto-detected OAuth — used when the
81 * user triggers auth after a 401). */
82 async connectOne(name: string, options?: { skipUnauthOAuth?: boolean; authIntercept?: AuthIntercept; forceOAuth?: boolean }): Promise<void> {
83 const cfg = this.configs.get(name)
84 if (!cfg) return
85 const state = this.states.get(name)!
86 const isRemote = cfg.type === "http" || cfg.type === "sse"
87
88 // At startup, don't open a browser for OAuth servers that haven't been
89 // authenticated yet — surface them as needs-auth so the user can trigger
90 // auth explicitly from the /mcp picker. This applies to both explicitly
91 // configured OAuth servers and any remote server (which may require OAuth
92 // we don't know about yet — we'll find out on the first connect attempt).
93 if (options?.skipUnauthOAuth && isOAuthConfig(cfg) && !hasStoredAuth(name)) {
94 state.status = "needs-auth"
95 state.detail = "not authenticated — press a to authenticate"
96 return
97 }
98
99 state.status = "connecting"
100 state.detail = undefined
101 try {
102 const { scope: _scope, ...serverConfig } = cfg
103 // Auto-detect: if forceOAuth is set and this is a remote server without
104 // explicit oauth config, inject oauth: true so the auth transport is used.
105 if (options?.forceOAuth && isRemote && !isOAuthConfig(cfg)) {
106 ;(serverConfig as McpHttpServerConfig).oauth = true
107 }
108 const connection = await connectMcpServer(name, serverConfig, options?.authIntercept)
109 this.connections.set(name, connection)
110 state.status = "connected"
111 state.toolCount = connection.tools.length
112 state.detail = `${connection.tools.length} tool${connection.tools.length === 1 ? "" : "s"}`
113 this.pendingApproval.delete(name)
114 } catch (error) {
115 const msg = (error as Error).message
116 // Any remote server that returns 401/unauthorized/invalid_token needs
117 // auth — surface as needs-auth regardless of whether `oauth` was
118 // explicitly configured (auto-detection, like Claude Code).
119 if (isRemote && /unauthorized|auth|401|oauth|invalid_token/i.test(msg)) {
120 state.status = "needs-auth"
121 state.detail = "authentication required — press a to authenticate"
122 } else {
123 state.status = "failed"
124 state.detail = msg
125 }
126 }
127 }
128
129 /** Disconnect a single server (keeps config; marks it disabled). */
130 async disconnectOne(name: string): Promise<void> {

Callers 4

startMethod · 0.95
enableServerMethod · 0.95
reauthServerMethod · 0.95
reconnectSelectedFunction · 0.80

Calls 3

isOAuthConfigFunction · 0.85
hasStoredAuthFunction · 0.85
connectMcpServerFunction · 0.85

Tested by

no test coverage detected