Skip to main content
Glama
marianfoo

SAP Documentation MCP Server

by marianfoo

sap_help_get

Retrieve complete SAP Help Portal page content using exact result IDs from search results to access detailed documentation and metadata.

Instructions

GET SAP HELP PAGE: sap_help_get(result_id="sap-help-12345abc")

FUNCTION NAME: sap_help_get (or mcp_sap-docs-remote_sap_help_get)

RETRIEVES: Complete SAP Help Portal page content REQUIRES: Exact result_id from sap_help_search

USAGE PATTERN:

  1. Get ID from sap_help_search results

  2. Use exact ID (don't modify the format)

  3. Receive full page content + metadata

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
result_idYesExact ID from sap_help_search results. Copy the ID exactly as returned.

Implementation Reference

  • Core handler function that implements the sap_help_get tool logic: extracts loio from result_id, fetches metadata and page content from SAP Help private APIs, converts HTML to markdown text, adds metadata, and truncates if necessary.
    export async function getSapHelpContent(resultId: string): Promise<string> {
      try {
        // Extract loio from the result ID
        const loio = resultId.replace('sap-help-', '');
        if (!loio || loio === resultId) {
          throw new Error("Invalid SAP Help result ID. Use an ID from sap_help_search results.");
        }
    
        // First try to get from cache
        const cache = global.sapHelpSearchCache || new Map();
        let hit = cache.get(loio);
    
        if (!hit) {
          // If not in cache, search again to get the full hit data
          const searchParams = {
            transtype: "standard,html,pdf,others", 
            state: "PRODUCTION,TEST,DRAFT",
            product: "",
            version: "",
            q: loio, // Search by loio to find the specific document
            to: "19",
            area: "content",
            advancedSearch: "0",
            excludeNotSearchable: "1",
            language: "en-US",
          };
    
          const searchUrl = `${BASE}/http.svc/elasticsearch?${toQuery(searchParams)}`;
          const searchResponse = await fetch(searchUrl, {
            headers: {
              Accept: "application/json",
              "User-Agent": "mcp-sap-docs/help-get",
              Referer: BASE,
            },
          });
    
          if (!searchResponse.ok) {
            throw new Error(`Failed to find document: ${searchResponse.status} ${searchResponse.statusText}`);
          }
    
          const searchData: SapHelpSearchResponse = await searchResponse.json();
          const results = searchData?.data?.results || [];
          hit = results.find(r => r.loio === loio);
    
          if (!hit) {
            throw new Error(`Document with loio ${loio} not found`);
          }
        }
    
        // Prepare metadata request parameters
        const topic_url = `${hit.loio}.html`;
        let product_url = hit.productId;
        let deliverable_url;
    
        try {
          const { productUrlSeg, deliverableLoio } = parseDocsPathParts(hit.url);
          deliverable_url = deliverableLoio;
          if (!product_url) product_url = productUrlSeg;
        } catch (e) {
          if (!product_url) {
            throw new Error("Could not determine product_url from hit; missing productId and unparsable url");
          }
        }
    
        const language = hit.language || "en-US";
    
        // Get deliverable metadata
        const metadataParams = {
          product_url,
          topic_url,
          version: "LATEST",
          loadlandingpageontopicnotfound: "true",
          deliverable_url,
          language,
          deliverableInfo: "1",
          toc: "1",
        };
    
        const metadataUrl = `${BASE}/http.svc/deliverableMetadata?${toQuery(metadataParams)}`;
        const metadataResponse = await fetch(metadataUrl, {
          headers: {
            Accept: "application/json",
            "User-Agent": "mcp-sap-docs/help-metadata",
            Referer: BASE,
          },
        });
    
        if (!metadataResponse.ok) {
          throw new Error(`Metadata request failed: ${metadataResponse.status} ${metadataResponse.statusText}`);
        }
    
        const metadataData: SapHelpMetadataResponse = await metadataResponse.json();
        const deliverable_id = metadataData?.data?.deliverable?.id;
        const buildNo = metadataData?.data?.deliverable?.buildNo;
        const file_path = metadataData?.data?.filePath || topic_url;
    
        if (!deliverable_id || !buildNo || !file_path) {
          throw new Error("Missing required metadata: deliverable_id, buildNo, or file_path");
        }
    
        // Get page content
        const pageParams = {
          deliverableInfo: "1",
          deliverable_id,
          buildNo,
          file_path,
        };
    
        const pageUrl = `${BASE}/http.svc/pagecontent?${toQuery(pageParams)}`;
        const pageResponse = await fetch(pageUrl, {
          headers: {
            Accept: "application/json",
            "User-Agent": "mcp-sap-docs/help-content",
            Referer: BASE,
          },
        });
    
        if (!pageResponse.ok) {
          throw new Error(`Page content request failed: ${pageResponse.status} ${pageResponse.statusText}`);
        }
    
        const pageData: SapHelpPageContentResponse = await pageResponse.json();
        const title = pageData?.data?.currentPage?.t || pageData?.data?.deliverable?.title || hit.title;
        const bodyHtml = pageData?.data?.body || "";
    
        if (!bodyHtml) {
          return `# ${title}\n\nNo content available for this page.`;
        }
    
        // Convert HTML to readable text while preserving structure
        const cleanText = bodyHtml
          .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '') // Remove scripts
          .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '') // Remove styles
          .replace(/<h([1-6])[^>]*>/gi, (_, level) => '\n' + '#'.repeat(parseInt(level)) + ' ') // Convert headings
          .replace(/<\/h[1-6]>/gi, '\n') // Close headings
          .replace(/<p[^>]*>/gi, '\n') // Paragraphs
          .replace(/<\/p>/gi, '\n')
          .replace(/<br[^>]*>/gi, '\n') // Line breaks
          .replace(/<li[^>]*>/gi, '• ') // List items
          .replace(/<\/li>/gi, '\n')
          .replace(/<code[^>]*>/gi, '`') // Inline code
          .replace(/<\/code>/gi, '`')
          .replace(/<pre[^>]*>/gi, '\n```\n') // Code blocks
          .replace(/<\/pre>/gi, '\n```\n')
          .replace(/<[^>]+>/g, '') // Remove remaining HTML tags
          .replace(/\s*\n\s*\n\s*/g, '\n\n') // Clean up multiple newlines
          .replace(/^\s+|\s+$/g, '') // Trim
          .trim();
    
        // Build the full content with metadata
        const fullContent = `# ${title}
    
    **Source:** SAP Help Portal
    **URL:** ${ensureAbsoluteUrl(hit.url)}
    **Product:** ${hit.product || hit.productId || "Unknown"}
    **Version:** ${hit.version || hit.versionId || "Latest"}
    **Language:** ${hit.language || "en-US"}
    ${hit.snippet ? `**Summary:** ${hit.snippet}` : ''}
    
    ---
    
    ${cleanText}
    
    ---
    
    *This content is from the SAP Help Portal and represents official SAP documentation.*`;
    
        // Apply intelligent truncation if content is too large
        const truncationResult = truncateContent(fullContent);
        
        return truncationResult.content;
    
      } catch (error: any) {
        throw new Error(`Failed to get SAP Help content: ${error.message}`);
      }
    }
  • Dispatch logic within the MCP CallToolRequestSchema handler that invokes getSapHelpContent when the tool name is 'sap_help_get', handles logging, error wrapping, and formats the response using createDocumentResponse.
    if (name === "sap_help_get") {
      const { result_id } = args as { result_id: string };
      
      // Enhanced logging with timing
      const timing = logger.logToolStart(name, result_id, clientMetadata);
      
      try {
        const content = await getSapHelpContent(result_id);
        
        // Transform SAP Help content to structured format
        const document: DocumentResult = {
          id: result_id,
          title: `SAP Help Document (${result_id})`,
          text: content,
          url: `https://help.sap.com/#${result_id}`,
          metadata: {
            source: 'sap-help',
            resultId: result_id,
            contentLength: content.length
          }
        };
        
        logger.logToolSuccess(name, timing.requestId, timing.startTime, 1, { 
          contentLength: content.length,
          resultId: result_id
        });
        
        return createDocumentResponse(document);
      } catch (error) {
        logger.logToolError(name, timing.requestId, timing.startTime, error);
        return createErrorResponse(
          `Error retrieving SAP Help content. Please try again later.`,
          timing.requestId
        );
      }
    }
  • Tool schema registration in ListToolsRequestSchema response, defining the name, description, and input schema requiring 'result_id' parameter.
                name: "sap_help_get", 
                description: `GET SAP HELP PAGE: sap_help_get(result_id="sap-help-12345abc")
    
    FUNCTION NAME: sap_help_get (or mcp_sap-docs-remote_sap_help_get)
    
    RETRIEVES: Complete SAP Help Portal page content
    REQUIRES: Exact result_id from sap_help_search
    
    USAGE PATTERN:
    1. Get ID from sap_help_search results  
    2. Use exact ID (don't modify the format)
    3. Receive full page content + metadata`,
                inputSchema: {
                  type: "object",
                  properties: {
                    result_id: {
                      type: "string",
                      description: "Exact ID from sap_help_search results. Copy the ID exactly as returned.",
                      examples: [
                        "sap-help-12345abc",
                        "sap-help-98765def"
                      ]
                    }
                  },
                  required: ["result_id"]
                }
              },

Tool Definition Quality

Score is being calculated. Check back soon.

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/marianfoo/mcp-sap-docs'

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