save_session
Save the browser session after manual login to Upwork. Verifies successful login, then persists cookies and storage for future headless automation. Call this after fully logged in.
Instructions
Step 2: After manually logging in via manual_login, call this to save the browser session. Checks if login was successful and saves cookies/storage for future headless use. Must be called AFTER you have fully logged in to Upwork in the browser window.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/manual-login.ts:46-130 (handler)Core handler for save_session. The `manualLogin` function connects to Chrome via CDP, extracts cookies from an Upwork tab, and saves the session file. It is re-exported as `saveSession` on line 132.
export async function manualLogin(): Promise<{ success: boolean; message: string }> { try { log('Checking CDP at localhost:', CDP_PORT); // Get list of tabs const targets = await cdpFetch('/json') as Array<{ type: string; url: string; webSocketDebuggerUrl: string; title: string; }>; const upworkTarget = targets.find(t => t.type === 'page' && t.url.includes('upwork.com') ); if (!upworkTarget) { const allUrls = targets.filter(t => t.type === 'page').map(t => t.url); return { success: false, message: `Chrome is connected but no Upwork tab found.\nOpen tabs: ${allUrls.join(', ')}\nPlease navigate to upwork.com first.`, }; } log('Found Upwork tab:', upworkTarget.url); // Check if logged in if (upworkTarget.url.includes('/login') || upworkTarget.url.includes('account-security')) { return { success: false, message: `Upwork tab found but not logged in. URL: ${upworkTarget.url}\nPlease login to Upwork first, then call manual_login again.`, }; } // Get all cookies for upwork.com const cookieResult = await cdpCommand( upworkTarget.webSocketDebuggerUrl, 'Network.getAllCookies' ) as { cookies: Array<{ name: string; value: string; domain: string; path: string; expires: number; httpOnly: boolean; secure: boolean; sameSite?: string; }> }; const upworkCookies = cookieResult.cookies.filter(c => c.domain.includes('upwork.com') ); log(`Found ${upworkCookies.length} Upwork cookies`); // Build Playwright-compatible storageState format const storageState = { cookies: upworkCookies.map(c => ({ name: c.name, value: c.value, domain: c.domain, path: c.path, expires: c.expires, httpOnly: c.httpOnly, secure: c.secure, sameSite: (c.sameSite as 'Strict' | 'Lax' | 'None') ?? 'None', })), origins: [] as unknown[], }; // Save session file const sessionDir = path.dirname(config.session.file); fs.mkdirSync(sessionDir, { recursive: true }); fs.writeFileSync(config.session.file, JSON.stringify(storageState, null, 2)); log('Session saved to', config.session.file); return { success: true, message: `Session saved! Extracted ${upworkCookies.length} cookies from: ${upworkTarget.url}\nAll tools are now ready. Session file: ${config.session.file}`, }; } catch (err) { const msg = err instanceof Error ? err.message : String(err); if (msg.includes('ECONNREFUSED') || msg.includes('fetch') || msg.includes('connect')) { return { success: false, message: 'Cannot connect to Chrome CDP. Chrome is not running with --remote-debugging-port=9222.\n' + 'Fix: Run "connect-chrome.bat" in the upwork-mcp folder, then call manual_login again.', }; } return { success: false, message: `Error: ${msg}` }; } } - src/tools/manual-login.ts:132-132 (helper)Re-export alias: `manualLogin` is exported as `saveSession`, making the same function available under both names.
export { manualLogin as saveSession }; - src/index.ts:33-39 (schema)Tool schema definition for `save_session` — declares it as an object with no required properties, with a description that it's Step 2 after manual_login.
{ name: 'save_session', description: `Step 2: After manually logging in via manual_login, call this to save the browser session. Checks if login was successful and saves cookies/storage for future headless use. Must be called AFTER you have fully logged in to Upwork in the browser window.`, inputSchema: { type: 'object', properties: {} }, }, - src/index.ts:284-287 (registration)Registration in the direct MCP server (`src/index.ts`): the `save_session` case dispatches to `saveSession()` in the CallTool request handler.
case 'save_session': { result = await saveSession(); break; } - src/gateway.ts:54-58 (registration)Registration in the gateway MCP server (`src/gateway.ts`): the `save_session` tool definition (alias for manual_login) in the gateway's tool list.
{ name: 'save_session', description: 'Alias for manual_login — re-save session from current Chrome tab.', inputSchema: { type: 'object', properties: {} }, },