Skip to main content
Glama

SharePoint Online MCP Server

by Zerg00s
getGlobalNavigationLinks.ts6.53 kB
// src/tools/getGlobalNavigationLinks.ts import request from 'request-promise'; import { IToolResult } from '../interfaces'; import { getSharePointHeaders, getRequestDigest } from '../auth_factory'; import { SharePointConfig } from '../config'; export interface GetGlobalNavigationLinksParams { url: string; } /** * Get global navigation links from a SharePoint site using MenuState API * @param params Parameters including site URL * @param config SharePoint configuration * @returns Tool result with global navigation links data */ export async function getGlobalNavigationLinks( params: GetGlobalNavigationLinksParams, config: SharePointConfig ): Promise<IToolResult> { const { url } = params; console.error(`getGlobalNavigationLinks tool called with URL: ${url}`); try { // Authenticate with SharePoint const headers = await getSharePointHeaders(url, config); console.error("Headers prepared with authentication"); // Try an alternative approach first - get web navigation nodes directly console.error("Trying direct navigation nodes approach for global navigation..."); let useDirectApi = true; let menuStateResponse; try { const topNavUrl = `${url}/_api/web/Navigation/TopNavigationBar`; console.error(`Requesting navigation from: ${topNavUrl}`); menuStateResponse = await request({ url: topNavUrl, headers: headers, json: true, method: 'GET', timeout: 30000 }); // Check if we got a valid response if (!menuStateResponse.d || !menuStateResponse.d.results) { console.error("Direct API did not return expected structure, falling back to MenuState API"); useDirectApi = false; } } catch (directApiError) { console.error("Direct API approach failed:", directApiError); useDirectApi = false; } // Fall back to original MenuState approach if direct approach failed if (!useDirectApi) { console.error("Getting global navigation links using MenuState API..."); menuStateResponse = await request({ url: `${url}/_api/navigation/MenuState?mapProviderName='GlobalNavigationSwitchableProvider'`, headers: headers, json: true, method: 'GET', timeout: 30000 }); } let formattedNodes = []; let menuState: any = null; let accessMethod = useDirectApi ? "direct" : "menustate"; if (useDirectApi) { // Process the direct navigation nodes response const navNodes = menuStateResponse.d.results || []; console.error(`Retrieved ${navNodes.length} global navigation links using direct API`); // Format the navigation nodes for display formattedNodes = navNodes.map((node: any) => ({ Key: node.Id?.toString() || "", Title: node.Title || "", Url: node.Url || "", IsExternal: node.IsExternal || false, HasChildren: false, // Direct API doesn't provide children info ParentKey: null, Children: [] // Direct API doesn't provide children })); } else { // Process the menu state to extract navigation nodes menuState = menuStateResponse.MenuState; const navNodes = menuState.Nodes || []; console.error(`Retrieved ${navNodes.length} global navigation links using MenuState API`); // Format the navigation nodes for display formattedNodes = navNodes .filter((node: any) => !node.IsDeleted) // Filter out deleted nodes .map((node: any) => ({ Key: node.Key, Title: node.Title, Url: node.SimpleUrl, IsExternal: node.FriendlyUrlSegment === '' && !node.SimpleUrl.startsWith(menuState.SPSitePrefix), HasChildren: (node.Nodes && node.Nodes.length > 0) || false, ParentKey: node.ParentKey || null, Children: (node.Nodes && node.Nodes.length > 0) ? node.Nodes .filter((childNode: any) => !childNode.IsDeleted) .map((childNode: any) => ({ Key: childNode.Key, Title: childNode.Title, Url: childNode.SimpleUrl, IsExternal: childNode.FriendlyUrlSegment === '' && !childNode.SimpleUrl.startsWith(menuState.SPSitePrefix), ParentKey: node.Key })) : [] })); } const responseData: any = { siteUrl: url, navLinksCount: formattedNodes.length, accessMethod: accessMethod, navLinks: formattedNodes }; // Include menuState info if available if (menuState) { responseData.menuState = { version: menuState.Version, startingNodeKey: menuState.StartingNodeKey, startingNodeTitle: menuState.StartingNodeTitle, sitePrefix: menuState.SPSitePrefix, webPrefix: menuState.SPWebPrefix }; } return { content: [{ type: "text", text: JSON.stringify(responseData, null, 2) }] } as IToolResult; } catch (error: unknown) { // Type-safe error handling let errorMessage: string; if (error instanceof Error) { errorMessage = error.message; } else if (typeof error === 'string') { errorMessage = error; } else { errorMessage = "Unknown error occurred"; } console.error("Error in getGlobalNavigationLinks tool:", errorMessage); return { content: [{ type: "text", text: `Error getting global navigation links: ${errorMessage}` }], isError: true } as IToolResult; } } export default getGlobalNavigationLinks;

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/Zerg00s/server-sharepoint'

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