Skip to main content
Glama
Bjern

jw-org-mcp

by Bjern

JW.Org MCP Tool

Tests Python 3.13+ Ruff mypy security: bandit License: GPL v3

A Model Context Protocol (MCP) server that provides controlled, verifiable access to content from jw.org for AI applications and LLM integrations.

Overview

The JW.Org MCP Tool ensures that scriptural and doctrinal information comes exclusively from official jw.org sources, eliminating the risk of hallucinations or external contamination when handling religious queries. This tool acts as a trusted intermediary between AI applications and jw.org content.

Related MCP server: Bible MCP

Features

  • Trusted Source Enforcement: Fetches data strictly from jw.org domains

  • Comprehensive Search: Search across articles, videos, publications, audio, and scriptures

  • Intelligent Query Parsing: Extracts meaningful search terms from natural language queries

  • Full Article Retrieval: Get complete article content with scripture references

  • Scripture Lookup: Direct scripture reference search

  • Performance Optimized: 15-minute caching, Brotli compression, async operations

  • Structured Output: Machine-readable responses with verification metadata

Installation

Requirements

  • Python 3.13+

  • uv for package management

Install with uv

# Clone the repository
git clone https://github.com/Bjern/jw-org-mcp.git
cd jw-org-mcp

# Install dependencies
uv sync

# Install with development dependencies
uv sync --group dev

Usage

Running the MCP Server

uv run jw-org-mcp

The server runs in stdio mode and communicates via the Model Context Protocol.

Adding to Claude Desktop

To use this MCP server with Claude Desktop, add it to your Claude configuration file:

Location:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Configuration:

{
  "mcpServers": {
    "jw-org": {
      "command": "uv",
      "args": [
        "--directory",
        "E:\\Projects\\Python\\jw-org-mcp",
        "run",
        "jw-org-mcp"
      ]
    }
  }
}

Note: Replace E:\\Projects\\Python\\jw-org-mcp with the actual path to your project directory. On Windows, use double backslashes (\\) in the path.

WINDOWS -> FEB 2026 -> If you are using this as a custom connector MCP tool, then, you might find that the Claude Desktop app on Windows is not working properly. The app does not launch, etc...

This is because, there is a bug that the new app (Since Feb 2026) has changed it's default folder to the MSIX virtualized path:

C:\Users{username}\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude_desktop_config.json

Or paste %localappdata%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude in the windows Run dialog.

After saving the configuration:

  1. Restart Claude Desktop

  2. The JW.Org MCP tools will be available in your conversations

  3. Look for tools like search_content, get_article, and get_scripture

Configuration

Configuration is done via environment variables with the prefix JWORG_MCP_:

# Cache settings
export JWORG_MCP_CACHE_TTL_SECONDS=900  # 15 minutes (default)
export JWORG_MCP_ENABLE_CACHE=true

# Request settings
export JWORG_MCP_REQUEST_TIMEOUT=30
export JWORG_MCP_MAX_RETRIES=3

# Search settings
export JWORG_MCP_DEFAULT_LANGUAGE=E  # English
export JWORG_MCP_DEFAULT_SEARCH_LIMIT=10

# Logging
export JWORG_MCP_LOG_LEVEL=INFO

MCP Tools

search_content

Search JW.Org content across multiple types.

Parameters:

  • query (required): Search query - can be natural language

  • filter (optional): Content type - all, publications, videos, audio, bible, indexes (default: all)

  • language (optional): Language code - E for English, S for Spanish, etc. (default: E)

  • limit (optional): Maximum results (default: 10)

Example:

{
  "query": "What does the Bible say about love?",
  "filter": "all",
  "limit": 5
}

The query parser automatically extracts "love" as the search term.

get_article

Retrieve full article content from a jw.org URL. Supports both direct article URLs and publication finder URLs.

When given a publication-level URL (e.g., a magazine issue), the tool returns a table of contents listing individual articles with their direct URLs, which can then be fetched individually.

Parameters:

  • url (required): Article URL from wol.jw.org or a publication finder URL

Example:

{
  "url": "https://wol.jw.org/en/wol/d/r1/lp-e/1985720"
}

get_scripture

Get scripture text by reference.

Parameters:

  • reference (required): Scripture reference (e.g., "John 3:16", "1 Thessalonians 5:3")

  • translation (optional): Bible translation code (default: "nwtsty")

Example:

{
  "reference": "John 3:16"
}

get_cache_stats

Get cache statistics including hit rate and entry count.

Parameters: None

Development

Setup Development Environment

# Install with development dependencies
uv sync --group dev

# Install pre-commit hooks (optional)
uv run pre-commit install

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=jw_org_mcp --cov-report=html

# Run specific test file
uv run pytest tests/test_parser.py

Code Quality

# Run linter
uv run ruff check .

# Format code
uv run ruff format .

# Type checking
uv run mypy src/

# Security scan
uv run bandit -r src/ -c pyproject.toml

Project Structure

