complete_authentication
Exchange the tokenId from browser login redirect for an access token to finalize authentication with DhanHQ trading APIs.
Instructions
Completes the authentication flow (Step 3). Takes the tokenId from the redirect URL after browser login and exchanges it for an access token.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tokenId | Yes | The tokenId received in the redirect URL after browser login (Step 2). |
Input Schema (JSON Schema)
{
"properties": {
"tokenId": {
"description": "The tokenId received in the redirect URL after browser login (Step 2).",
"type": "string"
}
},
"required": [
"tokenId"
],
"type": "object"
}
Implementation Reference
- src/index.ts:406-431 (handler)MCP CallTool handler case for 'complete_authentication': validates input, calls consumeConsent helper, and returns formatted success response with auth token.case 'complete_authentication': { console.error('[Tool] Executing: complete_authentication'); const { tokenId } = args as Record<string, unknown>; if (!tokenId) { throw new Error('tokenId is required'); } const authToken = await consumeConsent(tokenId as string); return { content: [ { type: 'text' as const, text: JSON.stringify( { success: true, message: 'Authentication completed successfully', authToken, }, null, 2 ), }, ], }; }
- src/index.ts:71-86 (schema)Tool schema definition including name, description, and inputSchema requiring 'tokenId' string.{ name: 'complete_authentication', description: 'Completes the authentication flow (Step 3). Takes the tokenId from the redirect URL after browser login and exchanges it for an access token.', inputSchema: { type: 'object' as const, properties: { tokenId: { type: 'string' as const, description: 'The tokenId received in the redirect URL after browser login (Step 2).', }, }, required: ['tokenId'], }, },
- src/authentication.ts:120-166 (helper)Core helper function implementing the API call to Dhan auth endpoint to exchange tokenId for access token, store auth state, and return DhanAuthToken.export async function consumeConsent( tokenId: string ): Promise<DhanAuthToken> { try { log('Consuming consent with tokenId...'); const response = await axios.get<AuthStep3Response>( `${AUTH_BASE_URL}/app/consumeApp-consent?tokenId=${tokenId}`, { headers: { app_id: dhanConfig.apiKey, app_secret: dhanConfig.apiSecret, }, } ); const authToken: DhanAuthToken = { accessToken: response.data.accessToken, dhanClientId: response.data.dhanClientId, dhanClientName: response.data.dhanClientName, dhanClientUcc: response.data.dhanClientUcc, expiryTime: response.data.expiryTime, givenPowerOfAttorney: response.data.givenPowerOfAttorney, generatedAt: new Date().toISOString(), }; authState.authToken = authToken; authState.tokenId = tokenId; log('✓ Access token generated successfully'); log(`Client Name: ${authToken.dhanClientName}`); log(`Client ID: ${authToken.dhanClientId}`); log(`Token Expiry: ${authToken.expiryTime}`); return authToken; } catch (error) { const errorMessage = error instanceof axios.AxiosError ? `API Error: ${error.response?.status} - ${error.response?.data}` : error instanceof Error ? error.message : 'Unknown error'; log(`✗ Failed: ${errorMessage}`); throw new Error(`Step 3 Failed: ${errorMessage}`); } }