Skip to main content
Glama
github.ts4.33 kB
import { Octokit } from "@octokit/rest"; import type { RestEndpointMethodTypes } from "@octokit/rest"; import type { GitHubActivityData, GitHubActivityItem } from "./types.js"; import { cacheOrFetch, CACHE_CONFIGS } from "../utils/cache.js"; type GitHubEvent = RestEndpointMethodTypes["activity"]["listPublicEventsForUser"]["response"]["data"][0]; /** * Format a single GitHub event into a structured activity item */ export function formatGitHubEvent(event: GitHubEvent, includeDetails = false): GitHubActivityItem { const date = new Date(event.created_at || new Date()).toLocaleDateString(); const repository = event.repo?.name || "Unknown repository"; let action = ""; let details = ""; switch (event.type) { case "PushEvent": { const payload = event.payload as any; const commits = payload?.commits?.length || 0; action = `Pushed ${commits} commit${commits > 1 ? "s" : ""}`; if (includeDetails && payload?.commits) { const commitMessages = payload.commits .slice(0, 3) .map((c: any) => ` - ${c.message}`) .join("\n"); details = `\n${commitMessages}`; } break; } case "CreateEvent": { const payload = event.payload as any; const refType = payload?.ref_type || "repository"; action = `Created ${refType}`; break; } case "IssuesEvent": { const payload = event.payload as any; const issueAction = payload?.action || "updated"; action = `${issueAction} issue`; if (includeDetails && payload?.issue) { details = `\n - ${payload.issue.title}`; } break; } case "PullRequestEvent": { const payload = event.payload as any; const prAction = payload?.action || "updated"; action = `${prAction} pull request`; if (includeDetails && payload?.pull_request) { details = `\n - ${payload.pull_request.title}`; } break; } case "WatchEvent": action = "Starred repository"; break; case "ForkEvent": action = "Forked repository"; break; case "ReleaseEvent": { const payload = event.payload as any; action = `${payload?.action || "created"} release`; if (includeDetails && payload?.release) { details = `\n - ${payload.release.tag_name}: ${payload.release.name}`; } break; } default: action = `${(event.type || "Unknown").replace("Event", "")}`; } return { type: event.type || "Unknown", action, repository, date, details: details || undefined, }; } /** * Fetch GitHub activity data (internal, not cached) */ async function fetchGitHubActivityData( limit: number, includeDetails: boolean, ): Promise<GitHubActivityData> { const username = "duyet"; const profileUrl = `https://github.com/${username}`; try { const octokit = new Octokit(); const { data: events } = await octokit.rest.activity.listPublicEventsForUser({ username, per_page: limit, }); if (events.length === 0) { return { activities: [], totalRetrieved: 0, profileUrl, username, }; } const activities = events.map((event) => formatGitHubEvent(event, includeDetails)); return { activities, totalRetrieved: activities.length, profileUrl, username, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; throw new Error(`Error fetching GitHub activity: ${errorMessage}`); } } /** * Get GitHub activity data with caching (15 minutes TTL) * This is the public API that should be used by tools/resources */ export async function getGitHubActivityData( limit = 5, includeDetails = false, ): Promise<GitHubActivityData> { const limitNum = Math.min(Math.max(limit, 1), 20); const cacheKey = `github-activity-${limitNum}-${includeDetails}`; return cacheOrFetch( cacheKey, CACHE_CONFIGS.GITHUB, () => fetchGitHubActivityData(limitNum, includeDetails), ); } /** * Format GitHub activity data for display */ export function formatGitHubActivityForDisplay(data: GitHubActivityData): string { if (data.activities.length === 0) { return "No recent GitHub activity found."; } const activityList = data.activities .map( (activity) => `${activity.action} in ${activity.repository} (${activity.date})${activity.details || ""}`, ) .join("\n\n"); return `Recent GitHub Activity for ${data.username}: ${activityList} GitHub Profile: ${data.profileUrl}`; }

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/duyet/duyet-mcp-server'

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