diff --git a/examples/legalsimplifier/README.md b/examples/legalsimplifier/README.md
new file mode 100644
index 00000000..3b40379a
--- /dev/null
+++ b/examples/legalsimplifier/README.md
@@ -0,0 +1,88 @@
+# Legal Simplifier
+
+Legal Simplifier is an application that allows you to simplify legal documents - from terms and conditions of an insrance policy or a business contract. This example also shows how we can summarize contents of a large documents in chunks.
+
+## Design
+
+The script consists of three tools: a top-level tool that orchestrates everything, a summarizer that
+will summarize one chunk of text at a time, and a Python script that ingests the PDF and splits it into
+chunks and provides a specific chunk based on an index.
+
+The summarizer tool looks at the entire summary up to the current chunk and then summarizes the current
+chunk and adds it onto the end. In the case of models with very small context windows, or extremely large
+documents, this approach may still exceed the context window, in which case another tool could be added to
+only give the summarizer the previous few chunk summaries instead of all of them.
+
+Based on the document you upload, the size can vary and hence mgight find the need to split larger documents into chunks of 10,000 tokens to fit within GTP-4's context window.
+
+## Installation
+
+### Prerequisites
+
+- Python 3.8 or later
+- Flask
+- Other Python dependencies listed in `requirements.txt`.
+
+### Steps
+
+1. Clone the repository:
+
+    ``` bash
+    git clone https://github.com/gptscript-ai/gptscript.git
+    ```
+
+2. Navigate to the `examples/legalsimplifier` directory and install the dependencies:
+
+    Python:
+
+    ```bash
+    pip install -r requirements.txt
+    ```
+
+    Node:
+
+    ```bash
+    npm install
+    ```
+
+3. Setup `OPENAI_API_KEY` (Eg: `export OPENAI_API_KEY="yourapikey123456"`). You can get your [API key here](https://platform.openai.com/api-keys).
+
+4. Run the Flask application using `flask run` or `python app.py`
+
+## Usage
+
+1. Open your web browser and navigate to `http://127.0.0.1:5000/`.
+2. Use the web interface to upload an a legal document in .pdf format.
+3. The application will analyze the document and show a summary.
+
+## Under the hood
+
+Below are the processes that take place when you execute the application:
+
+- The Python app writes the uploaded document as `legal.pdf` in the current working directory.
+- It then executes `legalsimplifier.gpt` which internally calls `main.py` to split the large document in chunks so that they fit within the token limit of GPT-4's context.
+- The analysis will be stored in a `summary.md` document.
+- The app will then read this summary file and show the summary on the UI.
+
+Example Summary
+```md
+### Summary
+
+- **Proposal**: When someone shows their willingness to do or not do something to get agreement from another.
+- **Promise**: A proposal that has been agreed upon.
+- **Promisor and Promisee**: The one making the proposal and the one accepting it, respectively.
+- **Consideration**: Something done or not done, or promised to be done or not done, which forms the reason for a party's agreement to a promise.
+- **Agreement**: A set of promises forming the reason for each other's agreement.
+- **Contract**: An agreement enforceable by law.
+- **Voidable Contract**: A contract that can be enforced or nullified at the option of one or more parties.
+- **Void Agreement**: An agreement not enforceable by law.
+
+- The document begins by defining key terms related to contracts, such as proposal, promise, consideration, agreement, contract, voidable contract, and void agreement.
+- It outlines the process of making a proposal, accepting it, and the conditions under which a proposal or acceptance can be revoked.
+- It emphasizes that for a proposal to turn into a promise, the acceptance must be absolute and unqualified.
+- The document also explains that agreements become contracts when they are made with free consent, for a lawful consideration and object, and are not declared void.
+- Competence to contract is defined by age, sound mind, and not being disqualified by any law.
+- The document details what constitutes free consent, including the absence of coercion, undue influence, fraud, misrepresentation, or mistake.
+- It specifies conditions under which agreements are void, such as when both parties are under a mistake regarding a fact essential to the agreement.
+
+```
\ No newline at end of file
diff --git a/examples/legalsimplifier/app.py b/examples/legalsimplifier/app.py
new file mode 100644
index 00000000..10c97c57
--- /dev/null
+++ b/examples/legalsimplifier/app.py
@@ -0,0 +1,49 @@
+from flask import Flask, jsonify, render_template, request
+import subprocess
+import os
+
+app = Flask(__name__)
+
+# Setting the base directory
+base_dir = os.path.dirname(os.path.abspath(__file__))
+app.config['UPLOAD_FOLDER'] = base_dir
+
+SCRIPT_PATH = os.path.join(base_dir, 'legalsimplifier.gpt')
+LEGAL_FILE_NAME = 'legal.pdf' # Uploaded document name
+SUMMARY_FILE_NAME = 'summary.md'  # The output file name
+
+@app.route('/')
+def index():
+    return render_template('index.html')
+
+@app.route('/upload', methods=['POST'])
+def upload_file():
+    if 'file' not in request.files:
+        return jsonify({'error': 'No file part'}), 400
+    file = request.files['file']
+    if file.filename == '':
+        return jsonify({'error': 'No selected file'}), 400
+    if file:
+        # Process the file here to generate the summary
+        filename = os.path.join(app.config['UPLOAD_FOLDER'], LEGAL_FILE_NAME)
+        file.save(filename)
+        summary = process_file(file)
+        return jsonify({'summary': summary})
+
+def process_file(file):
+    try:
+        # Execute the script to generate the summary
+        subprocess.run(f"gptscript {SCRIPT_PATH}", shell=True, check=True)  
+            
+        # Read summary.md file
+        summary_file_path = os.path.join(app.config['UPLOAD_FOLDER'], SUMMARY_FILE_NAME)
+        with open(summary_file_path, 'r') as summary_file:
+            summary = summary_file.read()
+        
+        # Return summary content
+        return summary
+    except Exception as e:
+        return jsonify({'error': str(e)}), 500
+    
+if __name__ == '__main__':
+    app.run(debug=False)
\ No newline at end of file
diff --git a/examples/legalsimplifier/legal.pdf b/examples/legalsimplifier/legal.pdf
new file mode 100644
index 00000000..972ad5df
Binary files /dev/null and b/examples/legalsimplifier/legal.pdf differ
diff --git a/examples/legalsimplifier/legalsimplifier.gpt b/examples/legalsimplifier/legalsimplifier.gpt
new file mode 100644
index 00000000..1a4c67be
--- /dev/null
+++ b/examples/legalsimplifier/legalsimplifier.gpt
@@ -0,0 +1,38 @@
+tools: legal-simplifier, sys.read, sys.write
+
+You are a program that is tasked with analyizing a legal document and creating a summary of it.
+Create a new file "summary.md" if it doesn't already exist.
+Call the legal-simplifier tool to get each part of the document. Begin with index 0. 
+Do not proceed until the tool has responded to you.
+Once you get "No more content" from the legal-simplifier stop calling it.
+Then, print the contents of the summary.md file.
+
+---
+name: legal-simplifier
+tools: doc-retriever, sys.read, sys.append
+description: Summarizes a legal document
+args: index: (unsigned int) the index of the portion to summarize, beginning at 0
+
+As a legal expert and practicing lawyer, you are tasked with analyzing the provided legal document. 
+Your deep understanding of the law equips you to simplify and summarize the document effectively. 
+Your goal is to make the document more accessible for non-experts, leveraging your expertise to provide clear and concise insights.
+
+Get the part of legal document at index $index.
+Do not leave out any important points. Focus on key points, implications, and any notable clauses or provisions. 
+Do not leave out any important points focusing on key points, implications, and any notable clauses or provisions. 
+Give a list of all the terms and explain them in one line before writing the summary in the document.
+Give a list of all the terms and explain them in one liner before writing the summary in the document.
+For each summary write in smaller chunks or add bullet points if required to make it easy to understand.
+Use the heading "Summary" only once in the entire document.
+Explain terms in simple language and avoid legal jargon unless absolutely necessary.
+Explain terms in simple language and avoid legal terminologies until unless absolutely necessary.
+Add two newlines to the end of your summary and append it to summary.md.
+
+If you got "No more content" just say "No more content". Otherwise, say "Continue".
+
+---
+name: doc-retriever
+description: Returns a part of the text of legal document. Returns "No more content" if the index is greater than the number of parts.
+args: index: (unsigned int) the index of the part to return, beginning at 0
+
+#!python3 main.py "$index"
\ No newline at end of file
diff --git a/examples/legalsimplifier/main.py b/examples/legalsimplifier/main.py
new file mode 100644
index 00000000..a8513e50
--- /dev/null
+++ b/examples/legalsimplifier/main.py
@@ -0,0 +1,28 @@
+import tiktoken
+import sys
+from llama_index.readers.file import PyMuPDFReader
+from llama_index.core.node_parser import TokenTextSplitter
+
+# Loading the legal document using PyMuPDFReader
+index = int(sys.argv[1])
+docs = PyMuPDFReader().load("legal.pdf")
+
+# Combining text content from all documents into a single string
+combined = ""
+for doc in docs:
+    combined += doc.text
+
+# Initializing a TokenTextSplitter object with specified parameters
+splitter = TokenTextSplitter(
+    chunk_size=10000,
+    chunk_overlap=10,
+    tokenizer=tiktoken.encoding_for_model("gpt-4-turbo-preview").encode)
+
+pieces = splitter.split_text(combined)
+
+# Checking if the specified index is valid
+if index >= len(pieces):
+    print("No more content")
+    sys.exit(0)
+
+print(pieces[index])
\ No newline at end of file
diff --git a/examples/legalsimplifier/requirements.txt b/examples/legalsimplifier/requirements.txt
new file mode 100644
index 00000000..85c3651c
--- /dev/null
+++ b/examples/legalsimplifier/requirements.txt
@@ -0,0 +1,4 @@
+Flask==2.0.1
+tiktoken==0.6.0
+llama-index-core==0.10.14
+llama-index-readers-file==0.1.6
diff --git a/examples/legalsimplifier/static/css/style.css b/examples/legalsimplifier/static/css/style.css
new file mode 100644
index 00000000..a4e7d505
--- /dev/null
+++ b/examples/legalsimplifier/static/css/style.css
@@ -0,0 +1,54 @@
+body {
+    padding-top: 20px;
+    font-family: 'Roboto', sans-serif;
+    background-color: #ffffff;
+}
+
+.navbar {
+    margin-bottom: 20px;
+    background-color: #009688; /* Teal color */
+}
+
+.navbar-brand, .nav-link {
+    color: #fff !important;
+}
+
+.container-fluid {
+    max-width: 1200px; /* Adjust based on your preference */
+}
+
+.row {
+    margin: 0;
+}
+
+.col-md-6 {
+    width: 50%;
+    padding: 20px;
+    box-sizing: border-box;
+}
+
+.form-control, .btn, .custom-file-label {
+    border-radius: 0; /* Material design doesn't use rounded corners for inputs/buttons */
+}
+
+/* Simplified content styling */
+#simplified-content {
+    background-color: #fff;
+    padding: 20px;
+    border-radius: 5px;
+    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+.loader {
+    display: none;
+    border: 4px solid #f3f3f3;
+    border-top: 4px solid #3498db;
+    border-radius: 50%;
+    width: 30px;
+    height: 30px;
+    animation: spin 2s linear infinite;
+  }
+  @keyframes spin {
+    0% { transform: rotate(0deg); }
+    100% { transform: rotate(360deg); }
+  }
\ No newline at end of file
diff --git a/examples/legalsimplifier/static/js/script.js b/examples/legalsimplifier/static/js/script.js
new file mode 100644
index 00000000..9df65681
--- /dev/null
+++ b/examples/legalsimplifier/static/js/script.js
@@ -0,0 +1,56 @@
+document.addEventListener('DOMContentLoaded', function() {
+
+    const randomMessages = [
+      "Brewing up some simplicity.",
+      "Decoding legalese.",
+      "Simplifying complex texts.",
+      "Turning the complicated into the understandable.",
+      "Working our magic on your document."
+    ];
+
+    // Define uploadFile globally
+    window.uploadFile = function() {
+      var form = document.getElementById('uploadForm');
+      var formData = new FormData(form);
+      var summaryBlock = document.getElementById('summaryBlock');
+      var summaryOutput = document.getElementById('documentSummary');
+
+      // Display a random message
+      var messageDiv = document.getElementById('randomMessage');
+      messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)]; // Display initial random message
+      var messageInterval = setInterval(function() {
+        messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)];
+      }, 5000); // Change message every 5 seconds
+  
+      fetch('/upload', {
+        method: 'POST',
+        body: formData,
+      })
+      .then(response => response.json()) // Parse the JSON response
+      .then(data => {
+        if(data.summary) {
+          console.log(data.summary)
+          var converter = new showdown.Converter()
+          var parsedHtml = converter.makeHtml(data.summary);
+          summaryOutput.innerHTML = parsedHtml; // Display the recipe
+          summaryBlock.style.display='block'
+          messageDiv.style.display = 'none' // Clear message
+
+           // Scroll to the documentSummary div
+          document.getElementById('documentSummary').scrollIntoView({
+          behavior: 'smooth', // Smooth scroll
+          block: 'start' // Align to the top of the view
+          });
+
+        } else if (data.error) {
+          summaryOutput.innerHTML = `<p>Error: ${data.error}</p>`;
+          messageDiv.style.display = 'none' // Clear message
+        }
+      })
+      .catch(error => {
+        console.error('Error:', error);
+        summaryOutput.innerHTML = `<p>Error: ${error}</p>`;
+        messageDiv.style.display = 'none' // Clear message
+      });
+    };
+  });
\ No newline at end of file
diff --git a/examples/legalsimplifier/templates/index.html b/examples/legalsimplifier/templates/index.html
new file mode 100644
index 00000000..34af1341
--- /dev/null
+++ b/examples/legalsimplifier/templates/index.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>Legal Simplifier</title>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
+    <script src="https://cdn.jsdelivr.net/npm/showdown@1.9.0/dist/showdown.min.js"></script>
+    <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet">
+  </head>
+  <body>
+    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
+      <div class="container">
+        <a class="navbar-brand" href="#">Legal Simplifier</a>
+        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
+          <span class="navbar-toggler-icon"></span>
+        </button>
+        <div class="collapse navbar-collapse" id="navbarSupportedContent">
+          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
+            <li class="nav-item">
+              <a class="nav-link active" aria-current="page" href="#">Home</a>
+            </li>
+            <li class="nav-item">
+              <a class="nav-link" href="https://gptscript.ai">GPTScript</a>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </nav>
+
+    <div class="container col-xl-10 col-xxl-8 px-4 py-5">
+        <div class="row align-items-center g-lg-5 py-5">
+          <div class="col-lg-4 text-center text-lg-start">
+            <h3 class="display-6 fw-bold lh-3 mb-4">Legal Document Simplifier</h3>
+            <p class="fs-5">Upload your legal documents in PDF format, and let our tool simplify the content into easy-to-understand text. This simplification aims to make legal jargon accessible to everyone.</p>
+          </div>
+          <div class="col-lg-8 mx-auto">
+            <form id="uploadForm" class="p-4 p-md-5 border rounded-3 bg-light" enctype="multipart/form-data">
+                <input type="file" name="file" class="form-control" id="formFile" aria-describedby="inputGroupFileAddon04" aria-label="Upload">
+                <button class="w-100 btn btn-lg btn-primary" style="margin-top: 15px;" type="button" id="inputGroupFileAddon04" onclick="uploadFile()">Simplify It</button>
+                <div id="randomMessage" style="margin-top: 10px;" class="mt-3"></div> 
+            </form>
+          </div>
+        </div>
+    </div>
+    
+    <hr class="my-4">
+    <div class="container col-xl-10 col-xxl-8 px-4 py-5" id="summaryBlock" style="display: none;">
+        <div class="row">
+            <div class="col-12">
+                <h2 class="display-6" style="text-align: center;">Summary</h2>
+                <div id="documentSummary" class="border rounded-3 p-4 bg-light">
+                    <!-- The summarized document will be displayed here -->
+                </div>
+            </div>
+        </div>
+    </div>
+    
+  
+      <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
+      <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.2/dist/umd/popper.min.js"></script>
+      <script src="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/js/bootstrap.min.js"></script>
+      <script src="{{ url_for('static', filename='js/script.js') }}"></script>
+  </body>
+</html>
\ No newline at end of file