Skip to main content
Glama

getWatchtowerLinks

Retrieve current Watchtower study articles with download links. Automatically fetches the correct publication issue for ongoing study materials from JW.org.

Instructions

STEP 1: Get JW.org Watchtower study articles. When a user asks for current/this week's Watchtower content, use this tool FIRST without any parameters - it automatically gets the correct issue for current study articles (Watchtower publications are 2 months ahead, so May 2025 studies come from March 2025 issue). Returns article titles like "Imitate the Faithful Angels (July 14-20)" with their RTF download URLs. Just use defaults for current articles.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pubNoPublication code: "w" for Watchtower (Study edition)w
langwrittenNoLanguage code: "E" for English, "S" for Spanish, etc.E
issueNoIssue in YYYYMM00 format. Leave empty for current study articles (server automatically calculates correct issue - Watchtower studies are 2 months ahead of publication)
fileformatNoFile format: "RTF" for Rich Text FormatRTF

Implementation Reference

  • Core handler function implementing the getWatchtowerLinks tool logic. Fetches publication data from JW.org API, processes files to extract article links, skipping the ZIP file.
    export async function getWatchtowerLinks(pub = 'w', langwritten = 'E', issue = null, fileformat = 'RTF') {
      try {
        // Use current Watchtower issue (2 months behind) if none provided
        const finalIssue = issue || getCurrentWatchtowerIssue();
        const { files, pubName, formattedDate, language } = await fetchPublicationData(pub, langwritten, finalIssue, fileformat);
        
        // Skip the first item (ZIP file) and return the individual articles
        const articles = files.slice(1).map((file, index) => ({
          title: file.title,
          url: file.file.url,
          filesize: file.filesize,
          track: file.track,
          modifiedDatetime: file.file.modifiedDatetime,
          checksum: file.file.checksum
        }));
    
        return {
          pubName,
          formattedDate,
          issue: finalIssue,
          language,
          articles
        };
    
      } catch (error) {
        throw new Error(`Failed to fetch Watchtower links: ${error.message}`);
      }
    }
  • Registration of Watchtower tools for MCP server, including schema and description for getWatchtowerLinks.
    export const watchtowerTools = [
      {
        name: 'getWatchtowerLinks',
        description: 'STEP 1: Get JW.org Watchtower study articles. When a user asks for current/this week\'s Watchtower content, use this tool FIRST without any parameters - it automatically gets the correct issue for current study articles (Watchtower publications are 2 months ahead, so May 2025 studies come from March 2025 issue). Returns article titles like "Imitate the Faithful Angels (July 14-20)" with their RTF download URLs. Just use defaults for current articles.',
        inputSchema: {
          type: 'object',
          properties: {
            pub: {
              type: 'string',
              description: 'Publication code: "w" for Watchtower (Study edition)',
              default: 'w'
            },
            langwritten: {
              type: 'string', 
              description: 'Language code: "E" for English, "S" for Spanish, etc.',
              default: 'E'
            },
            issue: {
              type: 'string',
              description: 'Issue in YYYYMM00 format. Leave empty for current study articles (server automatically calculates correct issue - Watchtower studies are 2 months ahead of publication)'
            },
            fileformat: {
              type: 'string',
              description: 'File format: "RTF" for Rich Text Format',
              default: 'RTF'
            }
          },
          required: []
        }
      },
      {
        name: 'getWatchtowerContent',
        description: 'STEP 2: Get the actual Watchtower article content after user chooses an article. Use this tool AFTER getWatchtowerLinks when user specifies which article they want (e.g., "Imitate the Faithful Angels" or "Look to Jehovah for Comfort"). Takes the RTF URL from Step 1 results, downloads the RTF file, parses it to clean plain text, and returns the formatted article content with proper structure and line breaks.',
        inputSchema: {
          type: 'object',
          properties: {
            url: {
              type: 'string',
              description: 'The RTF file URL from getWatchtowerLinks results (e.g., "https://cfp2.jw-cdn.org/a/...")'
            }
          },
          required: ['url']
        }
      }
    ];
  • MCP-specific handler dispatch block within handleWatchtowerTools that calls the core getWatchtowerLinks function based on tool name.
    // Handle getWatchtowerLinks tool
    if (request.params.name === 'getWatchtowerLinks') {
      try {
        const { pub, langwritten, issue, fileformat } = request.params.arguments || {};
        const result = await getWatchtowerLinks(pub, langwritten, issue, fileformat);
        
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(result, null, 2),
            },
          ],
        };
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error.message}`,
            },
          ],
          isError: true,
        };
      }
    }
  • Helper function to compute the current Watchtower study issue (2 months behind publication date). Used by getWatchtowerLinks when no issue provided.
    export function getCurrentWatchtowerIssue() {
      const now = new Date();
      // Subtract 2 months to get the correct Watchtower issue
      const targetDate = new Date(now.getFullYear(), now.getMonth() - 2, 1);
      const year = targetDate.getFullYear();
      const month = String(targetDate.getMonth() + 1).padStart(2, '0');
      return `${year}${month}00`;
    }
  • Helper function that calls JW.org pub-media API to fetch publication files data, used by getWatchtowerLinks to get the links.
    export async function fetchPublicationData(pub, langwritten = 'E', issue = null, fileformat = 'RTF') {
      try {
        // Use current issue if none provided
        const finalIssue = issue || getCurrentIssue();
        
        const apiUrl = `https://b.jw-cdn.org/apis/pub-media/GETPUBMEDIALINKS?pub=${pub}&langwritten=${langwritten}&issue=${finalIssue}&fileformat=${fileformat}&output=json`;
        
        const response = await fetch(apiUrl);
        
        if (!response.ok) {
          throw new Error(`API request failed: ${response.statusText}`);
        }
    
        const data = await response.json();
        
        // Extract files for the specified language and format
        const files = data.files?.[langwritten]?.[fileformat];
        
        if (!files || files.length === 0) {
          throw new Error(`No ${fileformat} files found for ${pub} in ${langwritten}`);
        }
    
        return {
          data,
          files,
          pubName: data.pubName,
          formattedDate: data.formattedDate,
          issue: data.issue,
          language: data.languages[langwritten].name
        };
    
      } catch (error) {
        throw new Error(`Failed to fetch publication data: ${error.message}`);
      }
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: automatic issue calculation ('server automatically calculates correct issue'), timing logic ('Watchtower publications are 2 months ahead'), return format ('article titles... with their RTF download URLs'), and default parameter usage. It doesn't mention error handling or rate limits, but covers most essential operational aspects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose and usage instructions. Every sentence serves a clear function: establishing purpose, providing usage guidelines, explaining timing logic, describing returns, and reinforcing default usage. It could be slightly more concise by combining some timing explanations, but overall it's well-structured with minimal waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (4 parameters, no annotations, no output schema), the description provides good contextual completeness. It covers purpose, usage guidelines, behavioral aspects like automatic calculation and timing logic, and return format. The main gap is the lack of output schema, but the description compensates by describing what's returned. For a read-only tool with good parameter documentation, this is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters thoroughly. The description adds minimal parameter semantics beyond the schema - it mentions using defaults for current articles and explains the timing logic for the issue parameter, but doesn't provide additional syntax or format details. This meets the baseline expectation when schema coverage is high.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get JW.org Watchtower study articles' with specific details about the resource (current/this week's Watchtower content) and distinguishes it from potential alternatives by specifying it should be used 'FIRST without any parameters' for current articles, differentiating from sibling tools like getWatchtowerContent which might handle different use cases.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidelines: 'When a user asks for current/this week's Watchtower content, use this tool FIRST without any parameters' and explains the timing logic (2-month ahead publication). It also implies when not to use it (e.g., for non-current articles or other publications), though it doesn't name specific alternatives beyond the context of sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/advenimus/jw-mcp'

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