11import config from "../../config.js" ;
2- import createClient , { FetchOptions , Middleware } from "openapi-fetch" ;
2+ import createClient , { Client , FetchOptions , Middleware } from "openapi-fetch" ;
33import { AccessToken , ClientCredentials } from "simple-oauth2" ;
44
55import { paths , operations } from "./openapi.js" ;
66
7+ const ATLAS_API_VERSION = "2025-03-12" ;
8+
79export class ApiClientError extends Error {
810 response ?: Response ;
911
@@ -25,38 +27,32 @@ export class ApiClientError extends Error {
2527}
2628
2729export interface ApiClientOptions {
28- credentials : {
30+ credentials ? : {
2931 clientId : string ;
3032 clientSecret : string ;
3133 } ;
3234 baseUrl ?: string ;
35+ userAgent ?: string ;
3336}
3437
3538export class ApiClient {
36- private client = createClient < paths > ( {
37- baseUrl : config . apiBaseUrl ,
38- headers : {
39- "User-Agent" : config . userAgent ,
40- Accept : `application/vnd.atlas.${ config . atlasApiVersion } +json` ,
41- } ,
42- } ) ;
43- private oauth2Client = new ClientCredentials ( {
44- client : {
45- id : this . options . credentials . clientId ,
46- secret : this . options . credentials . clientSecret ,
47- } ,
48- auth : {
49- tokenHost : this . options . baseUrl || config . apiBaseUrl ,
50- tokenPath : "/api/oauth/token" ,
51- } ,
52- } ) ;
39+ private options : {
40+ baseUrl : string ;
41+ userAgent : string ;
42+ credentials ?: {
43+ clientId : string ;
44+ clientSecret : string ;
45+ } ;
46+ } ;
47+ private client : Client < paths > ;
48+ private oauth2Client ?: ClientCredentials ;
5349 private accessToken ?: AccessToken ;
5450
5551 private getAccessToken = async ( ) => {
56- if ( ! this . accessToken || this . accessToken . expired ( ) ) {
52+ if ( this . oauth2Client && ( ! this . accessToken || this . accessToken . expired ( ) ) ) {
5753 this . accessToken = await this . oauth2Client . getToken ( { } ) ;
5854 }
59- return this . accessToken . token . access_token ;
55+ return this . accessToken ? .token . access_token as string | undefined ;
6056 } ;
6157
6258 private authMiddleware = ( apiClient : ApiClient ) : Middleware => ( {
@@ -82,22 +78,51 @@ export class ApiClient {
8278 } ,
8379 } ) ;
8480
85- constructor ( private options : ApiClientOptions ) {
86- this . client . use ( this . authMiddleware ( this ) ) ;
81+ constructor ( options ?: ApiClientOptions ) {
82+ const defaultOptions = {
83+ baseUrl : "https://cloud.mongodb.com/" ,
84+ userAgent : `AtlasMCP/${ config . version } (${ process . platform } ; ${ process . arch } ; ${ process . env . HOSTNAME || "unknown" } )` ,
85+ } ;
86+
87+ this . options = {
88+ ...defaultOptions ,
89+ ...options ,
90+ } ;
91+
92+ this . client = createClient < paths > ( {
93+ baseUrl : this . options . baseUrl ,
94+ headers : {
95+ "User-Agent" : this . options . userAgent ,
96+ Accept : `application/vnd.atlas.${ ATLAS_API_VERSION } +json` ,
97+ } ,
98+ } ) ;
99+ if ( this . options . credentials ?. clientId && this . options . credentials ?. clientSecret ) {
100+ this . oauth2Client = new ClientCredentials ( {
101+ client : {
102+ id : this . options . credentials . clientId ,
103+ secret : this . options . credentials . clientSecret ,
104+ } ,
105+ auth : {
106+ tokenHost : this . options . baseUrl ,
107+ tokenPath : "/api/oauth/token" ,
108+ } ,
109+ } ) ;
110+ this . client . use ( this . authMiddleware ( this ) ) ;
111+ }
87112 this . client . use ( this . errorMiddleware ( ) ) ;
88113 }
89114
90115 async getIpInfo ( ) {
91116 const accessToken = await this . getAccessToken ( ) ;
92117
93118 const endpoint = "api/private/ipinfo" ;
94- const url = new URL ( endpoint , config . apiBaseUrl ) ;
119+ const url = new URL ( endpoint , this . options . baseUrl || config . apiBaseUrl ) ;
95120 const response = await fetch ( url , {
96121 method : "GET" ,
97122 headers : {
98123 Accept : "application/json" ,
99124 Authorization : `Bearer ${ accessToken } ` ,
100- "User-Agent" : config . userAgent ,
125+ "User-Agent" : this . options . userAgent ,
101126 } ,
102127 } ) ;
103128
0 commit comments