Skip to main content
Glama

get_recent_logs

Retrieve recent coding activity logs from Wakapi to analyze development time, filter by project, and track productivity insights.

Instructions

Get heartbeats of user for recent days (extension of heartbeats GET).

Mimics https://wakatime.com/api/v1/users/{user}/heartbeats for multiple days.

Requires ApiKeyAuth: Set header Authorization to your API Key encoded as Base64 and prefixed with Basic.

Args: user (str, required, default="current"): Username (or current). project_name (str, optional): Filter by project. days (int, default=7): Number of days to retrieve. limit (int, default=1000): Maximum number of heartbeats.

Returns: List of HeartbeatEntry: Each with id (str), project (str), language (str), entity (str), time (number), is_write (bool), branch (str), category (str), cursorpos (int), line_additions (int), line_deletions (int), lineno (int), lines (int), type (str), user_agent_id (str), user_id (str), machine_name_id (str), created_at (str). Sorted by time descending.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
userNocurrent
project_nameNo
daysNo
limitNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The core handler function for the 'get_recent_logs' tool. Decorated with @app.tool, it fetches heartbeats from the Wakapi API for the last N days, optionally filtered by project, sorts them by time descending, limits the results, and returns a list of formatted dictionaries.
    @app.tool
    async def get_recent_logs(
        user: str = "current",
        project_name: Optional[str] = None,
        days: int = 7,
        limit: int = 1000,
    ) -> list[dict[str, Any]]:
        """Get heartbeats of user for recent days (extension of heartbeats GET).
    
        Mimics https://wakatime.com/api/v1/users/{user}/heartbeats for multiple days.
    
        Requires ApiKeyAuth: Set header `Authorization` to your API Key encoded as Base64
        and prefixed with `Basic`.
    
        Args:
            user (str, required, default="current"): Username (or current).
            project_name (str, optional): Filter by project.
            days (int, default=7): Number of days to retrieve.
            limit (int, default=1000): Maximum number of heartbeats.
    
        Returns:
            List of HeartbeatEntry: Each with id (str), project (str), language (str),
            entity (str), time (number), is_write (bool), branch (str), category (str),
            cursorpos (int), line_additions (int), line_deletions (int), lineno (int),
            lines (int), type (str), user_agent_id (str), user_id (str),
            machine_name_id (str), created_at (str).
            Sorted by time descending.
        """
        client = get_wakapi_client()
    
        end_date = datetime.now()
        all_logs = []
    
        current_date = end_date.date()
        for i in range(days):
            day_date = current_date - timedelta(days=i)
            try:
                day_logs = await client.get_heartbeats(
                    user=user,
                    date=day_date,
                    project=project_name,
                    limit=limit // days + 1 if days > 0 else limit,
                )
                all_logs.extend(day_logs.data if hasattr(day_logs, "data") else day_logs)
            except Exception as e:
                raise ValueError(f"Failed to fetch recent logs: {e}") from e
    
        # Sort by time descending
        all_logs.sort(key=lambda log: log.time, reverse=True)
    
        # Limit total results
        all_logs = all_logs[:limit]
    
        # Convert to dict
        return [
            {
                "id": log.id,
                "project": log.project,
                "language": log.language,
                "entity": log.entity,
                "time": log.time.timestamp()
                if isinstance(log.time, datetime)
                else log.time,
                "is_write": log.is_write,
                "branch": log.branch,
                "category": getattr(log, "category", None),
                "cursorpos": getattr(log, "cursorpos", None),
                "line_additions": getattr(log, "line_additions", None),
                "line_deletions": getattr(log, "line_deletions", None),
                "lineno": getattr(log, "lineno", None),
                "lines": getattr(log, "lines", None),
                "type": log.type,
                "user_agent_id": getattr(log, "user_agent_id", None),
                "user_id": log.user_id,
                "machine_name_id": getattr(log, "machine_name_id", None),
                "created_at": log.time.isoformat()
                if isinstance(log.time, datetime)
                else None,
            }
            for log in all_logs
        ]
  • main.py:126-155 (registration)
    The initialize_tools function imports get_recent_logs and assigns it to _ , triggering the @app.tool decorator to register the tool with the MCP server.
    def initialize_tools():
        """Initialize and register all Wakapi tools."""
        try:
            # Direct imports to avoid circular import in __init__.py
            from mcp_tools.stats import get_stats
    
            _ = get_stats  # Trigger registration
            from mcp_tools.projects import get_projects
    
            _ = get_projects  # Trigger registration
            from mcp_tools.leaders import get_leaders
    
            _ = get_leaders  # Trigger registration
            from mcp_tools.users import get_user
    
            _ = get_user  # Trigger registration
            from mcp_tools.all_time import get_all_time_since_today
    
            _ = get_all_time_since_today  # Trigger registration
            from mcp_tools.project_detail import get_project_detail
    
            _ = get_project_detail  # Trigger registration
            from mcp_tools.recent_logs import get_recent_logs
    
            _ = get_recent_logs  # Trigger registration
            from mcp_tools.connection import test_connection
    
            _ = test_connection  # Trigger registration
            print("All Wakapi tools registered successfully.", file=sys.stderr)
        except ImportError as e:
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and delivers substantial behavioral information. It discloses authentication requirements (ApiKeyAuth with specific header format), describes the return format in detail, mentions sorting behavior ('Sorted by time descending'), and references the external API it mimics. It doesn't mention rate limits, error conditions, or pagination behavior, preventing a perfect score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear sections: purpose statement, API reference, authentication requirements, parameter documentation, and return format. Each sentence adds value. It could be slightly more concise by combining some return field explanations, but overall it's efficiently organized and front-loaded with the core purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 4 parameters, 0% schema description coverage, no annotations, but with output schema details provided, the description is remarkably complete. It covers authentication, parameters, return format, sorting behavior, and API context. The detailed return type documentation compensates for the lack of output schema, making this description comprehensive for agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Given 0% schema description coverage, the description fully compensates by providing detailed parameter documentation. Each of the 4 parameters is clearly explained with type, requirement status, defaults, and purpose. The description adds crucial semantic context beyond what the bare schema provides, such as 'user (or current)' clarification and filtering behavior for project_name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get heartbeats of user for recent days' with specific resource (heartbeats) and scope (recent days). It distinguishes from siblings by specifying it's an extension of heartbeats GET for multiple days, differentiating from tools like get_stats or get_user. However, it doesn't explicitly contrast with all siblings like get_projects or get_project_detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by mentioning it's an 'extension of heartbeats GET' and 'mimics' a specific API endpoint, suggesting when this tool might be preferred over simpler heartbeats queries. However, it doesn't provide explicit guidance on when to use this vs. alternatives like get_stats or get_projects, nor does it mention any prerequisites beyond authentication.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/impure0xntk/mcp-wakapi'

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