Senior Project 2025

Deployment and Implementation
of Reader's Tools

Transforming the Christian Classics Ethereal Library into a living conversation by integrating AI-powered reading assistance tools into the CCEL website.

Directed by Professor Harry Plantinga

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

SC

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.

YK

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

Vision 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 checks
  • PublicStatusController.php - Status page display
  • RateLimitChatbot.php - Rate limiting middleware
  • AbuseMonitoringController.php - Admin monitoring dashboard

Frontend Files

  • reader-tools-integration.js (1500+ lines) - Complete UI/UX application
  • UserStatus.blade.php - Status monitor view
  • GlobalChatbot.blade.php - Chatbot integration

API Endpoints

  • GET /api/reader-tools/proxy - Reader Tools (Explain, Modernize, Background)
  • GET /api/chatbot/proxy - Smart Library Assistant
  • GET /api/health/reader-tools - Health check (fast, no AI call)
  • GET /api/health/chatbot - Chatbot health check
  • GET /user/{uid}/status - Public status monitor

Technology Stack

PHP 8.3.6 Laravel 5.x Claude API Python SLA Service Redis Caching Server-Sent Events Vanilla JavaScript Blade Templates

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:

PHP 8.3.6 with Laravel 5.x Claude API integration Redis caching for rate limiting Server-Sent Events streaming

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 Slides

Presentation Overview

1

Title & Overview

Introduction to the Reader's Tools project, team members, and advisor

2

The Problem & Vision

"No one should feel lost when reading a great book" - transforming CCEL from static to interactive

3

Two Systems Integrated

Reader's Tools (Explain/Modernize/Background) and Smart Library Assistant (Chatbot)

4

Key Accomplishments

1500+ line JavaScript frontend, secure proxy, health checks, rate limiting, and zero database changes

5

Design Principles

Transparency, Trust, Stewardship, Accessibility, and Security integrated throughout

6

Live Demonstration

Walk-through of floating chatbot icon, text selection menu, real-time responses, and status dashboard

7

Technical Stack

PHP/Laravel backend, vanilla JavaScript frontend, Claude API, and Server-Sent Events streaming

8

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;
}
View Full Repository on GitHub

All source code available with full commit history and documentation