Skip to main content
Glama
activities.tools.ts3.97 kB
import { Injectable } from '@nestjs/common'; import { Tool } from '@rekog/mcp-nest'; import { z } from 'zod'; import { AuthService } from '@/auth/auth.service'; import { ActivitiesService } from './activities.service'; import { ResponseUtil } from '@/common/utils/response.util'; /** * MCP Tools for activity management * Provides descriptive tool name for LLM decision making: * - list_all_available_work_activities: Get all predefined work activity types that can be logged in timesheet */ @Injectable() export class ActivitiesTools { constructor( private readonly authService: AuthService, private readonly activitiesService: ActivitiesService, ) {} /** * Authenticate using environment credentials if no token exists */ private async ensureAuthenticated(): Promise<{ user: any; token: string } | null> { try { // Try to get existing token let user = this.authService.getCurrentUser(); let token = this.authService.getToken(); // Try to refresh token try { const refreshedToken = await this.authService.refreshToken(); if (refreshedToken) { token = refreshedToken; try { user = this.authService.getCurrentUser(); } catch (e) { // Continue with existing user } } } catch (error) { // Token refresh failed, try to login with env credentials return await this.authenticateWithEnvCredentials(); } return { user, token }; } catch (error) { // No token in config, try to login with env credentials return await this.authenticateWithEnvCredentials(); } } /** * Authenticate using environment variables */ private async authenticateWithEnvCredentials(): Promise<{ user: any; token: string } | null> { const username = process.env.TIMESHEET_USERNAME; const password = process.env.TIMESHEET_PASSWORD; if (!username || !password) { return null; } try { const loginResult = await this.authService.login(username, password); if (!loginResult.success || !loginResult.user) { return null; } try { const user = this.authService.getCurrentUser(); const token = this.authService.getToken(); return { user, token }; } catch (error) { return null; } } catch (error) { return null; } } @Tool({ name: 'list_all_available_work_activities', description: 'Get all available work activity types or task categories that can be used when creating timesheet entries. Activities represent the type of work being logged (e.g., Development, Code Review, Testing, Deployment, Documentation, Meetings, etc.). Use this to select the appropriate activity_id when creating a timesheet entry. Automatically handles authentication with fresh token. Calls: GET /api/activities', parameters: z.object({}), }) async listAllAvailableWorkActivities() { try { const auth = await this.ensureAuthenticated(); if (!auth || !auth.user || !auth.token) { const username = process.env.TIMESHEET_USERNAME; const password = process.env.TIMESHEET_PASSWORD; if (!username || !password) { return ResponseUtil.error( 'User not authenticated. Please configure TIMESHEET_USERNAME and TIMESHEET_PASSWORD in your MCP client environment variables.', ); } return ResponseUtil.error( 'Authentication failed: Invalid username or password. Please verify your credentials in the MCP client configuration.', ); } const activities = await this.activitiesService.getAllActivities(); return ResponseUtil.success( '✓ Available work activities fetched successfully!', activities, ); } catch (error) { return ResponseUtil.error( error.message || 'Failed to fetch available activities', ); } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/arshad-khan1/Timesheet-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server