Skip to main content
Glama
fetch.ts5.33 kB
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; import { Api, MemberWithUser, ProjectListItem } from '@neondatabase/api-client'; import { fetchInputSchema } from '../toolsSchema.js'; import { z } from 'zod'; import { handleDescribeProject } from './decribe-project.js'; import { handleDescribeBranch } from './describe-branch.js'; import { ToolHandlerExtraParams } from '../types.js'; import { generateConsoleUrl, CONSOLE_URLS } from './urls.js'; type FetchProps = z.infer<typeof fetchInputSchema>; export async function handleFetch( { id }: FetchProps, neonClient: Api<unknown>, extra: ToolHandlerExtraParams, ): Promise<CallToolResult> { try { // Parse the ID format if (id.startsWith('org:') || id.startsWith('org-')) { return await fetchOrganizationDetails(id.slice(4), neonClient); } else if (id.startsWith('branch:')) { const [projectId, branchId] = id.slice(7).split('/'); return await fetchBranchDetails(projectId, branchId, neonClient, extra); } else if (id.startsWith('project:')) { return await fetchProjectDetails(id.slice(8), neonClient); } else { return { isError: true, content: [ { type: 'text', text: `Invalid ID format: "${id}". Expected format: org:*, project:*, or branch:*`, }, ], }; } } catch (error) { return { isError: true, content: [ { type: 'text', text: `Failed to fetch details: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } } async function fetchOrganizationDetails( orgId: string, neonClient: Api<unknown>, ): Promise<CallToolResult> { try { const { data: orgData } = await neonClient.getOrganization(orgId); let members: MemberWithUser[] = []; try { const { data: membersData } = await neonClient.getOrganizationMembers(orgId); members = membersData.members || []; } catch { // Skip if we can't access members } // Get projects count in this organization let projects: ProjectListItem[] = []; try { const { data: projectsData } = await neonClient.listProjects({ org_id: orgId, }); projects = projectsData.projects || []; } catch { // Skip if we can't access projects } const details = { organization: { id: orgData.id, name: orgData.name, created_at: orgData.created_at, updated_at: orgData.updated_at, }, console_url: generateConsoleUrl(CONSOLE_URLS.ORGANIZATION, { orgId: orgData.id, }), }; return { content: [ { type: 'text', text: `**Organization Details** **Basic Information:** - Name: ${details.organization.name} - ID: ${details.organization.id} - Created: ${new Date(details.organization.created_at).toLocaleDateString()} **Statistics:** ${members.length > 0 ? `- Members: ${members.length}` : undefined} - Projects: ${projects.length} `, metadata: { org: orgData, members: members, projects: projects, }, }, ], }; } catch (error) { return { isError: true, content: [ { type: 'text', text: `Failed to fetch organization details: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } } async function fetchProjectDetails( projectId: string, neonClient: Api<unknown>, ): Promise<CallToolResult> { try { const { project, branches } = await handleDescribeProject( projectId, neonClient, ); const defaultBranch = branches.find((branch) => branch.default); return { content: [ { type: 'text', text: `**Project Details** **Basic Information:** - Name: ${project.name} - ID: ${project.id} - Region: ${project.region_id} - PostgreSQL Version: ${project.pg_version} - Created: ${new Date(project.created_at).toLocaleDateString()} - Last Updated: ${new Date(project.updated_at).toLocaleDateString()} **Statistics:** - Branches: ${branches.length} - Default Branch: ${defaultBranch?.name} (${defaultBranch?.id}) `, metadata: { project: project, branches: branches, }, }, ], }; } catch (error) { return { isError: true, content: [ { type: 'text', text: `Failed to fetch project details: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } } async function fetchBranchDetails( projectId: string, branchId: string, neonClient: Api<unknown>, extra: ToolHandlerExtraParams, ): Promise<CallToolResult> { try { const result = await handleDescribeBranch( { projectId, branchId, }, neonClient, extra, ); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { isError: true, content: [ { type: 'text', text: `Failed to fetch branch details: ${error instanceof Error ? error.message : 'Unknown error'}`, }, ], }; } }

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/neondatabase-labs/mcp-server-neon'

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