jw-org-mcp/
├── .github/
│   └── workflows/
│       └── tests.yml         # CI pipeline (lint, type check, security, tests)
├── src/
│   └── jw_org_mcp/
│       ├── __init__.py       # Entry point
│       ├── auth.py           # Authentication & CDN discovery
│       ├── cache.py          # Caching layer
│       ├── client.py         # JW.Org API client
│       ├── config.py         # Configuration management
│       ├── exceptions.py     # Custom exceptions
│       ├── models.py         # Data models
│       ├── parser.py         # Content parsers
│       └── server.py         # MCP server implementation
├── tests/                    # Test suite
├── docs/                     # Documentation
├── pyproject.toml            # Project configuration
└── README.md

Architecture

Authentication Flow

  1. Discover CDN URL from jw.org homepage

  2. Request JWT token from CDN endpoint

  3. Use token for authenticated API requests

  4. Automatically refresh token before expiration

Search Flow

  1. Parse user query to extract search terms

  2. Check cache for existing results

  3. Make authenticated API request if cache miss

  4. Parse and structure response

  5. Cache results for 15 minutes

  6. Return structured data

Content Retrieval

  1. Fetch HTML content from wol.jw.org

  2. If the page is a publication index (table of contents), extract article links and return them

  3. Otherwise, parse article structure (title, paragraphs, references)

  4. Extract clean text without HTML artifacts

  5. Cache parsed content

  6. Return structured article data

API Response Format

All responses include metadata for verification:

{
  "data": {
    // Response-specific data
  },
  "metadata": {
    "source_domain": "jw.org",
    "source_url": "https://...",
    "timestamp": "2024-01-01T00:00:00Z",
    "query_params": {},
    "cache_hit": false
  }
}

Performance

  • Response Time: < 2 seconds for search queries (cached: < 100ms)

  • Cache TTL: 15 minutes (configurable)

  • Compression: Brotli for all API requests

  • Concurrency: Async I/O with connection pooling

Error Handling

The tool provides graceful error handling with specific exception types:

  • AuthenticationError: JWT token issues

  • CDNDiscoveryError: CDN discovery failures

  • SearchError: Search operation failures

  • ContentRetrievalError: Content fetch failures

  • ParseError: Content parsing failures

All errors are logged and returned with descriptive messages.

Security & Privacy

  • No PII Logging: No personally identifiable information is logged

  • HTTPS Only: All external requests use HTTPS

  • Token Security: JWT tokens are managed securely in memory

  • Input Validation: All user inputs are sanitized

Contributing

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes with tests

  4. Ensure all tests pass and code is formatted

  5. Submit a pull request

License

This project is licensed under the GNU General Public License v3.0.

Support

For issues and questions:

Acknowledgments

  • Built with FastMCP

  • Uses the Model Context Protocol standard

  • Provides verified access to jw.org content

Available Tools

4 tools
get_articleA

Retrieve full article content from a JW.Org URL. Returns the article text with paragraphs and scripture references.

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesThe article URL from wol.jw.org

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden. It discloses that the operation is a retrieval and gives expected output content (paragraphs and scripture references), but it does not mention potential errors, rate limits, or any side effects. It is adequate but lacks deeper behavioral detail.

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

Conciseness5/5

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

The description is a single sentence with no filler, front-loading the action and stating the key output. Every word earns its place, making it concise and well structured.

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?

For a simple tool with one parameter and no output schema, the description covers the essential context: what it retrieves and what it returns. It could mention edge cases like invalid URLs or non-article links, but for the given complexity it is nearly complete.

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% for the single 'url' parameter, which is already clearly described as 'The article URL from wol.jw.org'. The description adds no additional parameter semantics beyond what the schema provides, so the baseline score of 3 is appropriate.

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 uses a specific verb ('Retrieve') and clearly identifies the resource ('full article content from a JW.Org URL'). It also explicitly states what is returned (text with paragraphs and scripture references), which differentiates it from sibling tools like search_content and get_scripture.

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

Usage Guidelines3/5

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

The description implies when to use the tool (when you have a specific article URL) and what it returns, but it does not explicitly state when NOT to use it or mention alternative tools. There is no direct comparison to siblings, so guidance is only implicit.

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

get_cache_statsA

Get cache statistics including hit rate and entry count.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

No annotations are present, so the description carries the burden of behavioral disclosure. 'Get' implies a read-only operation, but the description does not mention response format, real-time accuracy, or any side effects. It discloses the basic action but lacks deeper context.

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

Conciseness5/5

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

The description is a single, front-loaded sentence with no redundant words. Every phrase adds value, specifying exactly what statistics are included.

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

Completeness5/5

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

Given the tool's simplicity (no parameters, no output schema), the description is complete. It names the two key metrics, which is sufficient for an agent to understand what the tool returns.

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

Parameters4/5

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

The tool has zero parameters, and the schema coverage is 100% (vacuously). The description adds no parameter details, but the baseline for 0 params is 4, and no additional semantics are needed.

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 action ('Get') and resource ('cache statistics') while specifying key metrics (hit rate, entry count). It is distinct from sibling tools like search_content, get_article, and get_scripture, which are content-focused.

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

