@@ -18,6 +18,9 @@ import { CustomHeaders } from "../../types/customHeaders";
18
18
// Mock fetch
19
19
global . fetch = jest . fn ( ) . mockResolvedValue ( {
20
20
json : ( ) => Promise . resolve ( { status : "ok" } ) ,
21
+ headers : {
22
+ get : jest . fn ( ) . mockReturnValue ( null ) ,
23
+ } ,
21
24
} ) ;
22
25
23
26
// Mock the SDK dependencies
@@ -574,9 +577,10 @@ describe("useConnection", () => {
574
577
mockStreamableHTTPTransport . options = undefined ;
575
578
} ) ;
576
579
577
- test ( "sends X-MCP-Proxy-Auth header when proxy auth token is configured" , async ( ) => {
580
+ test ( "sends X-MCP-Proxy-Auth header when proxy auth token is configured for proxy connectionType " , async ( ) => {
578
581
const propsWithProxyAuth = {
579
582
...defaultProps ,
583
+ connectionType : "proxy" as const ,
580
584
config : {
581
585
...DEFAULT_INSPECTOR_CONFIG ,
582
586
MCP_PROXY_AUTH_TOKEN : {
@@ -626,6 +630,56 @@ describe("useConnection", () => {
626
630
) . toHaveProperty ( "X-MCP-Proxy-Auth" , "Bearer test-proxy-token" ) ;
627
631
} ) ;
628
632
633
+ test ( "does NOT send X-MCP-Proxy-Auth header when proxy auth token is configured for direct connectionType" , async ( ) => {
634
+ const propsWithProxyAuth = {
635
+ ...defaultProps ,
636
+ connectionType : "direct" as const ,
637
+ config : {
638
+ ...DEFAULT_INSPECTOR_CONFIG ,
639
+ MCP_PROXY_AUTH_TOKEN : {
640
+ ...DEFAULT_INSPECTOR_CONFIG . MCP_PROXY_AUTH_TOKEN ,
641
+ value : "test-proxy-token" ,
642
+ } ,
643
+ } ,
644
+ } ;
645
+
646
+ const { result } = renderHook ( ( ) => useConnection ( propsWithProxyAuth ) ) ;
647
+
648
+ await act ( async ( ) => {
649
+ await result . current . connect ( ) ;
650
+ } ) ;
651
+
652
+ // Check that the transport was created with the correct headers
653
+ expect ( mockSSETransport . options ) . toBeDefined ( ) ;
654
+ expect ( mockSSETransport . options ?. requestInit ) . toBeDefined ( ) ;
655
+
656
+ // Verify that X-MCP-Proxy-Auth header is NOT present for direct connections
657
+ expect ( mockSSETransport . options ?. requestInit ?. headers ) . not . toHaveProperty (
658
+ "X-MCP-Proxy-Auth" ,
659
+ ) ;
660
+ expect ( mockSSETransport ?. options ?. fetch ) . toBeDefined ( ) ;
661
+
662
+ // Verify the fetch function does NOT include the proxy auth header
663
+ const mockFetch = mockSSETransport . options ?. fetch ;
664
+ const testUrl = "http://test.com" ;
665
+ await mockFetch ?.( testUrl , {
666
+ headers : {
667
+ Accept : "text/event-stream" ,
668
+ } ,
669
+ cache : "no-store" ,
670
+ mode : "cors" ,
671
+ signal : new AbortController ( ) . signal ,
672
+ redirect : "follow" ,
673
+ credentials : "include" ,
674
+ } ) ;
675
+
676
+ expect ( global . fetch ) . toHaveBeenCalledTimes ( 1 ) ;
677
+ expect ( ( global . fetch as jest . Mock ) . mock . calls [ 0 ] [ 0 ] ) . toBe ( testUrl ) ;
678
+ expect (
679
+ ( global . fetch as jest . Mock ) . mock . calls [ 0 ] [ 1 ] . headers ,
680
+ ) . not . toHaveProperty ( "X-MCP-Proxy-Auth" ) ;
681
+ } ) ;
682
+
629
683
test ( "does NOT send Authorization header for proxy auth" , async ( ) => {
630
684
const propsWithProxyAuth = {
631
685
...defaultProps ,
@@ -882,6 +936,57 @@ describe("useConnection", () => {
882
936
} ) ;
883
937
} ) ;
884
938
939
+ describe ( "Connection URL Verification" , ( ) => {
940
+ beforeEach ( ( ) => {
941
+ jest . clearAllMocks ( ) ;
942
+ // Reset the mock transport objects
943
+ mockSSETransport . url = undefined ;
944
+ mockSSETransport . options = undefined ;
945
+ mockStreamableHTTPTransport . url = undefined ;
946
+ mockStreamableHTTPTransport . options = undefined ;
947
+ } ) ;
948
+
949
+ test ( "uses server URL directly when connectionType is 'direct'" , async ( ) => {
950
+ const directProps = {
951
+ ...defaultProps ,
952
+ connectionType : "direct" as const ,
953
+ } ;
954
+
955
+ const { result } = renderHook ( ( ) => useConnection ( directProps ) ) ;
956
+
957
+ await act ( async ( ) => {
958
+ await result . current . connect ( ) ;
959
+ } ) ;
960
+
961
+ // Verify the transport was created with the direct server URL
962
+ expect ( mockSSETransport . url ) . toBeDefined ( ) ;
963
+ expect ( mockSSETransport . url ?. toString ( ) ) . toBe ( "http://localhost:8080/" ) ;
964
+ } ) ;
965
+
966
+ test ( "uses proxy server URL when connectionType is 'proxy'" , async ( ) => {
967
+ const proxyProps = {
968
+ ...defaultProps ,
969
+ connectionType : "proxy" as const ,
970
+ } ;
971
+
972
+ const { result } = renderHook ( ( ) => useConnection ( proxyProps ) ) ;
973
+
974
+ await act ( async ( ) => {
975
+ await result . current . connect ( ) ;
976
+ } ) ;
977
+
978
+ // Verify the transport was created with a proxy server URL
979
+ expect ( mockSSETransport . url ) . toBeDefined ( ) ;
980
+ expect ( mockSSETransport . url ?. pathname ) . toBe ( "/sse" ) ;
981
+ expect ( mockSSETransport . url ?. searchParams . get ( "url" ) ) . toBe (
982
+ "http://localhost:8080" ,
983
+ ) ;
984
+ expect ( mockSSETransport . url ?. searchParams . get ( "transportType" ) ) . toBe (
985
+ "sse" ,
986
+ ) ;
987
+ } ) ;
988
+ } ) ;
989
+
885
990
describe ( "OAuth Error Handling with Scope Discovery" , ( ) => {
886
991
beforeEach ( ( ) => {
887
992
jest . clearAllMocks ( ) ;
0 commit comments