jw-org-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@jw-org-mcpsearch for articles about hope"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
JW.Org MCP Tool
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 devUsage
Running the MCP Server
uv run jw-org-mcpThe 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.jsonWindows:
%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:
Restart Claude Desktop
The JW.Org MCP tools will be available in your conversations
Look for tools like
search_content,get_article, andget_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=INFOMCP Tools
search_content
Search JW.Org content across multiple types.
Parameters:
query(required): Search query - can be natural languagefilter(optional): Content type -all,publications,videos,audio,bible,indexes(default:all)language(optional): Language code -Efor English,Sfor 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 installRunning 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.pyCode 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.tomlProject 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.mdArchitecture
Authentication Flow
Discover CDN URL from jw.org homepage
Request JWT token from CDN endpoint
Use token for authenticated API requests
Automatically refresh token before expiration
Search Flow
Parse user query to extract search terms
Check cache for existing results
Make authenticated API request if cache miss
Parse and structure response
Cache results for 15 minutes
Return structured data
Content Retrieval
Fetch HTML content from wol.jw.org
If the page is a publication index (table of contents), extract article links and return them
Otherwise, parse article structure (title, paragraphs, references)
Extract clean text without HTML artifacts
Cache parsed content
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 issuesCDNDiscoveryError: CDN discovery failuresSearchError: Search operation failuresContentRetrievalError: Content fetch failuresParseError: 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
Fork the repository
Create a feature branch
Make your changes with tests
Ensure all tests pass and code is formatted
Submit a pull request
License
This project is licensed under the GNU General Public License v3.0.
Support
For issues and questions:
GitHub Issues: https://github.com/Bjern/jw-org-mcp/issues
Documentation: See
docs/folder
Acknowledgments
Built with FastMCP
Uses the Model Context Protocol standard
Provides verified access to jw.org content
Available Tools
4 toolsget_articleA
Retrieve full article content from a JW.Org URL. Returns the article text with paragraphs and scripture references.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The article URL from wol.jw.org |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| reference | Yes | Scripture reference (e.g., 'John 3:16') | |
| translation | No | Bible translation code | nwtsty |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return | |
| query | Yes | The search query. Can be natural language like 'What does the Bible say about love?' The tool will extract 'love' as the search term. | |
| filter | No | Content type filter | all |
| language | No | Language code (E=English, S=Spanish, etc) | E |
TDQS
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.
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.
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.
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.
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.
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.
4 tool updates
v0.1.0- First observed
get_article - First observed
get_cache_stats - First observed
get_scripture - First observed
search_content
TDQS
Scored across 4 tools
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.
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.
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.
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
Related MCP Connectors
Free, no-key Bible MCP server — 86 translations in 32 languages, from any MCP client.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
An MCP server that provides congressional transcripts
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn 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.23MIT
- AlicenseAqualityAmaintenanceFree, 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.7MIT
- FlicenseAqualityDmaintenanceProvides controlled, verifiable access to jw.org content for AI applications, enabling search, article retrieval, and scripture lookup while preventing hallucinations.4-
- FlicenseAqualityCmaintenanceA 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.201-