Usage Guidelines4/5

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

The description implies a clear use case (retrieving cache stats) but does not provide explicit guidance on when to use vs. alternatives. However, given the simplicity and distinct resource, the context is sufficient without exclusions.

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

get_scriptureA

Get scripture text by reference (e.g., 'John 3:16', '1 Thessalonians 5:3'). Returns the scripture text and reference.

ParametersJSON Schema
NameRequiredDescriptionDefault
referenceYesScripture reference (e.g., 'John 3:16')
translationNoBible translation codenwtsty

TDQS

A3.8/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states that the tool 'returns the scripture text and reference,' but does not mention error behavior (e.g., invalid reference), handling of the optional translation parameter, or any other side effects. This is minimal transparency.

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

Conciseness5/5

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

The description is two sentences, immediately states the main action, and includes useful examples without any filler. Every word contributes to understanding the tool's purpose and behavior.

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?

For a simple tool with two parameters and no output schema, the description covers the essential purpose, input examples, and return value. It is not missing critical information, though it could optionally mention what happens for invalid references or how the translation parameter affects output. This is adequate for the tool's simplicity.

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

Parameters4/5

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

The input schema already provides descriptions for both parameters (100% coverage), and the description adds valuable context by giving examples of the reference format. It also clarifies that the return value includes both text and reference, which helps understand the translation parameter's role. This exceeds the baseline of 3.

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 function with a specific verb ('Get') and resource ('scripture text'), and provides concrete examples of valid references. This clearly distinguishes it from sibling tools like search_content, which would be used for searching rather than direct reference lookup.

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

Usage Guidelines3/5

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

The description implies usage (when you have a specific scripture reference), but does not explicitly mention when to use this tool versus alternatives, or any exclusions. It would be improved by noting that search_content is for searching/finding references, while this tool is for retrieving text by a known reference.

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

search_contentA

Search JW.Org content including articles, videos, publications, audio, and scriptures. Extracts meaningful search terms from natural language queries.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of results to return
queryYesThe search query. Can be natural language like 'What does the Bible say about love?' The tool will extract 'love' as the search term.
filterNoContent type filterall
languageNoLanguage code (E=English, S=Spanish, etc)E

TDQS

A3.5/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden. It discloses one behavioral trait—natural language term extraction—but omits critical details like result format, ordering, pagination, or authentication. The verb 'search' implies read-only, but that is not explicitly stated, and there is no mention of what the response will look like.

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

Conciseness5/5

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

The description is two efficient sentences with no redundancy. The first sentence clearly states the tool's purpose and scope, while the second adds a distinctive behavioral detail. Every word earns its place.

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

Completeness3/5

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

Given the absence of annotations and output schema, the description provides adequate purpose and one behavioral note, but it fails to describe the return value or any usage constraints. An agent knows what to search for but not what to expect back, which is a meaningful gap for a search tool.

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?

The input schema has 100% description coverage, including a detailed example for 'query'. The tool description adds no additional parameter meaning beyond the schema. The natural-language extraction behavior is already explained in the query parameter's own description, so baseline 3 applies.

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 uses a specific verb 'Search' and identifies the resource as 'JW.Org content' with explicit content types (articles, videos, publications, audio, scriptures). This clearly distinguishes it from sibling get_article and get_scripture, which target specific items rather than broad search.

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

Usage Guidelines3/5

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

The description implies usage for natural-language searches across a broad content set, but it does not explicitly say when to prefer this over get_article or get_scripture, nor provide exclusions. The phrase 'Extracts meaningful search terms from natural language queries' gives some context for its query style, but no direct alternatives are named.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedget_article
    • First observedget_cache_stats
    • First observedget_scripture
    • First observedsearch_content

TDQS

A4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a distinct purpose: searching content, retrieving an article, retrieving a scripture, and inspecting cache stats. There is no overlap or ambiguity in their intended usage.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with snake_case: search_content, get_article, get_scripture, get_cache_stats. This is uniform and predictable.

Tool Count5/5

With 4 tools, the server is well-scoped for its apparent purpose of accessing JW.Org content. Each tool contributes a distinct function without redundancy.

Completeness4/5

The server covers search, article retrieval, and scripture retrieval, which are central to its domain. However, it lacks dedicated retrieval for other content types like videos or publications, though these can be discovered via search.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that provides powerful search capabilities for Jewish texts and literature. This server enables Large Language Models to search and reference Jewish texts through a standardized interface.
    23
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Free, no-key MCP server for reading scripture from 35+ public-domain translations in 8 languages. Lets users fetch verses, chapters, and passages via natural language from any MCP client.
    7
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    A remote MCP server for traceable research across JW.org and the Watchtower Online Library, providing tools for searching, retrieving articles, footnotes, cross-references, and daily texts with optional AI-powered synthesis.
    20
    1
    -