Skip to main content
Glama

Fonoster MCP Server

Official
by fonoster
MIT License
118
7,391
  • Apple
  • Linux
apps.page.tsx5.85 kB
/** * Copyright (C) 2025 by Fonoster Inc (https://fonoster.com) * http://github.com/fonoster/fonoster * * This file is part of Fonoster * * Licensed under the MIT License (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * https://opensource.org/licenses/MIT * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import type { Route } from "./+types/apps.page"; import { useCallback, useState } from "react"; import { Page } from "~/core/components/general/page/page"; import { DataTable } from "~/core/components/design-system/ui/data-table/data-table"; import { toast } from "~/core/components/design-system/ui/toaster/toaster"; import { columns } from "./apps.columns"; import { ApplicationsPageHeader } from "./apps.page-header"; import { APPS_SEARCHABLE_FIELDS } from "./apps.const"; import { useApplications, useDeleteApplication } from "~/applications/services/applications.service"; import { useResourceTable } from "~/core/hooks/use-resource-table"; import { PAGE_SIZE } from "~/core/shared/page-sizes.const"; import type { Application } from "@fonoster/types"; import { useNavigate } from "react-router"; import { useWorkspaceId } from "~/workspaces/hooks/use-workspace-id"; /** * Returns metadata for the applications page. * Used by the routing system to set the page title and meta description. * * @param _ - Meta arguments (unused in this case). * @returns Array of meta objects for the page. */ export function meta(_: Route.MetaArgs) { return [ { title: "Voice Applications | Fonoster" }, { name: "description", content: "Manage your External and Autopilot applications here. Autopilot uses LLMs to handle conversations; External lets you run custom business logic." } ]; } /** * Main component responsible for displaying and managing voice applications. * Integrates search, pagination, delete, and edit functionalities via a reusable DataTable component. */ export default function Applications() { /** Hook to navigate programmatically within the application. */ const navigate = useNavigate(); /** Retrieves the current workspace ID for API calls and navigation. */ const workspaceId = useWorkspaceId(); /** State to hold the current pagination token used to fetch a specific page of data. */ const [pageToken, setPageToken] = useState<string | undefined>(undefined); /** Fetch applications data using the current page token and page size. */ const { data, nextPageToken, isLoading } = useApplications({ pageSize: PAGE_SIZE, pageToken }); /** Hook to delete an application via the API. */ const { mutateAsync: deleteApplication } = useDeleteApplication(); /** * Custom hook for table management: * - Handles search functionality * - Handles filtering * - Handles pagination (next/prev pages) * - Handles deletion of selected rows */ const { filteredData, searchBy, setSearchBy, handleNextPage, handlePrevPage, handleSearch, handleDelete, prevTokens } = useResourceTable({ data, pageSize: PAGE_SIZE, pageToken, setPageToken, deleteResource: deleteApplication, searchableFields: APPS_SEARCHABLE_FIELDS, defaultSearchBy: "ref" }); /** * Callback function to handle editing a selected application. * * Navigates to the edit page for the selected application. * Uses view transitions for a smoother user experience. * @param ref - The reference of the application to edit. * @param {ICredential} ref - The application object containing the reference. * @returns {void} */ const onEditSelected = useCallback(({ ref }: Application) => { navigate(`/workspaces/${workspaceId}/applications/${ref}/edit`, { viewTransition: true }); }, []); return ( <Page> <ApplicationsPageHeader /> <DataTable /** Displays loading state when data is being fetched. */ isLoading={isLoading} /** Data to be displayed in the table (filtered based on search). */ data={filteredData} /** Column definitions for the table. */ columns={columns} /** Function to get a unique row ID for each record. */ getRowId={(row) => row.ref} /** Current field selected for searching. */ searchBy={searchBy} /** List of searchable fields displayed in the UI. */ searchableFields={APPS_SEARCHABLE_FIELDS} /** Number of rows per page. */ pageSize={PAGE_SIZE} /** Pagination controls for next/prev pages. */ pagination={{ total: filteredData.length, nextToken: nextPageToken, prevToken: prevTokens.length ? prevTokens[prevTokens.length - 1] : null }} /** Handler for navigating to the next page. */ onNextPage={() => handleNextPage(nextPageToken)} /** Handler for navigating to the previous page. */ onPrevPage={handlePrevPage} /** Handler for updating the search term. */ onSearch={handleSearch} /** Handler for changing the search field. */ onSearchByFieldChange={setSearchBy} /** Handler for deleting selected rows. */ onDeleteSelected={handleDelete} /** Handler for editing selected rows (currently shows a toast). */ onEditSelected={onEditSelected} /** Handler for clicking on a row to navigate to edit page. */ onRowClick={onEditSelected} /> </Page> ); }

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/fonoster/fonoster'

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