@@ -348,7 +348,9 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
348348 return this . currentToken || fallback ;
349349 }
350350
351- private buildMcpServers ( credentials : Credentials ) : AcpMcpServer [ ] {
351+ private async buildMcpServers (
352+ credentials : Credentials ,
353+ ) : Promise < AcpMcpServer [ ] > {
352354 const servers : AcpMcpServer [ ] = [ ] ;
353355
354356 const mcpUrl = this . getPostHogMcpUrl ( credentials . apiHost ) ;
@@ -367,9 +369,94 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
367369 ] ,
368370 } ) ;
369371
372+ // Fetch user-installed MCP servers from the PostHog backend
373+ const installations = await this . fetchMcpInstallations ( credentials ) ;
374+
375+ for ( const installation of installations ) {
376+ // Skip the PostHog MCP server since it's already included above
377+ if ( installation . url === mcpUrl ) continue ;
378+
379+ if ( installation . auth_type === "none" ) {
380+ servers . push ( {
381+ name :
382+ installation . name || installation . display_name || installation . url ,
383+ type : "http" ,
384+ url : installation . url ,
385+ headers : [ ] ,
386+ } ) ;
387+ } else {
388+ // Authenticated servers go through the PostHog proxy so credentials
389+ // never leave the backend
390+ servers . push ( {
391+ name :
392+ installation . name || installation . display_name || installation . url ,
393+ type : "http" ,
394+ url : installation . proxy_url ,
395+ headers : [ { name : "Authorization" , value : `Bearer ${ token } ` } ] ,
396+ } ) ;
397+ }
398+ }
399+
370400 return servers ;
371401 }
372402
403+ private async fetchMcpInstallations ( credentials : Credentials ) : Promise <
404+ Array < {
405+ id : string ;
406+ url : string ;
407+ proxy_url : string ;
408+ name : string ;
409+ display_name : string ;
410+ auth_type : string ;
411+ } >
412+ > {
413+ const token = this . getToken ( credentials . apiKey ) ;
414+ const baseUrl = this . getPostHogApiBaseUrl ( credentials . apiHost ) ;
415+ const url = `${ baseUrl } /api/environments/${ credentials . projectId } /mcp_server_installations/` ;
416+
417+ try {
418+ const response = await fetch ( url , {
419+ headers : {
420+ Authorization : `Bearer ${ token } ` ,
421+ "Content-Type" : "application/json" ,
422+ } ,
423+ } ) ;
424+
425+ if ( ! response . ok ) {
426+ log . warn ( "Failed to fetch MCP installations" , {
427+ status : response . status ,
428+ } ) ;
429+ return [ ] ;
430+ }
431+
432+ const data = ( await response . json ( ) ) as {
433+ results ?: Array < {
434+ id : string ;
435+ url : string ;
436+ proxy_url ?: string ;
437+ name : string ;
438+ display_name : string ;
439+ auth_type : string ;
440+ pending_oauth : boolean ;
441+ needs_reauth : boolean ;
442+ } > ;
443+ } ;
444+ const installations = data . results ?? [ ] ;
445+
446+ return installations
447+ . filter ( ( i ) => ! i . pending_oauth && ! i . needs_reauth )
448+ . map ( ( i ) => ( {
449+ ...i ,
450+ proxy_url :
451+ i . proxy_url ??
452+ `${ baseUrl } /api/environments/${ credentials . projectId } /mcp_server_installations/${ i . id } /proxy/` ,
453+ } ) ) ;
454+ } catch ( err ) {
455+ log . warn ( "Error fetching MCP installations" , { error : err } ) ;
456+ return [ ] ;
457+ }
458+ }
459+
373460 private buildSystemPrompt (
374461 credentials : Credentials ,
375462 customInstructions ?: string ,
@@ -396,6 +483,11 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
396483 return "https://mcp.posthog.com/mcp" ;
397484 }
398485
486+ private getPostHogApiBaseUrl ( apiHost : string ) : string {
487+ const host = process . env . POSTHOG_PROXY_BASE_URL || apiHost ;
488+ return host . endsWith ( "/" ) ? host . slice ( 0 , - 1 ) : host ;
489+ }
490+
399491 async startSession ( params : StartSessionInput ) : Promise < SessionResponse > {
400492 this . validateSessionParams ( params ) ;
401493 const config = this . toSessionConfig ( params ) ;
@@ -516,7 +608,7 @@ export class AgentService extends TypedEventEmitter<AgentServiceEvents> {
516608 } ) ;
517609
518610 const mcpServers =
519- adapter === "codex" ? [ ] : this . buildMcpServers ( credentials ) ;
611+ adapter === "codex" ? [ ] : await this . buildMcpServers ( credentials ) ;
520612
521613 let configOptions : SessionConfigOption [ ] | undefined ;
522614 let agentSessionId : string ;
0 commit comments