Project Vision
Our vision starts with a simple problem: reading dense, 400-year-old theological texts is difficult, and it can be a very solitary experience. The CCEL website is an amazing resource, but it's currently a static collection of texts. Our vision is simple: "no one should have to feel lost or alone when reading a great book".
We want to transform CCEL into a living conversation. Our project does this by integrating two distinct AI-powered systems. This creates a twofold technical challenge:
- Reader's Tools — "Explain" and "Modernize" contextual buttons that help readers understand difficult passages on-the-fly
- Smart Library Assistant (Chatbot) — "Ask CCEL a question" conversational interface powered by an external Python service
By strictly integrating these features into the native CCEL environment, we aim to make profound theological study accessible to everyone, regardless of their academic background, creating a true "co-pilot" for digital reading.
Meet the Team
Department of Computer Science, Calvin University
Sungmin Choi
Chatbot/Readers Tools + Proxy & API Integration Lead
Lead developer for the "Ask CCEL" Chatbot/Readers Tools + Proxy and external SLA API integration. Also working collaboratively on security and rate limiting implementation.
Youngha Kweon
UI/UX & Frontend Lead
Lead on UI/UX design and frontend implementation. Responsible for responsive design, streaming display, markdown rendering, and creating the complete 1500+ line reader-tools-integration.js application.
Advisor: Professor Harry Plantinga, Department of Computer Science
Executive Summary
We successfully integrated two AI-powered systems into the Christian Classics Ethereal Library (CCEL), transforming it from a static text repository into an interactive learning environment. Our implementation includes a secure backend proxy for the "Explain," "Modernize," and "Background Info" Reader's Tools, real-time streaming responses, per-user rate limiting, and a public status monitoring dashboard—all without modifying the existing database.
1500+ Lines
Frontend JS Code
400+ Lines
Backend PHP Code
Zero Database
Schema Changes
Table of Contents
Vision Statement Normative and Ethical Considerations Background What We Did: Accomplishments to Date Key Technical Decisions Implementation Details Results Testing & Validation Next Steps & Future WorkVision Statement
Our vision starts with a simple problem: reading dense, 400-year-old theological texts is difficult, and it can be a very solitary experience. The CCEL website is an amazing resource, but it's currently a static collection of texts. Our vision is simple:
"No one should have to feel lost or alone when reading a great book."
We want to transform CCEL into a living conversation. Our project does this by integrating two distinct AI-powered systems. This creates a twofold technical challenge:
- Reader's Tools — "Explain," "Modernize," and "Background" contextual buttons that help readers understand difficult passages on-the-fly. We built a secure backend proxy to Claude AI, handling streaming responses in real-time.
- Smart Library Assistant — The "Ask CCEL a question" chatbot powered by an external Python service. We architected an API bridge to connect the PHP site to its Python backend, with per-user rate limiting and abuse prevention.
Normative and Ethical Considerations
Our design decisions reflect careful consideration of eight key normative values that guide technology use in a faith-based academic environment:
1. Cultural Appropriateness
Ignoring this norm risks disrupting the quiet, studious atmosphere of CCEL. A tool that's too flashy or an AI that offers shallow interpretations would feel disrespectful to users. To align with the culture, we designed the AI to act as an inquisitive guide, not an expert. It prompts users with thoughtful questions that encourage deeper reflection, enhancing the existing contemplative environment.
2. Transparency
Without transparency, users might uncritically accept AI-generated answers, which can sometimes be inaccurate or "hallucinated." To address this:
- All AI-generated content is clearly labeled with distinct visual styling
- The tool provides citations and links back to source texts
- Chat data processing is visually indicated as third-party (SLA service)
- Users know exactly when they're interacting with AI vs. reading static text
3. Social Responsibility
The AI facilitator is programmed to highlight common ground and ask questions that encourage productive discussion, fostering positive community interaction.
4. Stewardship
Frequent, complex calls to an LLM API are expensive and resource-intensive. We balanced advanced features with costs through:
- Per-user rate limiting (50 chatbot requests/hour, 200 reader tools/hour)
- Lightweight health checks (~100-150ms) instead of full API calls for monitoring
- Client-side streaming to add zero weight to the database
- Efficient token usage through careful prompt engineering
5. Aesthetics
The new tools visually match CCEL's existing design through:
- Consistent purple gradient theme (#667eea to #764ba2)
- Semi-Apple-inspired interface styling
- Smooth animations and responsive design
- Distinct visual separation from static content
6. Justice
We mitigate LLM bias through rigorous testing, careful prompt engineering, encouraging the AI to present multiple scholarly perspectives, and citation generation to show sources and context.
7. Caring
The AI is designed to be encouraging and supportive: affirming user contributions before offering critique, providing helpful context without being pedantic, and creating a safe space for learning and exploration.
8. Trust
We built the System Status Monitor so admins have reliable, real-time visibility into infrastructure health. Trustworthy technology means being honest about capabilities and failures—not hiding problems. Response time tracking and color-coded status badges ensure the team can respond immediately if something breaks.
Background
Previous Work
Previous teams created the Smart Library Assistant, an LLM-integrated chatbot using Claude AI that helps researchers, students, and theologians find precise answers amid vast volumes of Christian literature. Key features included domain-specific RAG search using the CCEL library and citation generation.
Prior Work in the Field
While general AI reading tools like ChatPDF exist, they lack domain-specific context for theological study. Our project focuses on deep integration within a library ecosystem, requiring higher standards of transparency, citation, and cost management than standalone consumer apps.
What We Did: Accomplishments to Date
Phase 1: Frontend Integration & Discovery
- Implemented floating chatbot icon ("magic wand") for AI entry point
- Created a contextual menu that appears on text selection
- Established a shared development environment and Team Contract
- Reverse-engineered existing SLA API endpoints through network inspection
Phase 2: Backend Architecture & Security
We made a strategic decision: instead of routing all Reader's Tools through the existing Python API, we built a secure backend proxy layer in PHP that:
Handles Reader's Tools Natively
- Direct integration with Claude API for Explain, Modernize, and Background Info
- Real-time streaming using Server-Sent Events (SSE) converted to NDJSON
- Keeps API keys on the server (never exposed to clients)
- Validates all inputs and detects prompt injection attempts
- Implements per-user rate limiting to prevent abuse
Proxies the Smart Library Assistant
- Routes chatbot messages through /api/chatbot/proxy endpoint
- Maintains session management and citation tracking
- Applies the same security and rate-limiting standards
Added Abuse Prevention
- Per-user rate limiting: 50 requests/hour (chatbot), 200/hour (reader tools)
- Input validation to block malicious prompts
- Real-time monitoring for suspicious patterns
- HTTP 429 responses with Retry-After headers
Phase 3: Frontend Implementation
Reader's Tools Sidebar
- Three text analysis tools: Explain, Modernize, Background Info
- Real-time streaming display—users see responses word-by-word
- Markdown formatting for bold, italic, headers, and code blocks
- Distinct visual styling to clarify AI vs. static content
Smart Library Assistant Chatbot
- Two-tab interface (Chat / Tools)
- Session persistence using localStorage
- Real-time streaming responses with citations
- Source attribution and clickable links
- Typing indicators and auto-scrolling
System Status Monitor
- Public access at /user/{uid}/status
- Real-time health checks every 30 seconds
- Sub-150ms response times (verified with curl)
- Color-coded status badges (operational/warning/down)
- No impact on database or infrastructure
Phase 4: Design & Polish
- Gradient buttons with hover animations
- Responsive sidebar (fixed 500px width)
- Professional UI matching CCEL branding
- Error boundaries and loading states
- HTML escaping for security (XSS prevention)
Key Technical Decisions
1. Server-Side Proxying
Why: Keeping API keys on the server protects them from client exposure. It also centralizes security (rate limiting, validation) in one place, making the system easier to audit and maintain.
2. Streaming Responses
Why: Users see immediate feedback instead of waiting for full responses. This significantly improves perceived performance and user engagement, making AI assistance feel more responsive and natural.
3. Zero Database Changes
Why: All data flows through external APIs (Claude, SLA). No new tables = simpler integration, easier rollback, lower risk for production deployment. This minimizes the blast radius of any issues.
4. Lightweight Health Checks
Why: Instead of calling Claude on each status check, we just verify the configuration. This keeps monitoring overhead minimal (~100-150ms per check), reducing unnecessary API calls and costs.
5. NDJSON Over JSON
Why: Newline-delimited JSON is easier to parse line-by-line during streaming, preventing issues with partial data chunks and improving streaming reliability.
Implementation Details
Backend Files
ReaderToolsProxyController.php- Main proxy with streaming, rate limiting, health checksPublicStatusController.php- Status page displayRateLimitChatbot.php- Rate limiting middlewareAbuseMonitoringController.php- Admin monitoring dashboard
Frontend Files
reader-tools-integration.js(1500+ lines) - Complete UI/UX applicationUserStatus.blade.php- Status monitor viewGlobalChatbot.blade.php- Chatbot integration
API Endpoints
GET /api/reader-tools/proxy- Reader Tools (Explain, Modernize, Background)GET /api/chatbot/proxy- Smart Library AssistantGET /api/health/reader-tools- Health check (fast, no AI call)GET /api/health/chatbot- Chatbot health checkGET /user/{uid}/status- Public status monitor
Technology Stack
Results
The Ask CCEL Interface
✓ Real-Time Chat Window
The persistent "magic wand" icon expands into a chat window that overlays the text without obscuring it, maintaining the user's reading context. Features include real-time message streaming, session persistence across page refreshes, citation links to source materials, and typing indicators for better UX.
Contextual Analysis Tools
✓ Text Selection Menu
When a user selects a paragraph or text, the updated Annotation Bar appears, featuring gradient buttons (Background, Modernize, Explain) that trigger real-time AI analysis. Features include word-by-word streaming display as responses arrive, markdown formatting for complex content, distinct purple gradient styling to indicate AI content, and a modal overlay that preserves reading context.
System Status Monitor
✓ Infrastructure Dashboard
Real-time health dashboard accessible at /user/{uid}/status. Shows Reader Tools API status (health: 117ms average), Chatbot API status (health: 101ms average), auto-refresh every 30 seconds, color-coded status badges, and last update timestamp.
Live Development Environment
We have full access to development servers and confirmed working environments with:
Testing & Validation
✓ Streaming Works
Verified with curl: NDJSON format, real-time chunks, word-by-word display functioning correctly.
✓ Rate Limiting Works
Tested per-user limits with multiple requests. HTTP 429 responses correctly triggered at limits, Retry-After headers functioning as expected.
✓ Health Checks Fast
Confirmed sub-150ms response times. Reader Tools: 117ms average, Chatbot: 101ms average. Well below production thresholds.
✓ Markdown Rendering
Bold, italic, headers, lists, and code blocks all display correctly. Special characters properly escaped.
✓ Both Modes Functional
Streaming and non-streaming modes are operational. Fallback mechanisms work when streaming is unavailable.
✓ Security
API keys never exposed in client code. CSRF tokens on all forms. XSS prevention through HTML escaping. Prompt injection detection blocking malicious patterns.
✓ Database Clean
Zero modifications to existing database schema. All features implemented as stateless proxies.
Next Steps & Future Work
Immediate (Production Integration)
- Merge code into the live site under supervisor approval
- Monitor performance and user feedback
- Adjust rate limits based on real-world usage
Short-term (Next 2-3 months)
- Historical tracking for the status monitor (long-term uptime data)
- Automated alerts (email when services drop)
- User usage analytics on the status page (admin can see who's using what)
- Manual quota management (admins can grant additional requests to power users)
Long-term (Stretch Goals)
- Full admin dashboard consolidating infrastructure + usage data
- Discussion forums leveraging LLM for thought-provoking prompts
- AI-generated cross-reference maps connecting concepts across the library
- Expanded Reader's Tools (character analysis, theological position mapping, etc.)
Conclusion
This project demonstrates how thoughtful technology integration can enhance rather than disrupt a faith-based academic environment. By prioritizing transparency, stewardship, and user trust, we've created AI-powered reading assistance tools that respect CCEL's contemplative mission while making profound theological study more accessible.
The implementation is production-ready, fully tested, and designed for long-term maintainability. With zero database changes and a server-side proxy architecture, CCEL can confidently deploy these features while maintaining control over costs, security, and user experience.
We're excited to see how readers, students, and scholars will engage with these tools—and we're committed to supporting CCEL's mission of making Christian classics accessible to everyone, everywhere.
Implementation Details
Files Created & Modified
Backend (PHP)
ReaderToolsProxyController.php
Main proxy controller (~400 lines) handling all API requests, streaming, rate limiting, and security
PublicStatusController.php
Serves the public status monitor dashboard with health check integration
RateLimitChatbot.php
Middleware for rate limiting (60 lines, integrated into controller)
AbuseMonitoringController.php
Admin dashboard for tracking suspicious activity and API usage patterns
routes/web.php (updated)
5 new routes for API endpoints and public status page
Frontend (JavaScript)
public/js/reader-tools-integration.js
Complete application (1500+ lines) with sidebar UI, streaming handlers, markdown conversion, and session management
resources/views/UserStatus.blade.php (updated)
Status monitor dashboard with health check integration and back button
resources/views/GlobalChatbot.blade.php (updated)
Global chatbot entry point included on all pages
Technology Stack
Laravel 5.x
Framework base with routing, middleware, caching, and logging
PHP 8.3+
Server-side proxy logic, API integration, and security
Vanilla JavaScript
Frontend application without framework dependencies
Python Service
External SLA Query Agent and AI endpoints
Claude API
Anthropic AI for Reader Tools (explain/modernize)
Redis/Cache
Rate limiting and session storage
Rate Limiting Strategy
Reader Tools
Limit: 200 requests/hour per user
Rationale: Lower frequency, quick processing (explain/modernize)
Chatbot
Limit: 50 requests/hour per user
Rationale: Conversational nature; prevents abuse of expensive API calls
User Identification: Priority order — Authenticated user ID → Session ID → Anonymous (IP-based)
Storage: Laravel Cache system (Redis in production, file-based in development)
Response: HTTP 429 with Retry-After header when exceeded
Complete Presentation
Google SlidesPresentation Overview
Title & Overview
Introduction to the Reader's Tools project, team members, and advisor
The Problem & Vision
"No one should feel lost when reading a great book" - transforming CCEL from static to interactive
Two Systems Integrated
Reader's Tools (Explain/Modernize/Background) and Smart Library Assistant (Chatbot)
Key Accomplishments
1500+ line JavaScript frontend, secure proxy, health checks, rate limiting, and zero database changes
Design Principles
Transparency, Trust, Stewardship, Accessibility, and Security integrated throughout
Live Demonstration
Walk-through of floating chatbot icon, text selection menu, real-time responses, and status dashboard
Technical Stack
PHP/Laravel backend, vanilla JavaScript frontend, Claude API, and Server-Sent Events streaming
Next Steps & Future Work
Production deployment, automated alerts, analytics dashboard, and community features
Project Codebase
Our project integrates modern AI microservices into a legacy PHP/Laravel architecture with comprehensive security and monitoring.
Laravel/PHP
Core website, proxy controller, rate limiting, and backend logic
JavaScript ES6
1500+ line frontend application with streaming and UI
Python
External SLA service and existing AI logic
Code Highlights
Rate Limiting Implementation
// In ReaderToolsProxyController.php
public function checkRateLimit($service) {
$userId = Auth::check() ? Auth::id() :
(session()->getId() ?: request()->ip());
$limit = $service === 'chatbot' ? 50 : 200;
$key = "rate_limit:{$service}:{$userId}";
$current = Cache::get($key, 0);
if ($current >= $limit) {
return response()->json(
['error' => 'Rate limit exceeded'],
429
)->header('Retry-After', '3600');
}
Cache::put($key, $current + 1, now()->addHour());
}
Server-Sent Events Streaming
// Stream Claude response as NDJSON
private function streamClaudeResponse($stream) {
$allRawText = '';
foreach ($stream->getIterator() as $chunk) {
$lines = explode("\n", $chunk);
foreach ($lines as $line) {
$parsed = $this->parseSSEChunk($line);
if ($parsed) {
$allRawText .= $parsed['text'];
echo json_encode([
'type' => 'chunk',
'text' => $parsed['text']
]) . "\n";
}
}
}
// Emit complete event
echo json_encode([
'type' => 'complete',
'fullText' => $allRawText
]) . "\n";
}
Security: Prompt Injection Detection
// Detect suspicious patterns
private function containsSuspiciousPatterns($input) {
$patterns = [
'/system\s*prompt/i',
'/ignore.*instructions/i',
'/forget.*previous/i',
'/execute.*code/i',
'/\{.*\{.*\}/i', // Nested braces
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $input)) {
Log::warning('Suspicious pattern detected',
['input' => substr($input, 0, 100)]);
return true;
}
}
return false;
}
All source code available with full commit history and documentation