post_profile_custom
Create and customize browser profiles with specific parameters such as OS, language, bookmarks, and proxy settings using GoLogin MCP for efficient profile management.
Instructions
Create profile with partial parameters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| audioContext | No | AudioContext is a configuration component that controls how Chromium handles the Web Audio API. | |
| autoLang | No | If true, the browser will automatically change the language to the language of your location or proxy location if proxy is enabled. | |
| bookmarks | No | Bookmarks of the browser that will be created. | |
| canvas | No | Canvas is a browser feature that utilizes the HTML5 Canvas API for rendering 2D and 3D graphics in web browsers. | |
| chromeExtensions | No | List of Chrome extensions to be installed in the browser profile. | |
| clientRects | No | Controls whether the client rectangle values are randomized. | |
| devicePixelRatio | No | Parameter of mobile devices, tablets and notebooks. If you not sure what to put - leave it empty. | |
| dns | No | Allows you to specify custom DNS (Domain Name System) settings for the browser profile. | |
| folderName | No | ||
| folders | No | List of folder identifiers associated with this browser profile for organization. | |
| fonts | No | Fonts are a configuration component that controls how Chromium handles the Fonts API. | |
| geolocation | No | Geolocation in the browser is a feature that allows websites to access the user's geographical location. | |
| lockEnabled | No | If enabled - other users will not be able to run this profile when its already running. | |
| mediaDevices | No | A feature that provides access to connected media input and output devices like cameras, microphones, and speakers. | |
| name | No | Profile name. | |
| navigator | No | ||
| notes | No | Here you can put some information about the profile that wil help you to navigate. | |
| os | No | OS type. It should be the same with the OS you want to run the browser on. | |
| osSpec | No | Here you can specify OS specification. For example chip version for macos or version of windows. | |
| proxy | No | ||
| timezone | No | The timezone configuration is a setting that controls how the browser handles time and date information. | |
| userChromeExtensions | No | List of custom Chrome extensions to be installed in the browser profile. | |
| webGL | No | WebGL (Web Graphics Library) is a JavaScript API in Chromium-based browsers that allows websites to render interactive 2D and 3D graphics without requiring plugins. It provides direct access to the computer's GPU(Graphics Processing Unit) for accelerated rendering. | |
| webGLMetadata | No | Controls WebGL metadata such as vendor and renderer information. | |
| webRTC | No | WebRTC in browser configuration refers to settings that control how the browser handles real-time communication protocols. | |
| workspaceId | No |
Implementation Reference
- src/index.ts:454-570 (handler)Dynamic handler `callDynamicTool` that implements `post_profile_custom`. It matches the tool name to the OpenAPI spec's POST `/profile/custom` endpoint (via path.replace('browser', 'profile').replace(/[^a-zA-Z0-9]/g, '_') producing _profile_custom, prefixed with 'post'), constructs the request URL/body/headers from arguments, and executes the HTTP POST request to the GoLogin API base URL.private async callDynamicTool( toolName: string, parameters: CallParameters = {}, headers: Record<string, string> = {} ): Promise<CallToolResult> { console.log('parameters', parameters.body); if (!this.apiSpec || !this.apiSpec.paths) { throw new Error('API specification not loaded'); } let targetPath = ''; let targetMethod = ''; let operation: OpenAPIV3.OperationObject | undefined; for (const [path, pathItem] of Object.entries(this.apiSpec.paths)) { if (!pathItem) continue; for (const [method, op] of Object.entries(pathItem)) { if (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'].includes(method) && op) { const opObj = op as OpenAPIV3.OperationObject; const generatedToolName = `${method}${path.replace('browser', 'profile').replace(/[^a-zA-Z0-9]/g, '_')}`; if (generatedToolName === toolName) { targetPath = path; targetMethod = method.toUpperCase(); operation = opObj; break; } } } if (operation) break; } if (!operation) { throw new Error(`Tool "${toolName}" not found`); } let url = `${this.baseUrl}${targetPath}`; const requestHeaders: Record<string, string> = { ...headers }; let requestBody: string | undefined; requestHeaders['User-Agent'] = 'gologin-mcp'; console.error('this.token', this.token); if (this.token) { requestHeaders['Authorization'] = `Bearer ${this.token}`; } if (parameters.path) { for (const [key, value] of Object.entries(parameters.path)) { url = url.replace(`{${key}}`, encodeURIComponent(value)); } } const queryParams = new URLSearchParams(); if (parameters.query) { for (const [key, value] of Object.entries(parameters.query)) { if (value) { queryParams.append(key, value); } } } if (queryParams.toString()) { url += `?${queryParams.toString()}`; } if (parameters.body && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(targetMethod)) { requestHeaders['Content-Type'] = 'application/json'; requestBody = JSON.stringify(parameters.body); } console.log('requestBody', requestBody); try { const fetchOptions: RequestInit = { method: targetMethod, headers: requestHeaders, }; console.error('fetchOptions', fetchOptions); if (requestBody) { fetchOptions.body = requestBody; } const response = await fetch(url, fetchOptions); const responseHeaders: Record<string, string> = {}; response.headers.forEach((value, key) => { responseHeaders[key] = value; }); let responseBody: any; const contentType = response.headers.get('content-type') || ''; if (contentType.includes('application/json')) { try { responseBody = await response.json(); } catch { responseBody = await response.text(); } } else { responseBody = await response.text(); } return { content: [ { type: 'text', text: `API Call Result:\n` + `URL: ${url}\n` + `Method: ${targetMethod}\n` + `Status: ${response.status} ${response.statusText}\n\n` + `Response Headers:\n${JSON.stringify(responseHeaders, null, 2)}\n\n` + `Response Body:\n${typeof responseBody === 'object' ? JSON.stringify(responseBody, null, 2) : responseBody}`, }, ], }; } catch (error) { throw new Error(`API call failed: ${error instanceof Error ? error.message : String(error)}`); } }
- src/index.ts:47-71 (registration)Dynamic registration of `post_profile_custom` tool in the ListTools response. Scans OpenAPI paths, generates tool name from POST `/profile/custom` path matching `post_profile_custom`, provides description and dynamically built inputSchema.this.server.setRequestHandler(ListToolsRequestSchema, async () => { const tools: Tool[] = []; if (this.apiSpec && this.apiSpec.paths) { for (const [path, pathItem] of Object.entries(this.apiSpec.paths)) { if (!pathItem) continue; for (const [method, operation] of Object.entries(pathItem)) { if (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'].includes(method) && operation) { const op = operation as OpenAPIV3.OperationObject; const toolName = `${method}${path.replace('browser', 'profile').replace(/[^a-zA-Z0-9]/g, '_')}`; const inputSchema = this.buildInputSchema(op, path); tools.push({ name: toolName, description: op.summary || op.description || `${method.toUpperCase()} ${path}`, inputSchema, }); } } } } return { tools }; });
- src/index.ts:204-249 (schema)`buildInputSchema` dynamically generates the input JSON schema for `post_profile_custom` by extracting and converting OpenAPI path/query/body parameter schemas from the spec's POST `/profile/custom` operation.private buildInputSchema(operation: OpenAPIV3.OperationObject, path: string): any { const properties: any = {}; const required: string[] = []; const pathParams = this.extractPathParameters(operation, path); const queryParams = this.extractQueryParameters(operation); const bodySchema = this.extractRequestBodySchema(operation); if (pathParams.properties && Object.keys(pathParams.properties).length > 0) { for (const [key, prop] of Object.entries(pathParams.properties)) { properties[key] = this.convertOpenAPISchemaToJsonSchema(prop as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject); if (pathParams.required.includes(key)) { required.push(key); } } } if (queryParams.properties && Object.keys(queryParams.properties).length > 0) { for (const [key, prop] of Object.entries(queryParams.properties)) { properties[key] = this.convertOpenAPISchemaToJsonSchema(prop as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject); if (queryParams.required.includes(key)) { required.push(key); } } } if (bodySchema && bodySchema.properties) { for (const [key, prop] of Object.entries(bodySchema.properties)) { properties[key] = this.convertOpenAPISchemaToJsonSchema(prop as OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject); if (bodySchema.required && bodySchema.required.includes(key)) { required.push(key); } } } const schema: any = { type: 'object', properties, }; if (required.length > 0) { schema.required = required; } return schema; }
- src/index.ts:96-175 (helper)`extractParametersFromArgs` helper: for `post_profile_custom`, resolves toolName to the matching OpenAPI operation, parses arguments into path params (e.g. for {id} etc.), query, and body.private extractParametersFromArgs(toolName: string, args: Record<string, any>): CallParameters { if (!this.apiSpec || !this.apiSpec.paths) { return { body: args }; } let operation: OpenAPIV3.OperationObject | undefined; let path = ''; for (const [apiPath, pathItem] of Object.entries(this.apiSpec.paths)) { if (!pathItem) continue; for (const [method, op] of Object.entries(pathItem)) { if (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'].includes(method) && op) { const opObj = op as OpenAPIV3.OperationObject; const generatedToolName = opObj.operationId || `${method}_${apiPath.replace(/[^a-zA-Z0-9]/g, '_')}`; if (generatedToolName === toolName) { operation = opObj; path = apiPath; break; } } } if (operation) break; } if (!operation) { return { body: args }; } const pathParams: Record<string, string> = {}; const queryParams: Record<string, string> = {}; const bodyParams: any = {}; const pathParamNames = path.match(/\{([^}]+)\}/g)?.map(p => p.slice(1, -1)) || []; if (operation.parameters) { operation.parameters.forEach(param => { if ('$ref' in param) return; const parameter = param as OpenAPIV3.ParameterObject; const paramName = parameter.name; if (parameter.in === 'path' && args[paramName] !== undefined) { pathParams[paramName] = String(args[paramName]); } else if (parameter.in === 'query' && args[paramName] !== undefined) { queryParams[paramName] = String(args[paramName]); } }); } pathParamNames.forEach(paramName => { if (args[paramName] !== undefined && !pathParams[paramName]) { pathParams[paramName] = String(args[paramName]); } }); const usedParams = new Set([...Object.keys(pathParams), ...Object.keys(queryParams)]); for (const [key, value] of Object.entries(args)) { if (!usedParams.has(key)) { bodyParams[key] = value; } } const parameters: CallParameters = {}; if (Object.keys(pathParams).length > 0) { parameters.path = pathParams; } if (Object.keys(queryParams).length > 0) { parameters.query = queryParams; } if (Object.keys(bodyParams).length > 0) { parameters.body = bodyParams; } return parameters; }
- src/index.ts:177-202 (helper)Loads the external OpenAPI specification that defines the `/profile/custom` POST endpoint used by `post_profile_custom` tool.private async loadApiSpec(): Promise<void> { const url = 'https://docs-download.gologin.com/openapi-test.json'; console.log('url', url); const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const contentType = response.headers.get('content-type') || ''; let spec: any; if (contentType.includes('application/json')) { spec = await response.json(); } else { const text = await response.text(); try { spec = JSON.parse(text); } catch { spec = yaml.load(text); } } // console.log('spec', spec); this.apiSpec = spec; this.baseUrl = this.getBaseUrl(spec); }