|
176 | 176 | [])) |
177 | 177 |
|
178 | 178 | (defn ^:private initialize-mcp-oauth |
179 | | - [{:keys [authorization-endpoint callback-port] :as oauth-info} |
| 179 | + [oauth-info |
180 | 180 | server-name |
181 | 181 | db* |
182 | 182 | server-config |
183 | | - {:keys [on-success on-error on-server-updated]}] |
184 | | - (oauth/start-oauth-server! |
185 | | - {:port callback-port |
186 | | - :on-success (fn [{:keys [code]}] |
187 | | - (let [{:keys [access-token refresh-token expires-at]} (oauth/authorize-token! oauth-info code)] |
188 | | - (swap! db* assoc-in [:mcp-auth server-name] {:type :auth/oauth |
189 | | - :url (:url server-config) |
190 | | - :refresh-token refresh-token |
191 | | - :access-token access-token |
192 | | - :expires-at expires-at})) |
193 | | - (oauth/stop-oauth-server! callback-port) |
194 | | - (on-success)) |
195 | | - :on-error (fn [error] |
196 | | - (oauth/stop-oauth-server! callback-port) |
197 | | - (on-error error))}) |
198 | | - (logger/info logger-tag (format "Authenticating MCP server '%s' at '%s'" server-name authorization-endpoint)) |
199 | | - (swap! db* assoc-in [:mcp-clients server-name] {:status :requires-auth}) |
200 | | - (browse/browse-url authorization-endpoint) |
| 183 | + {:keys [on-server-updated]}] |
| 184 | + (logger/info logger-tag (format "MCP server '%s' requires authentication" server-name)) |
| 185 | + (swap! db* assoc-in [:mcp-clients server-name] {:status :requires-auth |
| 186 | + :oauth-info oauth-info}) |
201 | 187 | (on-server-updated (->server server-name server-config :requires-auth @db*))) |
202 | 188 |
|
203 | 189 | (defn ^:private token-expired? |
|
266 | 252 | name |
267 | 253 | db* |
268 | 254 | server-config |
269 | | - {:on-server-updated on-server-updated |
270 | | - :on-success (fn [] |
271 | | - ;; :mcp-auth exists now |
272 | | - (db/update-global-cache! @db* metrics) |
273 | | - (initialize-server! name db* config metrics on-server-updated)) |
274 | | - :on-error (fn [error] |
275 | | - (logger/error logger-tag error) |
276 | | - (swap! db* assoc-in [:mcp-clients name :status] :failed) |
277 | | - (on-server-updated (->server name server-config :failed db)))}) |
| 255 | + {:on-server-updated on-server-updated}) |
278 | 256 | (let [init-timeout (:mcpTimeoutSeconds config) |
279 | 257 | on-tools-change (fn [tools] |
280 | 258 | (let [tools (mapv tool->internal tools)] |
|
354 | 332 | (logger/info logger-tag (format "Starting MCP server %s from manual request despite :disabled=true" name))) |
355 | 333 | (initialize-server! name db* config metrics on-server-updated))) |
356 | 334 |
|
| 335 | +(defn connect-server! |
| 336 | + "Initiate OAuth authorization for an MCP server that requires auth. |
| 337 | + Starts the local OAuth callback server and returns the authorization URL." |
| 338 | + [name db* config metrics {:keys [on-server-updated]}] |
| 339 | + (let [server-config (get-in config [:mcpServers name]) |
| 340 | + {:keys [oauth-info]} (get-in @db* [:mcp-clients name])] |
| 341 | + (when (and server-config oauth-info) |
| 342 | + (let [{:keys [authorization-endpoint callback-port]} oauth-info] |
| 343 | + (swap! db* assoc-in [:mcp-clients name :status] :starting) |
| 344 | + (on-server-updated (->server name server-config :starting @db*)) |
| 345 | + (oauth/start-oauth-server! |
| 346 | + {:port callback-port |
| 347 | + :on-success (fn [{:keys [code]}] |
| 348 | + (let [{:keys [access-token refresh-token expires-at]} (oauth/authorize-token! oauth-info code)] |
| 349 | + (swap! db* assoc-in [:mcp-auth name] {:type :auth/oauth |
| 350 | + :url (:url server-config) |
| 351 | + :refresh-token refresh-token |
| 352 | + :access-token access-token |
| 353 | + :expires-at expires-at})) |
| 354 | + (oauth/stop-oauth-server! callback-port) |
| 355 | + (db/update-global-cache! @db* metrics) |
| 356 | + (initialize-server! name db* config metrics on-server-updated)) |
| 357 | + :on-error (fn [error] |
| 358 | + (oauth/stop-oauth-server! callback-port) |
| 359 | + (logger/error logger-tag error) |
| 360 | + (swap! db* assoc-in [:mcp-clients name :status] :failed) |
| 361 | + (on-server-updated (->server name server-config :failed @db*)))}) |
| 362 | + (browse/browse-url authorization-endpoint))))) |
| 363 | + |
| 364 | +(defn logout-server! |
| 365 | + "Logout from an MCP server by clearing stored OAuth credentials and restarting it." |
| 366 | + [name db* config metrics {:keys [on-server-updated]}] |
| 367 | + (when (get-in config [:mcpServers name]) |
| 368 | + (swap! db* update :mcp-auth dissoc name) |
| 369 | + (db/update-global-cache! @db* metrics) |
| 370 | + (when (get-in @db* [:mcp-clients name :client]) |
| 371 | + (stop-server! name db* config {:on-server-updated on-server-updated})) |
| 372 | + (future |
| 373 | + (initialize-server! name db* config metrics on-server-updated)))) |
| 374 | + |
357 | 375 | (defn all-tools [db] |
358 | 376 | (into [] |
359 | 377 | (mapcat (fn [[name {:keys [tools version]}]] |
|
0 commit comments