Compare commits

..

No commits in common. "3af91e8a9d3019d57e165650bf05f1479662616a" and "2c17a3e4e3e71030aeb3b16c81ba648cc3bfb08b" have entirely different histories.

47 changed files with 87 additions and 473 deletions

View File

@ -1,7 +0,0 @@
node_modules
dist
.astro
.git
.env
.env.*
!.env.example

View File

@ -1,2 +0,0 @@
COMPOSE_PROJECT_NAME=mcwaddams-site
DOMAIN=mcwaddams.mcp.website

View File

@ -1,24 +0,0 @@
:8080 {
root * /srv
file_server
handle /health {
respond "OK" 200
}
# SPA-style fallback for clean URLs
try_files {path} {path}/ {path}.html /index.html
# Cache static assets aggressively
@static path *.css *.js *.svg *.png *.webp *.jpg *.jpeg *.gif *.ico *.woff *.woff2
header @static Cache-Control "public, max-age=31536000, immutable"
# Security headers
header {
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
encode gzip zstd
}

View File

@ -1,21 +0,0 @@
# Stage 1: Build the Astro/Starlight site
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Serve static files with Caddy
FROM caddy:2-alpine
COPY --from=build /app/dist /srv
COPY Caddyfile /etc/caddy/Caddyfile
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://127.0.0.1:8080/health || exit 1

View File

@ -1,28 +0,0 @@
.PHONY: build up down restart logs status clean
build:
docker compose build
up: build
docker compose up -d
@echo "Waiting for container to start..."
@sleep 3
docker compose logs --tail=20
down:
docker compose down
restart:
docker compose down
docker compose up -d --build
@sleep 3
docker compose logs --tail=20
logs:
docker compose logs -f
status:
docker compose ps
clean:
docker compose down --rmi local --volumes

View File

@ -99,7 +99,6 @@ export default defineConfig({
{
label: 'Community',
items: [
{ label: 'The Gallery', slug: 'community/gallery', badge: { text: 'New', variant: 'success' } },
{ label: 'Feedback', slug: 'community/feedback' },
{ label: 'Flair Leaderboard', slug: 'community/leaderboard' },
{ label: 'Credits', slug: 'community/credits' },

View File

@ -1,19 +0,0 @@
services:
site:
build: .
restart: unless-stopped
networks:
- caddy
labels:
caddy: ${DOMAIN}
caddy.reverse_proxy: "{{upstreams 8080}}"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8080/health"]
interval: 30s
timeout: 3s
start_period: 5s
retries: 3
networks:
caddy:
external: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

View File

@ -1,37 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<defs>
<linearGradient id="filmGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#1a1a2e"/>
<stop offset="100%" style="stop-color:#16213e"/>
</linearGradient>
<linearGradient id="reelGold" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#f59e0b"/>
<stop offset="100%" style="stop-color:#d97706"/>
</linearGradient>
</defs>
<!-- Badge background -->
<circle cx="50" cy="50" r="48" fill="url(#filmGradient)" stroke="#f59e0b" stroke-width="3"/>
<!-- Film reel -->
<circle cx="50" cy="50" r="30" fill="none" stroke="url(#reelGold)" stroke-width="4"/>
<circle cx="50" cy="50" r="8" fill="url(#reelGold)"/>
<!-- Film reel holes -->
<circle cx="50" cy="28" r="5" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="2"/>
<circle cx="50" cy="72" r="5" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="2"/>
<circle cx="28" cy="50" r="5" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="2"/>
<circle cx="72" cy="50" r="5" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="2"/>
<!-- Diagonal holes -->
<circle cx="34.5" cy="34.5" r="4" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="1.5"/>
<circle cx="65.5" cy="34.5" r="4" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="1.5"/>
<circle cx="34.5" cy="65.5" r="4" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="1.5"/>
<circle cx="65.5" cy="65.5" r="4" fill="#1a1a2e" stroke="url(#reelGold)" stroke-width="1.5"/>
<!-- Film strip accents -->
<rect x="10" y="85" width="8" height="6" rx="1" fill="url(#reelGold)" opacity="0.8"/>
<rect x="22" y="85" width="8" height="6" rx="1" fill="url(#reelGold)" opacity="0.8"/>
<rect x="70" y="85" width="8" height="6" rx="1" fill="url(#reelGold)" opacity="0.8"/>
<rect x="82" y="85" width="8" height="6" rx="1" fill="url(#reelGold)" opacity="0.8"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

View File

@ -5,6 +5,8 @@ description: How Milton Waddams became the patron saint of legacy document proce
import { Aside } from '@astrojs/starlight/components';
# The Backstory
> *"I was told I could listen to the radio at a reasonable volume from nine to eleven..."*
## The Relocation

View File

@ -5,6 +5,8 @@ description: The open source projects and cultural references that make mcwaddam
import { Aside, Card, CardGrid, LinkCard } from '@astrojs/starlight/components';
# Credits & Attributions
> *"It's not just about me and my dream of doing nothing."*
mcwaddams stands on the shoulders of giants — both technical and cinematic.
@ -131,8 +133,6 @@ For creating Office Space and giving the tech industry a shared vocabulary for d
The hero image — featuring THE actual film slate and red Swingline from production — is courtesy of [Mike Judge on X](https://x.com/MikeJudge).
Additional Office Space screenshots and character images sourced from the [Office Space Wiki](https://officespace.fandom.com/wiki/Office_Space_Wiki). Initech logo from the [Initech wiki page](https://officespace.fandom.com/wiki/Initech). Box of Flair merchandise image from the [Office Space Box of Flair wiki page](https://officespace.fandom.com/wiki/Office_Space_Box_of_Flair).
### Swingline
For actually manufacturing a red stapler after the movie came out. Sometimes life imitates art. (Fun fact: the prop department painted a black stapler red because Swingline didn't make that color in 1999.)

View File

@ -5,6 +5,8 @@ description: Found a bug? Have an idea? We want to hear it.
import { Aside, Card, CardGrid, LinkCard } from '@astrojs/starlight/components';
# Feedback
> *"Excuse me, I believe you have my bug report..."*
We want to hear from you — bugs, feature requests, or just letting us know what works.

View File

@ -1,212 +0,0 @@
---
title: The Gallery
description: A tribute to the film that inspired it all.
---
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
> *"I'd say in a given week I probably only do about fifteen minutes of real, actual work."*
Welcome to the mcwaddams gallery — a loving tribute to Office Space (1999), the film that understands corporate life better than any management consultant ever could.
---
## The Initech Crew
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Peter.webp" alt="Peter Gibbons" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I did nothing. I did absolutely nothing, and it was everything I thought it could be."</p>
<small>Peter Gibbons</small>
</div>
<div style="text-align: center;">
<img src="/peter-zen.webp" alt="Peter in his zen state" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I don't like my job, and I don't think I'm gonna go anymore."</p>
<small>Post-hypnotherapy Peter</small>
</div>
<div style="text-align: center;">
<img src="/Peter-Computing-Surprised.webp" alt="Peter surprised at computer" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I have eight different bosses right now."</p>
<small>The moment of realization</small>
</div>
</div>
---
## Management
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Peter-Lumberg-At-Cubicle.webp" alt="Lumbergh at Peter's cubicle" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Yeahhh, I'm gonna need you to come in on Saturday..."</p>
<small>Bill Lumbergh</small>
</div>
<div style="text-align: center;">
<img src="/TheBobs.webp" alt="The Bobs" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"What would you say... you do here?"</p>
<small>The Bobs — efficiency experts</small>
</div>
<div style="text-align: center;">
<img src="/management-disapproval.webp" alt="Management disapproval" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"We're gonna have to go ahead and move you downstairs into Storage B."</p>
<small>The look of corporate disappointment</small>
</div>
<div style="text-align: center;">
<img src="/Lumbergh-cake-sign.webp" alt="Lumbergh with cake sign" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Hello Peter, what's happening?"</p>
<small>Passive-aggressive celebration</small>
</div>
</div>
---
## The Iconic Scenes
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Printer.webp" alt="The printer destruction scene" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"PC LOAD LETTER? What the f*** does that mean?!"</p>
<small>The printer gets what it deserves</small>
</div>
<div style="text-align: center;">
<img src="/stapler-theft.webp" alt="Milton's stapler" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I believe you have my stapler..."</p>
<small>The red Swingline</small>
</div>
<div style="text-align: center;">
<img src="/Ohface.webp" alt="The O-Face" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"O-O-O-OHHHHH!"</p>
<small>Drew's... moment</small>
</div>
<div style="text-align: center;">
<img src="/Cakepass.webp" alt="The cake scene" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Milton, we're gonna need you to move your desk again..."</p>
<small>Another office milestone ignored</small>
</div>
</div>
---
## Chotchkie's & The Flair
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Stan.webp" alt="Stan the manager" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"We need to talk about your flair."</p>
<small>Stan — the flair enforcer</small>
</div>
<div style="text-align: center;">
<img src="/box-of-flair.webp" alt="Box of flair" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"You know, the Nazis had pieces of flair they made the Jews wear."</p>
<small>The official flair collection</small>
</div>
<div style="text-align: center;">
<img src="/fu-Flair.webp" alt="Joanna's statement" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"There's my flair."</p>
<small>Joanna's final day at Chotchkie's</small>
</div>
<div style="text-align: center;">
<img src="/chotchkies-logo.webp" alt="Chotchkie's logo" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Sounds like somebody's got a case of the Mondays."</p>
<small>Where dreams go to die</small>
</div>
</div>
---
## The Supporting Cast
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Lawrence.webp" alt="Lawrence" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Hey Peter, man, check out Channel 9!"</p>
<small>Lawrence — the neighbor</small>
</div>
<div style="text-align: center;">
<img src="/Lawrence-couch.webp" alt="Lawrence on the couch" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Two chicks at the same time, man."</p>
<small>Lawrence's dream</small>
</div>
<div style="text-align: center;">
<img src="/Nina.webp" alt="Nina" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Uh-oh. Sounds like somebody's got a case of the Mondays."</p>
<small>Nina — the cheerful coworker</small>
</div>
<div style="text-align: center;">
<img src="/peter-hard-hat-samir-michael-GroupPic.webp" alt="Peter, Samir, and Michael Bolton" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Why should I change? He's the one who sucks."</p>
<small>The crew at work</small>
</div>
</div>
---
## Initech
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin: 2rem 0;">
<div style="text-align: center;">
<img src="/Initech.webp" alt="Initech building" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Corporate accounts payable, Nina speaking. Just a moment."</p>
<small>Initech — where TPS reports are born</small>
</div>
<div style="text-align: center;">
<img src="/peter-initech-sign.webp" alt="Peter arriving at Initech" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"Every single day of my life has been worse than the day before it."</p>
<small>Another day at Initech</small>
</div>
<div style="text-align: center;">
<img src="/empty-office.webp" alt="Empty Initech office" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I'd like to move us right along to a Peter Gibbons."</p>
<small>The cubicle farm</small>
</div>
<div style="text-align: center;">
<img src="/burned-stapler-recover.webp" alt="Milton's stapler recovered" style="width: 100%; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.2);" />
<p style="margin-top: 0.5rem; font-style: italic;">"I could set the building on fire..."</p>
<small>The stapler survived</small>
</div>
</div>
---
<Aside type="note" title="Attribution">
All images are from Office Space (1999), directed by Mike Judge. Copyright © 20th Century Fox. Used for educational and tribute purposes. mcwaddams is not affiliated with 20th Century Fox.
</Aside>
<div style="text-align: center; margin-top: 2rem; font-style: italic; opacity: 0.7;">
*"I don't like my job, and I don't think I'm gonna go anymore."*
<br/>
<small>— Peter Gibbons, speaking for all of us</small>
</div>

View File

@ -5,6 +5,8 @@ description: Who's got the most pieces of documentation flair?
import { Aside, Card, CardGrid } from '@astrojs/starlight/components';
# Flair Leaderboard
<div style="display: flex; justify-content: center; margin: 2rem 0;">
<img src="/chotchkies-logo.webp" alt="Chotchkie's Bar & Grill" style="max-width: 300px; border-radius: 8px;" />
</div>
@ -17,49 +19,46 @@ We don't require 37 pieces of flair like Brian. Just the minimum — but we enco
## Your Collection
Click the **flair counter** in the bottom-right corner of any page to see your collection. Badges are earned by spending 15+ seconds reading each page.
Click the **flair counter** in the bottom-right corner of any page to see your collection. Badges are earned by spending 3+ seconds reading each page.
## Available Flair (13 Badges)
## Available Flair (12 Badges)
<CardGrid>
<Card title="📄 I Was Told There Would Be Extraction" icon="document">
Start your mcwaddams journey (homepage)
<Card title="📄 First Extraction" icon="document">
Visit the homepage
</Card>
<Card title="🔴 Basement Dweller" icon="puzzle">
Learn about Milton and the legacy documents
Read the backstory
</Card>
<Card title="🖨️ PC Load Letter" icon="setting">
Successfully install mcwaddams
Complete installation
</Card>
<Card title="☕ Case of the Mondays" icon="rocket">
Complete the quick start guide
Finish quick start
</Card>
<Card title="📋 TPS Report Expert" icon="list-format">
Read the complete tools reference
Browse tools reference
</Card>
<Card title="👔 The Bobs Approved" icon="approve-check">
Understand the architecture
Study architecture
</Card>
<Card title="📝 Did You Get The Memo?" icon="information">
Check the test dashboard
<Card title="📝 Memo Received" icon="information">
Check test dashboard
</Card>
<Card title="😮 O Face" icon="star">
Witness the torture test results
<Card title="🔥 Jump to Conclusions" icon="warning">
Survive torture tests
</Card>
<Card title="🔴 I Have Your Stapler" icon="heart">
Find the credits and attributions
<Card title="⭐ Flair Enthusiast" icon="star">
View leaderboard
</Card>
<Card title="🎲 Jump to Conclusions" icon="warning">
Complete your first extraction tutorial
<Card title="🎖️ Credit Where Due" icon="heart">
Read the credits
</Card>
<Card title="📊 Spreadsheet Survivor" icon="open-book">
Master table extraction
<Card title="📚 Legacy Handler" icon="open-book">
Learn legacy formats
</Card>
<Card title="🎖️ 37 Pieces of Flair" icon="external">
Discover the flair leaderboard
</Card>
<Card title="🎬 Cinema Enthusiast" icon="star">
Explore the Office Space gallery
<Card title="🌐 Cloud Connect" icon="external">
Use hosted MCP
</Card>
</CardGrid>
@ -67,7 +66,7 @@ Click the **flair counter** in the bottom-right corner of any page to see your c
## The Goal
Collect all 13 pieces of flair. Brian from accounting has 37, but we only ask for the minimum.
Collect all 12 pieces of flair. Brian from accounting has 37, but we only ask for the minimum.
<Aside type="tip" title="Persistence">
Your flair collection is stored in localStorage — it persists across sessions but stays on your device.

View File

@ -5,6 +5,8 @@ description: How mcwaddams processes Office documents behind the scenes.
import { Aside } from '@astrojs/starlight/components';
# Architecture
> *"So I was sitting in my cubicle today, and I realized... every document format is worse than the one before it."*
mcwaddams is designed around a single principle: **never silently fail**. When extraction works, you get content. When it doesn't, you get a clear explanation why.

View File

@ -5,6 +5,8 @@ description: How mcwaddams tries multiple methods to extract your documents.
import { Aside } from '@astrojs/starlight/components';
# Fallback Strategy
> *"We fixed the glitch."*
When the primary extraction method fails, mcwaddams automatically tries alternatives.

View File

@ -5,6 +5,8 @@ description: The architectural decision behind mcwaddams's modular structure.
import { Aside } from '@astrojs/starlight/components';
# Why Mixins?
> *"What would you say... you do here?"*
mcwaddams uses Python mixins to organize 20 tools into logical groups without creating multiple MCP servers.

View File

@ -5,6 +5,8 @@ description: How MCP resources enable on-demand document access.
import { Aside } from '@astrojs/starlight/components';
# Resource System
> *"I was told I could fetch chapters at a reasonable rate..."*
The MCP resource system lets you access parts of indexed documents without reprocessing.

View File

@ -5,6 +5,8 @@ description: Get statistical analysis and data quality insights from spreadsheet
import { Aside } from '@astrojs/starlight/components';
# Analyze Excel Data
> *"I did nothing and it was everything I thought it could be."*
Get comprehensive insights from Excel spreadsheets including statistics, data types, and quality checks.

View File

@ -5,6 +5,8 @@ description: Transform Word documents into clean Markdown.
import { Aside } from '@astrojs/starlight/components';
# Convert to Markdown
> *"Why should I change? The document format's the one who sucks."*
Convert Word documents to Markdown while preserving structure, headings, lists, and tables.

View File

@ -5,6 +5,8 @@ description: Get structured table data from Word documents in multiple formats.
import { Aside, Steps, Tabs, TabItem } from '@astrojs/starlight/components';
# Extract Tables from Word Documents
> *"We need to talk about your table extraction..."*
Word documents often contain important data locked in tables. mcwaddams extracts them as structured data you can actually use.

View File

@ -5,6 +5,8 @@ description: Use mcwaddams without installing anything locally.
import { Aside, Code, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
# Connect to Hosted Server
> *"I was told there would be no installation..."*
Don't want to install anything? Connect to our hosted mcwaddams server via HTTP.
@ -14,7 +16,7 @@ Don't want to install anything? Connect to our hosted mcwaddams server via HTTP.
<Tabs>
<TabItem label="Claude Code">
```bash
claude mcp add mcwaddams-hosted --transport http "https://mcwaddams.l.supported.systems/mcp"
claude mcp add mcwaddams-hosted --transport http "https://mcwaddams.supported.systems/mcp"
```
</TabItem>
<TabItem label="MCP Settings JSON">
@ -24,7 +26,7 @@ Don't want to install anything? Connect to our hosted mcwaddams server via HTTP.
"mcwaddams": {
"transport": {
"type": "streamable-http",
"url": "https://mcwaddams.l.supported.systems/mcp"
"url": "https://mcwaddams.supported.systems/mcp"
}
}
}
@ -36,7 +38,7 @@ Don't want to install anything? Connect to our hosted mcwaddams server via HTTP.
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
async with streamable_http_client("https://mcwaddams.l.supported.systems/mcp") as (read, write):
async with streamable_http_client("https://mcwaddams.supported.systems/mcp") as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
@ -73,7 +75,7 @@ All 20+ mcwaddams tools are available via the hosted server:
| Feature | Hosted | Local (uvx) |
|---------|--------|-------------|
| Installation | None | `uvx mcwaddams` |
| File Access | URL + base64 upload | Local + URL |
| File Access | URL only | Local + URL |
| Speed | Network latency | Instant |
| Privacy | Files processed on server | Files stay local |
| Availability | Requires internet | Works offline |
@ -82,13 +84,9 @@ All 20+ mcwaddams tools are available via the hosted server:
When using the hosted server, your documents are transmitted to and processed on our server. For sensitive documents, use the local installation instead.
</Aside>
## Uploading Documents
## Using with URLs
The hosted server cannot access files on your local machine. Instead, you have two options:
### Option 1: URL Reference
If your document is already hosted online:
The hosted server can process documents from URLs directly:
```python
# Extract text from a public document
@ -97,77 +95,7 @@ result = await session.call_tool("extract_text", {
})
```
### Option 2: Base64 Upload
For local files, encode them as base64 and pass via `file_content`:
<Tabs>
<TabItem label="Python">
```python
import base64
from pathlib import Path
# Read and encode your document
doc_path = Path("my-report.docx")
file_content = base64.b64encode(doc_path.read_bytes()).decode("utf-8")
# Call the tool with file_content
result = await session.call_tool("extract_text", {
"file_path": "my-report.docx", # Used for extension detection
"file_content": file_content
})
```
</TabItem>
<TabItem label="JavaScript">
```javascript
import { readFileSync } from 'fs';
// Read and encode your document
const docBuffer = readFileSync('my-report.docx');
const fileContent = docBuffer.toString('base64');
// Call the tool with file_content
const result = await session.callTool("extract_text", {
file_path: "my-report.docx", // Used for extension detection
file_content: fileContent
});
```
</TabItem>
<TabItem label="Bash/curl">
```bash
# Encode document to base64
FILE_CONTENT=$(base64 -w 0 my-report.docx)
# Call via HTTP (simplified example)
curl -X POST https://mcwaddams.l.supported.systems/mcp \
-H "Content-Type: application/json" \
-d "{
\"method\": \"tools/call\",
\"params\": {
\"name\": \"extract_text\",
\"arguments\": {
\"file_path\": \"my-report.docx\",
\"file_content\": \"$FILE_CONTENT\"
}
}
}"
```
</TabItem>
</Tabs>
<Aside type="note" title="file_path Still Required">
When using `file_content`, the `file_path` parameter is still required but only used for extension detection. The server uses the extension to determine the correct processing method.
</Aside>
### All Tools Support Upload
Every tool that accepts `file_path` also accepts `file_content`:
- `extract_text` - Extract text with base64 upload
- `extract_images` - Extract images with base64 upload
- `convert_to_markdown` - Convert Word docs to Markdown
- `analyze_excel_data` - Analyze uploaded spreadsheets
- And all other document tools...
This is particularly useful for processing documents already hosted online.
## Self-Hosting
@ -183,16 +111,10 @@ services:
- MCP_TRANSPORT=streamable-http
- MCP_HOST=0.0.0.0
- MCP_PORT=8000
# Enable local file access (disabled by default for security)
# - MCP_ALLOW_LOCAL_FILES=true
ports:
- "8000:8000"
```
<Aside type="tip" title="Local File Access">
By default, hosted servers only accept URLs and `file_content` uploads. If you're self-hosting on a trusted network and want to access local files, set `MCP_ALLOW_LOCAL_FILES=true`.
</Aside>
### With Caddy Reverse Proxy
Clone the repo and use our docker-compose with caddy-docker-proxy labels:

View File

@ -5,6 +5,8 @@ description: Work with documents that exceed token limits.
import { Aside } from '@astrojs/starlight/components';
# Handle Pagination
> *"Yeah, I'm gonna need you to go ahead and come in on Saturday for page 2..."*
Documents over 25,000 tokens are automatically paginated. Use cursors to fetch subsequent pages.

View File

@ -5,6 +5,8 @@ description: Extract documents directly from HTTP/HTTPS URLs.
import { Aside } from '@astrojs/starlight/components';
# Process URLs
> *"We fixed the glitch... by caching the download."*
All tools accept HTTP/HTTPS URLs directly. Files are cached for 1 hour.

View File

@ -5,6 +5,8 @@ description: Get mcwaddams up and running in under a minute.
import { Tabs, TabItem, Aside, Steps } from '@astrojs/starlight/components';
# Installation
> *"PC Load Letter? What the f*** does that mean?"*
Don't worry. This is simpler than fixing the printer.

View File

@ -5,6 +5,8 @@ description: Extract your first document in 60 seconds.
import { Aside, Steps, Code } from '@astrojs/starlight/components';
# Quick Start
> *"I'll be honest with you, I love his music. I do. I'm a Michael Bolton fan."*
Let's get you extracting documents faster than you can say "TPS report cover sheet."

View File

@ -5,6 +5,8 @@ description: Specialized tools for Excel spreadsheet processing.
import { Aside } from '@astrojs/starlight/components';
# Excel Tools
These 3 tools are specialized for `.xlsx`, `.xls`, and `.csv` files.
## analyze_excel_data

View File

@ -5,6 +5,8 @@ description: Complete list of supported Office document formats.
import { Aside } from '@astrojs/starlight/components';
# Format Support
mcwaddams supports all major Microsoft Office formats, both modern and legacy.
## Modern Formats (2007+)

View File

@ -5,6 +5,8 @@ description: Resource URIs for on-demand document access.
import { Aside } from '@astrojs/starlight/components';
# MCP Resources
After indexing a document, access content via MCP resource URIs.
## Resource URI Schemes

View File

@ -5,6 +5,8 @@ description: Complete reference for all 20 mcwaddams MCP tools.
import { Aside, Badge, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components';
# All Tools Reference
> *"I'm going to need you to go ahead and read the documentation..."*
mcwaddams provides **20 tools** organized into three categories. Each tool follows the same pattern: pass a file path (local or URL), get structured data back.

View File

@ -5,6 +5,8 @@ description: Tools that work across all Office document formats.
import { Aside } from '@astrojs/starlight/components';
# Universal Tools
These 7 tools work with all supported formats: `.docx`, `.doc`, `.xlsx`, `.xls`, `.pptx`, `.ppt`, `.csv`.
## extract_text

View File

@ -5,6 +5,8 @@ description: Specialized tools for Word document processing.
import { Aside } from '@astrojs/starlight/components';
# Word Tools
These 10 tools are specialized for `.docx` and `.doc` files.
## convert_to_markdown

View File

@ -5,6 +5,8 @@ description: Test coverage philosophy and metrics.
import { Aside } from '@astrojs/starlight/components';
# Coverage Report
> *"Looks like you've been missing a lot of work lately."*
> *"I wouldn't say I've been missing it, Bob."*

View File

@ -5,6 +5,8 @@ description: "Did you get the memo about the TPS reports?"
import { Aside, Badge, Card, CardGrid } from '@astrojs/starlight/components';
# TPS Reports: Test Dashboard
> *"Yeah, I'm gonna need you to go ahead and come in on Saturday..."*
<Aside type="danger" title="TPS = Testing Painful Stuff">

View File

@ -5,6 +5,8 @@ description: "301 random Office documents walked into a bar..."
import { Aside, Badge, Card, CardGrid } from '@astrojs/starlight/components';
# Torture Test Results
> *"I'm gonna need you to come in on Saturday... and Sunday too."*
We grabbed 301 random Office documents from a real filesystem — no cherry-picking, no sanitizing, just raw production files from someone's decade-old archive.

View File

@ -5,6 +5,8 @@ description: Extract text from an Office document in 60 seconds.
import { Aside, Steps, Code, Tabs, TabItem } from '@astrojs/starlight/components';
# Your First Extraction
> *"I'll be honest with you, I love extracting documents. I do. I'm a mcwaddams fan."*
Let's get you extracting documents faster than you can say "TPS report cover sheet."

View File

@ -5,6 +5,8 @@ description: Efficiently access huge documents without loading everything at onc
import { Aside } from '@astrojs/starlight/components';
# Indexing Large Documents
> *"It's not that I'm lazy, it's that I just don't care about loading 500 pages at once."*
For documents over 25,000 tokens, the indexing system enables on-demand fetching through MCP resources.

View File

@ -5,6 +5,8 @@ description: Handle .doc, .xls, and .ppt files from the basement archives.
import { Aside } from '@astrojs/starlight/components';
# Working with Legacy Formats
> *"I was told I could keep my legacy documents at a reasonable location from nine to eleven..."*
Legacy formats (`.doc`, `.xls`, `.ppt`) require special handling. mcwaddams uses OLE Compound Document parsing to extract content from files dating back to 1997.

View File

@ -5,6 +5,8 @@ description: Access document content through the MCP resource protocol.
import { Aside } from '@astrojs/starlight/components';
# Using MCP Resources
> *"The thing is, Bob, it's not that I'm lazy, it's that I just don't want to load everything."*
MCP resources let you fetch specific parts of indexed documents without reprocessing.

View File

@ -97,14 +97,6 @@
"placeholder": "🎖️",
"image": "/flair/flair-badge.svg",
"description": "Discovered the flair leaderboard"
},
{
"id": "gallery",
"path": "/community/gallery/",
"name": "Cinema Enthusiast",
"placeholder": "🎬",
"image": "/flair/cinema.svg",
"description": "Explored the Office Space gallery"
}
],
"completionMessage": "You've got more than the minimum 15 pieces of flair!",