H9CEAI · Session 8 · Full-stack build with chatbot and MCP
Class demo: the Harbour View Hotel chatbot
Build a chatbot that talks to a live data source and answers real customer questions, then deploy it to a live GitHub page and submit the URL via Moodle.
Harbour View Hotel is a modern Irish 4-star hotel: rooms, packages, dining, spa and leisure, meetings and events, and the extras guests always ask about. It sells more than 90 rates and packages.
Reception fields the same questions every day: What family rooms do you have? Any midweek offers? Do you have a meeting room for 20 people? Can I bring the dog? The hotel wants a chatbot that answers these instantly, and always from its current rates and availability, not a static copy that goes stale the moment a price changes.
Your job: build that chatbot.
Every rate, package and extra lives in one Google Sheet: 93 rows, six categories. This is the hotel's "live database", and it is the tool your bot connects to.
- The Sheet (read it, copy it):
Harbour View Hotel · rates and packages ↗ - The CSV feed (what your code fetches):
https://docs.google.com/spreadsheets/d/1RzwstN-LofU3iSag4bQHzCPIjnmoXgZTYQmbz19ZxAo/gviz/tq?tqx=out:csv
File → Make a copy. Then in your copy: File → Share → Publish to web → CSV → Publish (or Share → Anyone with the link → Viewer, then use the same /gviz/tq?tqx=out:csv pattern with your own file ID). Point your bot at your CSV link. Edits take a minute or two to propagate: that lag is normal.Columns: rate_id, item_name, category, applies_to, price_eur, unit, capacity, requires_booking, availability, slots_this_week, special_offer, description.
Categories: Rooms, Packages, Dining, Spa & Leisure, Meetings & Events, Extras.
- Chat interface. A simple web page where a guest types a question and reads a reply.
- Reads live data. On each question, the bot uses the published sheet as its source of truth (the "tool" it connects to).
- Has an LLM brain. It understands natural-language questions and replies in natural language, not canned buttons.
- Grounded, not guessing. Answers come from the sheet. If something isn't in the data, the bot says so rather than inventing it.
- Reflects live edits. Change a cell in the sheet, ask again, and the answer updates.
- Deployed live. Published to a working GitHub page and reachable by URL.
Three parts: front end (the chat page) → live tool (the published sheet) → LLM brain (the model that reads the data and writes the reply).
This is the core idea behind MCP: giving your AI a live tool to reach real data instead of hoping it already knows. In the terminal you do this with a real MCP server; in a deployed web bot you wire the same idea directly to the sheet.
- Copy the data. Open the Sheet,
File → Make a copy, publish your copy, and keep its CSV link. - Fetch it. Get your code reading that CSV link and printing a few rows. Do not go further until this works.
- Add the brain. Send the guest's question plus the CSV rows to the model, with an instruction: answer only from this data; if it is not in the data, say you don't know.
- Add the front end. A text box, a Send button, and the reply on screen. Keep it simple.
- Deploy and test. Push to GitHub, turn on Pages, open the URL on your phone, and run the four test questions below.
The starter prompt at the bottom of this page gives an AI assistant everything it needs to scaffold this for you. You still have to understand what it wrote: that is the part being assessed.
Should list the family rooms and what they sleep.
Reads
special_offer and the Sun-Thu rates.Reads
capacity in Meetings & Events.Reads
slots_this_week live.slots_this_week to 0 on the Superior Sea View row, wait a moment, and ask again. The bot flips to "fully booked." That is the whole point: before, it guesses; now, it knows.Submit via the 14 July Moodle links, within six days.
- Your live GitHub page URL (the working chatbot, open to anyone with the link).
- The link to your published Google Sheet (your copy, not the master).
- A short note (a few lines): which model you used, where the API key lives, and confirmation that it is not in the public page.
It passes if: the bot answers the four test questions correctly from the live sheet, and it reflects a live edit (change a cell, the answer changes).
Stretch: add a second capability (filter by category or by price), and handle "no match found" gracefully instead of guessing.
Stuck? Ask in the Q&A on the session page, or email me. No question is too small.
Starter prompt
Paste this into your AI assistant to scaffold the build. Swap in your own CSV link once you have made your copy.
Build me a customer chatbot for Harbour View Hotel, a 4-star Irish hotel. The live data is a published Google Sheet, fetched as CSV from this URL: https://docs.google.com/spreadsheets/d/1RzwstN-LofU3iSag4bQHzCPIjnmoXgZTYQmbz19ZxAo/gviz/tq?tqx=out:csv (Replace this with the CSV link of MY OWN copy of the sheet before we finish.) Columns: rate_id, item_name, category, applies_to, price_eur, unit, capacity, requires_booking, availability, slots_this_week, special_offer, description. Categories: Rooms, Packages, Dining, Spa & Leisure, Meetings & Events, Extras. Build three parts: 1. A front end: a simple chat page (text box, Send button, replies on screen). Plain HTML, CSS and JavaScript, one page, no framework. 2. A live tool: on every question, fetch the CSV fresh so the answer always reflects the current sheet. 3. An LLM brain: send the question plus the CSV rows to the model and return a natural-language reply. Rules the bot must follow: - Answer ONLY from the sheet data. If it is not in the data, say you do not know, do not invent it. - Quote prices with the unit (per night, per person, per package). - Be brief and friendly, like a good receptionist. Security: my API key must NEVER appear in the public page. Put the model call in a small backend (a Cloudflare Worker is fine) that holds the key as a secret and fetches the sheet. Show me both files and tell me exactly where to paste the key. Then tell me, step by step, how to deploy the front end to GitHub Pages and get a public URL. Finally, help me test it with: What family rooms do you offer? Are there any midweek offers? Do you have a meeting room for 20 people? Any sea-view rooms left this week?
Copy the short brief
Plain-text version for Moodle, the group chat, or your notes.
Class demo: Harbour View Hotel chatbot Scenario: Harbour View Hotel is a modern Irish 4-star hotel (rooms, spa, dining, meetings, events) with 90+ rates and packages. Build a customer chatbot that answers real questions from the hotel's live data. Live data (the Sheet): https://docs.google.com/spreadsheets/d/1RzwstN-LofU3iSag4bQHzCPIjnmoXgZTYQmbz19ZxAo/edit As CSV: https://docs.google.com/spreadsheets/d/1RzwstN-LofU3iSag4bQHzCPIjnmoXgZTYQmbz19ZxAo/gviz/tq?tqx=out:csv Make your own copy first (File, Make a copy), publish it, and point your bot at your copy, so you can demonstrate a live edit. Columns: rate_id, item_name, category, applies_to, price_eur, unit, capacity, requires_booking, availability, slots_this_week, special_offer, description. Your bot must: 1. Give a chat interface (type a question, read a reply). 2. Read the live published sheet as its source of truth. 3. Have an LLM brain (natural language in and out). 4. Answer only from the data; if it is not there, say so, do not invent it. 5. Reflect live edits (change a cell, the answer updates). 6. Be deployed to a live GitHub page. How it fits: front end (chat page), then live tool (the published sheet), then LLM brain. This is the MCP idea: give your AI a live tool. Important: never put your API key in the public page. Route the model call through a small backend (a Cloudflare Worker or the pattern shown in class) that holds the key and reads the sheet. Test questions: - What family rooms do you offer? - Are there any midweek offers? - Do you have a meeting room for 20 people? - Any sea-view rooms left this week? Live proof: ask about sea-view rooms, set slots_this_week to 0 on that row in your sheet, ask again, watch it flip to fully booked. Submit within six days via the 14 July Moodle links: your live GitHub page URL, the link to your published sheet, and a short note on which model you used and where the API key lives. Stretch: add a second capability (filter by category or price) and handle no-match gracefully.